${project.groupId}
mage-tournament-boosterdraft
diff --git a/Mage.Server/release/config/config.xml b/Mage.Server/release/config/config.xml
index 31121bfb8ca..40d78b18a37 100644
--- a/Mage.Server/release/config/config.xml
+++ b/Mage.Server/release/config/config.xml
@@ -119,6 +119,7 @@
+
@@ -133,6 +134,7 @@
+
@@ -142,6 +144,7 @@
+
@@ -162,6 +165,7 @@
+
diff --git a/Mage.Server/src/main/java/mage/server/ChatManager.java b/Mage.Server/src/main/java/mage/server/ChatManager.java
index 755571becf4..be02de0ed5d 100644
--- a/Mage.Server/src/main/java/mage/server/ChatManager.java
+++ b/Mage.Server/src/main/java/mage/server/ChatManager.java
@@ -5,6 +5,7 @@ import mage.cards.repository.CardRepository;
import mage.server.exceptions.UserNotFoundException;
import mage.server.game.GameController;
import mage.server.game.GameManager;
+import mage.server.game.GamesRoomManager;
import mage.server.util.SystemUtil;
import mage.view.ChatMessage.MessageColor;
import mage.view.ChatMessage.MessageType;
@@ -316,12 +317,16 @@ public enum ChatManager {
}
public void sendLostConnectionMessage(UUID userId, DisconnectReason reason) {
+ UserManager.instance.getUser(userId).ifPresent(user -> sendMessageToUserChats(userId, user.getName() + " " + reason.getMessage()));
+ }
+
+ public void sendMessageToUserChats(UUID userId, String message) {
UserManager.instance.getUser(userId).ifPresent(user
-> getChatSessions()
.stream()
+ .filter(chat -> !chat.getChatId().equals(GamesRoomManager.instance.getMainChatId())) // ignore main lobby
.filter(chat -> chat.hasUser(userId))
- .forEach(chatSession -> chatSession.broadcast(null, user.getName() + reason.getMessage(), MessageColor.BLUE, true, MessageType.STATUS, null)));
-
+ .forEach(chatSession -> chatSession.broadcast(null, message, MessageColor.BLUE, true, MessageType.STATUS, null)));
}
public void removeUser(UUID userId, DisconnectReason reason) {
diff --git a/Mage.Server/src/main/java/mage/server/Session.java b/Mage.Server/src/main/java/mage/server/Session.java
index be7d0357507..83b8ec85e83 100644
--- a/Mage.Server/src/main/java/mage/server/Session.java
+++ b/Mage.Server/src/main/java/mage/server/Session.java
@@ -1,4 +1,3 @@
-
package mage.server;
import java.util.*;
@@ -352,7 +351,16 @@ public class Session {
if (valid && callBackLock.tryLock(50, TimeUnit.MILLISECONDS)) {
call.setMessageId(messageId++);
lockSet = true;
- callbackHandler.handleCallbackOneway(new Callback(call));
+ Callback callback = new Callback(call);
+// if (call.getMethod().equals(ClientCallbackMethod.GAME_TARGET)) {
+// Object object = call.getData();
+// if (object instanceof GameClientMessage) {
+// String message = ((GameClientMessage) object).getMessage();
+// logger.info("Server Session Event->" + call.getMethod() + " (id:" + call.getMessageId() + ") " + message);
+// logger.info(callback.toString());
+// }
+// }
+ callbackHandler.handleCallbackOneway(callback);
}
} catch (InterruptedException ex) {
logger.warn("SESSION LOCK - fireCallback - userId: " + userId + " messageId: " + call.getMessageId(), ex);
@@ -364,6 +372,8 @@ public class Session {
logger.trace("Stack trace:", ex);
SessionManager.instance.disconnect(sessionId, LostConnection);
});
+ } catch (Exception ex) {
+ logger.warn("Unspecific exception:", ex);
} finally {
if (lockSet) {
callBackLock.unlock();
diff --git a/Mage.Server/src/main/java/mage/server/SessionManager.java b/Mage.Server/src/main/java/mage/server/SessionManager.java
index 20d201e6c30..b87dc49c9c4 100644
--- a/Mage.Server/src/main/java/mage/server/SessionManager.java
+++ b/Mage.Server/src/main/java/mage/server/SessionManager.java
@@ -29,7 +29,7 @@ public enum SessionManager {
}
if (session.getUserId() != null && !UserManager.instance.getUser(session.getUserId()).isPresent()) {
logger.error("User for session " + sessionId + " with userId " + session.getUserId() + " is missing. Session removed.");
- // can happen if user from same host signs in multiple time with multiple clients, after he disconnects with one client
+ // can happen if user from same host signs in multiple time with multiple clients, after they disconnect with one client
disconnect(sessionId, DisconnectReason.ConnectingOtherInstance, session); // direct disconnect
return Optional.empty();
}
diff --git a/Mage.Server/src/main/java/mage/server/UserManager.java b/Mage.Server/src/main/java/mage/server/UserManager.java
index 21ca15d278f..2c7cdea698c 100644
--- a/Mage.Server/src/main/java/mage/server/UserManager.java
+++ b/Mage.Server/src/main/java/mage/server/UserManager.java
@@ -22,6 +22,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
public enum UserManager {
instance;
+ private static final int SERVER_TIMEOUTS_USER_INFORM_OPPONENTS_ABOUT_DISCONNECT_AFTER_SECS = 30; // send to chat info about disconnection troubles, must be more than ping timeout
private static final int SERVER_TIMEOUTS_USER_DISCONNECT_FROM_SERVER_AFTER_SECS = 3 * 60; // removes from all games and chats too (can be seen in users list with disconnected status)
private static final int SERVER_TIMEOUTS_USER_REMOVE_FROM_SERVER_AFTER_SECS = 8 * 60; // removes from users list
@@ -145,6 +146,22 @@ public enum UserManager {
}
}
+ public void informUserOpponents(final UUID userId, final String message) {
+ if (userId != null) {
+ getUser(userId).ifPresent(user
+ -> USER_EXECUTOR.execute(
+ () -> {
+ try {
+ logger.info("INFORM OPPONENTS by " + user.getName() + ": " + message);
+ ChatManager.instance.sendMessageToUserChats(user.getId(), message);
+ } catch (Exception ex) {
+ handleException(ex);
+ }
+ }
+ ));
+ }
+ }
+
public boolean extendUserSession(UUID userId, String pingInfo) {
if (userId != null) {
User user = users.get(userId);
@@ -163,6 +180,8 @@ public enum UserManager {
*/
private void checkExpired() {
try {
+ Calendar calendarInform = Calendar.getInstance();
+ calendarInform.add(Calendar.SECOND, -1 * SERVER_TIMEOUTS_USER_INFORM_OPPONENTS_ABOUT_DISCONNECT_AFTER_SECS);
Calendar calendarExp = Calendar.getInstance();
calendarExp.add(Calendar.SECOND, -1 * SERVER_TIMEOUTS_USER_DISCONNECT_FROM_SERVER_AFTER_SECS);
Calendar calendarRemove = Calendar.getInstance();
@@ -179,6 +198,12 @@ public enum UserManager {
}
for (User user : userList) {
try {
+ if (user.getUserState() != UserState.Offline
+ && user.isExpired(calendarInform.getTime())) {
+ long secsInfo = (Calendar.getInstance().getTimeInMillis() - user.getLastActivity().getTime()) / 1000;
+ informUserOpponents(user.getId(), user.getName() + " got connection problem for " + secsInfo + " secs");
+ }
+
if (user.getUserState() == UserState.Offline) {
if (user.isExpired(calendarRemove.getTime())) {
// removes from users list
diff --git a/Mage.Server/src/main/java/mage/server/game/GameController.java b/Mage.Server/src/main/java/mage/server/game/GameController.java
index 83033d9bb94..7374ddb6a86 100644
--- a/Mage.Server/src/main/java/mage/server/game/GameController.java
+++ b/Mage.Server/src/main/java/mage/server/game/GameController.java
@@ -50,7 +50,7 @@ import java.util.zip.GZIPOutputStream;
public class GameController implements GameCallback {
private static final int GAME_TIMEOUTS_CHECK_JOINING_STATUS_EVERY_SECS = 15; // checks and inform players about joining status
- private static final int GAME_TIMEOUTS_CANCEL_PLAYER_GAME_JOINING_AFTER_INACTIVE_SECS = 4 * 60; // leave player from game if it don't join and inactive on server
+ private static final int GAME_TIMEOUTS_CANCEL_PLAYER_GAME_JOINING_AFTER_INACTIVE_SECS = 2 * 60; // leave player from game if it don't join and inactive on server
private static final ExecutorService gameExecutor = ThreadExecutor.instance.getGameExecutor();
private static final Logger logger = Logger.getLogger(GameController.class);
@@ -235,7 +235,7 @@ public class GameController implements GameCallback {
/**
* We create a timer that will run every 250 ms individually for a player
- * decreasing his internal game counter. Later on this counter is used to
+ * decreasing their internal game counter. Later on this counter is used to
* get time left to play the whole match.
*
* What we also do here is passing Action to PriorityTimer that is the
@@ -336,7 +336,10 @@ public class GameController implements GameCallback {
GameManager.instance.joinGame(game.getId(), user.getId());
logger.debug("Player " + player.getName() + " (disconnected) has joined gameId: " + game.getId());
}
- ChatManager.instance.broadcast(chatId, player.getName(), user.getPingInfo() + " is pending to join the game", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, null);
+ ChatManager.instance.broadcast(chatId, player.getName(), user.getPingInfo()
+ + " is pending to join the game (waiting " + user.getSecondsDisconnected() + " of "
+ + GAME_TIMEOUTS_CANCEL_PLAYER_GAME_JOINING_AFTER_INACTIVE_SECS + " secs)",
+ MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, null);
if (user.getSecondsDisconnected() > GAME_TIMEOUTS_CANCEL_PLAYER_GAME_JOINING_AFTER_INACTIVE_SECS) {
// TODO: 2019.04.22 - if user playing another game on server but not joining (that's the reason?), then that's check will never trigger
// Cancel player join possibility lately after 4 minutes
@@ -1201,6 +1204,7 @@ public class GameController implements GameCallback {
if (activePlayer != null && activePlayer.hasLeft()) {
sb.append("
Found disconnected player! Concede...");
activePlayer.concede(game);
+ activePlayer.leave(); // abort any wait response actions
Phase currentPhase = game.getPhase();
if (currentPhase != null) {
@@ -1221,6 +1225,7 @@ public class GameController implements GameCallback {
Player p = game.getPlayer(state.getChoosingPlayerId());
if (p != null) {
p.concede(game);
+ p.leave(); // abort any wait response actions
}
Phase currentPhase = game.getPhase();
if (currentPhase != null && !fixedAlready) {
@@ -1235,14 +1240,14 @@ public class GameController implements GameCallback {
}
// fix lost priority
+ Player p = game.getPlayer(state.getPriorityPlayerId());
sb.append("
Checking priority player: " + getName(game.getPlayer(state.getPriorityPlayerId())));
- if (state.getPriorityPlayerId() != null) {
- if (game.getPlayer(state.getPriorityPlayerId()).hasLeft()) {
+ if (p != null) {
+ if (p.hasLeft()) {
sb.append("
Found disconnected player! Concede...");
- Player p = game.getPlayer(state.getPriorityPlayerId());
- if (p != null) {
- p.concede(game);
- }
+ p.concede(game);
+ p.leave(); // abort any wait response actions
+
Phase currentPhase = game.getPhase();
if (currentPhase != null && !fixedAlready) {
currentPhase.getStep().skipStep(game, state.getActivePlayerId());
@@ -1250,7 +1255,6 @@ public class GameController implements GameCallback {
sb.append("
Forcibly passing the phase!");
}
}
- sb.append(game.getPlayer(state.getPriorityPlayerId()).getName());
sb.append("");
}
@@ -1272,6 +1276,8 @@ public class GameController implements GameCallback {
sb.append("Not using future Timeout!");
}
sb.append("");
+
+
return sb.toString();
}
}
diff --git a/Mage.Server/src/main/java/mage/server/game/GameSessionWatcher.java b/Mage.Server/src/main/java/mage/server/game/GameSessionWatcher.java
index 086a1cc04d1..ebe711cfcf0 100644
--- a/Mage.Server/src/main/java/mage/server/game/GameSessionWatcher.java
+++ b/Mage.Server/src/main/java/mage/server/game/GameSessionWatcher.java
@@ -1,5 +1,3 @@
-
-
package mage.server.game;
import mage.game.Game;
@@ -101,7 +99,6 @@ public class GameSessionWatcher {
GameView gameView = new GameView(game.getState(), game, null, userId);
processWatchedHands(userId, gameView);
return gameView;
-
}
protected void processWatchedHands(UUID userId, GameView gameView) {
diff --git a/Mage.Server/src/main/java/mage/server/game/GamesRoomManager.java b/Mage.Server/src/main/java/mage/server/game/GamesRoomManager.java
index 83e78ed57e6..73eaeba89bf 100644
--- a/Mage.Server/src/main/java/mage/server/game/GamesRoomManager.java
+++ b/Mage.Server/src/main/java/mage/server/game/GamesRoomManager.java
@@ -1,5 +1,3 @@
-
-
package mage.server.game;
import org.apache.log4j.Logger;
@@ -16,12 +14,14 @@ public enum GamesRoomManager {
private final ConcurrentHashMap rooms = new ConcurrentHashMap<>();
private final UUID mainRoomId;
+ private final UUID mainChatId;
private static final Logger logger = Logger.getLogger(GamesRoomManager.class);
GamesRoomManager() {
GamesRoom mainRoom = new GamesRoomImpl();
mainRoomId = mainRoom.getRoomId();
+ mainChatId = mainRoom.getChatId();
rooms.put(mainRoomId, mainRoom);
}
@@ -35,8 +35,12 @@ public enum GamesRoomManager {
return mainRoomId;
}
+ public UUID getMainChatId() {
+ return mainChatId;
+ }
+
public Optional getRoom(UUID roomId) {
- if(rooms.containsKey(roomId)) {
+ if (rooms.containsKey(roomId)) {
return Optional.of(rooms.get(roomId));
}
logger.error("room not found : " + roomId);
diff --git a/Mage.Server/src/main/java/mage/server/util/SystemUtil.java b/Mage.Server/src/main/java/mage/server/util/SystemUtil.java
index ab298d44b5b..16789e46e64 100644
--- a/Mage.Server/src/main/java/mage/server/util/SystemUtil.java
+++ b/Mage.Server/src/main/java/mage/server/util/SystemUtil.java
@@ -483,12 +483,18 @@ public final class SystemUtil {
gameZone = Zone.LIBRARY;
} else if ("token".equalsIgnoreCase(command.zone)) {
gameZone = Zone.BATTLEFIELD;
+ } else if ("exiled".equalsIgnoreCase(command.zone)) {
+ gameZone = Zone.EXILED;
+ } else if ("outside".equalsIgnoreCase(command.zone)) {
+ gameZone = Zone.OUTSIDE;
} else if ("emblem".equalsIgnoreCase(command.zone)) {
gameZone = Zone.COMMAND;
} else if ("plane".equalsIgnoreCase(command.zone)) {
gameZone = Zone.COMMAND;
} else if ("commander".equalsIgnoreCase(command.zone)) {
gameZone = Zone.COMMAND;
+ } else if ("sideboard".equalsIgnoreCase(command.zone)) {
+ gameZone = Zone.OUTSIDE;
} else {
logger.warn("Unknown zone [" + command.zone + "]: " + line);
continue;
@@ -527,6 +533,11 @@ public final class SystemUtil {
} else {
logger.fatal("Commander card can be used in commander game only: " + command.cardName);
}
+ } else if ("sideboard".equalsIgnoreCase(command.zone) && cardsToLoad.size() > 0) {
+ // put to sideboard
+ for (Card card : cardsToLoad) {
+ player.getSideboard().add(card);
+ }
} else {
// as other card
for (Card card : cardsToLoad) {
@@ -560,8 +571,17 @@ public final class SystemUtil {
break;
case STACK:
card.cast(game, Zone.EXILED, card.getSpellAbility(), player.getId());
+ break;
+ case EXILED:
+ // nothing to do
+ break;
+ case OUTSIDE:
+ card.setZone(Zone.OUTSIDE, game);
+ game.getExile().getPermanentExile().remove(card);
+ break;
default:
card.moveToZone(zone, null, game, false);
+ break;
}
logger.info("Added card to player's " + zone.toString() + ": " + card.getName() + ", player = " + player.getName());
}
diff --git a/Mage.Sets/pom.xml b/Mage.Sets/pom.xml
index 185cde6f19d..dc142fcc850 100644
--- a/Mage.Sets/pom.xml
+++ b/Mage.Sets/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-root
- 1.4.37
+ 1.4.41
mage-sets
diff --git a/Mage.Sets/src/mage/cards/a/AbhorrentOverlord.java b/Mage.Sets/src/mage/cards/a/AbhorrentOverlord.java
index e39aece80d0..57f88bca5f1 100644
--- a/Mage.Sets/src/mage/cards/a/AbhorrentOverlord.java
+++ b/Mage.Sets/src/mage/cards/a/AbhorrentOverlord.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -13,15 +11,14 @@ import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.ColoredManaSymbol;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.StaticFilters;
import mage.game.permanent.token.TokenImpl;
-import mage.game.permanent.token.Token;
+
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class AbhorrentOverlord extends CardImpl {
@@ -35,15 +32,17 @@ public final class AbhorrentOverlord extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
+
// When Abhorrent Overlord enters the battlefield, create a number of 1/1 black Harpy creature tokens with flying equal to your devotion to black.
- Effect effect = new CreateTokenEffect(new AbhorrentOverlordHarpyToken(), new DevotionCount(ColoredManaSymbol.B));
+ Effect effect = new CreateTokenEffect(new AbhorrentOverlordHarpyToken(), DevotionCount.B);
effect.setText("create a number of 1/1 black Harpy creature tokens with flying equal to your devotion to black. (Each {B} in the mana costs of permanents you control counts toward your devotion to black.)");
- this.addAbility(new EntersBattlefieldTriggeredAbility(effect));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(effect).addHint(DevotionCount.B.getHint()));
+
// At the beginning of your upkeep, sacrifice a creature.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeControllerEffect(StaticFilters.FILTER_PERMANENT_CREATURE, 1, null), TargetController.YOU, false));
}
- public AbhorrentOverlord(final AbhorrentOverlord card) {
+ private AbhorrentOverlord(final AbhorrentOverlord card) {
super(card);
}
@@ -55,7 +54,7 @@ public final class AbhorrentOverlord extends CardImpl {
class AbhorrentOverlordHarpyToken extends TokenImpl {
- public AbhorrentOverlordHarpyToken() {
+ AbhorrentOverlordHarpyToken() {
super("Harpy", "1/1 black Harpy creature tokens with flying");
cardType.add(CardType.CREATURE);
color.setBlack(true);
@@ -65,7 +64,8 @@ class AbhorrentOverlordHarpyToken extends TokenImpl {
this.addAbility(FlyingAbility.getInstance());
}
- public AbhorrentOverlordHarpyToken(final AbhorrentOverlordHarpyToken token) {
+
+ private AbhorrentOverlordHarpyToken(final AbhorrentOverlordHarpyToken token) {
super(token);
}
diff --git a/Mage.Sets/src/mage/cards/a/AboshanCephalidEmperor.java b/Mage.Sets/src/mage/cards/a/AboshanCephalidEmperor.java
index c7e2fb8075f..f24172edee9 100644
--- a/Mage.Sets/src/mage/cards/a/AboshanCephalidEmperor.java
+++ b/Mage.Sets/src/mage/cards/a/AboshanCephalidEmperor.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -24,24 +22,25 @@ import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author cbt33
*/
public final class AboshanCephalidEmperor extends CardImpl {
-
-static final FilterControlledCreaturePermanent filter1 = new FilterControlledCreaturePermanent("untapped Cephalid you control");
-static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("creatures without flying");
-static {
- filter1.add(new SubtypePredicate(SubType.CEPHALID));
- filter2.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
-}
+ static final FilterControlledCreaturePermanent filter1 = new FilterControlledCreaturePermanent("untapped Cephalid you control");
+ static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("creatures without flying");
+
+ static {
+ filter1.add(new SubtypePredicate(SubType.CEPHALID));
+ filter2.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
+ }
public AboshanCephalidEmperor(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{U}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{U}");
addSuperType(SuperType.LEGENDARY);
- this.subtype.add(SubType.CEPHALID);
+ this.subtype.add(SubType.CEPHALID, SubType.NOBLE);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
@@ -50,7 +49,7 @@ static {
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new TapTargetCost(new TargetControlledCreaturePermanent(1, 1, filter1, true)));
ability.addTarget(new TargetPermanent());
this.addAbility(ability);
-
+
// {U}{U}{U}: Tap all creatures without flying.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapAllEffect(filter2), new ManaCostsImpl("{U}{U}{U}")));
}
diff --git a/Mage.Sets/src/mage/cards/a/AcclaimedContender.java b/Mage.Sets/src/mage/cards/a/AcclaimedContender.java
new file mode 100644
index 00000000000..7dfaf13e365
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AcclaimedContender.java
@@ -0,0 +1,79 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
+import mage.abilities.dynamicvalue.common.StaticValue;
+import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.constants.Zone;
+import mage.filter.FilterCard;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.filter.predicate.mageobject.SupertypePredicate;
+import mage.filter.predicate.permanent.AnotherPredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AcclaimedContender extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledPermanent(SubType.KNIGHT);
+ private static final FilterCard filter2
+ = new FilterCard("a Knight, Aura, Equipment, or legendary artifact card");
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ filter2.add(Predicates.or(
+ new SubtypePredicate(SubType.KNIGHT),
+ new SubtypePredicate(SubType.AURA),
+ new SubtypePredicate(SubType.EQUIPMENT),
+ Predicates.and(
+ new SupertypePredicate(SuperType.LEGENDARY),
+ new CardTypePredicate(CardType.ARTIFACT)
+ )
+ ));
+ }
+
+ private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter);
+
+ public AcclaimedContender(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // When Acclaimed Contender enters the battlefield, if you control another Knight, look at the top five cards of your library. You may reveal a Knight, Aura, Equipment, or legendary artifact card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
+ this.addAbility(new ConditionalInterveningIfTriggeredAbility(
+ new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(
+ new StaticValue(5), false, new StaticValue(1), filter2, Zone.LIBRARY, false,
+ true, false, Zone.HAND, true, false, false
+ ).setBackInRandomOrder(true)), condition, "When {this} enters the battlefield, " +
+ "if you control another Knight, look at the top five cards of your library. " +
+ "You may reveal a Knight, Aura, Equipment, or legendary artifact card from among them " +
+ "and put it into your hand. Put the rest on the bottom of your library in a random order."
+ ));
+ }
+
+ private AcclaimedContender(final AcclaimedContender card) {
+ super(card);
+ }
+
+ @Override
+ public AcclaimedContender copy() {
+ return new AcclaimedContender(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AcidicSoil.java b/Mage.Sets/src/mage/cards/a/AcidicSoil.java
index cbb5e62189c..eab2f63fe85 100644
--- a/Mage.Sets/src/mage/cards/a/AcidicSoil.java
+++ b/Mage.Sets/src/mage/cards/a/AcidicSoil.java
@@ -24,7 +24,7 @@ public final class AcidicSoil extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}");
- //Acidic Soil deals damage to each player equal to the number of lands he or she controls.
+ //Acidic Soil deals damage to each player equal to the number of lands they control.
this.getSpellAbility().addEffect(new AcidicSoilEffect());
}
@@ -42,7 +42,7 @@ class AcidicSoilEffect extends OneShotEffect {
AcidicSoilEffect() {
super(Outcome.Damage);
- staticText = "{this} deals damage to each player equal to the number of lands he or she controls";
+ staticText = "{this} deals damage to each player equal to the number of lands they control";
}
AcidicSoilEffect(final AcidicSoilEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/a/AcolytesReward.java b/Mage.Sets/src/mage/cards/a/AcolytesReward.java
index 7f48be367e2..41394538689 100644
--- a/Mage.Sets/src/mage/cards/a/AcolytesReward.java
+++ b/Mage.Sets/src/mage/cards/a/AcolytesReward.java
@@ -1,39 +1,39 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.DevotionCount;
import mage.abilities.effects.PreventionEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.ColoredManaSymbol;
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.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class AcolytesReward extends CardImpl {
public AcolytesReward(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");
// 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, Acolyte's Reward deals that much damage to any target.
this.getSpellAbility().addEffect(new AcolytesRewardEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addTarget(new TargetAnyTarget());
+ this.getSpellAbility().addHint(DevotionCount.W.getHint());
}
- public AcolytesReward(final AcolytesReward card) {
+ private AcolytesReward(final AcolytesReward card) {
super(card);
}
@@ -47,12 +47,12 @@ class AcolytesRewardEffect extends PreventionEffectImpl {
protected int amount = 0;
- public AcolytesRewardEffect() {
+ AcolytesRewardEffect() {
super(Duration.EndOfTurn);
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";
}
- public AcolytesRewardEffect(final AcolytesRewardEffect effect) {
+ private AcolytesRewardEffect(final AcolytesRewardEffect effect) {
super(effect);
this.amount = effect.amount;
}
@@ -65,7 +65,7 @@ class AcolytesRewardEffect extends PreventionEffectImpl {
@Override
public void init(Ability source, Game game) {
super.init(source, game);
- amount = new DevotionCount(ColoredManaSymbol.W).calculate(game, source, this);
+ amount = DevotionCount.W.calculate(game, source, this);
}
@Override
@@ -83,39 +83,43 @@ class AcolytesRewardEffect extends PreventionEffectImpl {
} else {
amount = 0;
}
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getControllerId(), source.getSourceId(), source.getControllerId(), toPrevent, false);
- if (!game.replaceEvent(preventEvent)) {
- Permanent targetCreature = game.getPermanent(source.getFirstTarget());
- if (targetCreature != null) {
- 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) {
- game.informPlayers("Acolyte's Reward prevented " + toPrevent + " to " + targetCreature.getName());
- game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE,
- source.getControllerId(), source.getSourceId(), source.getControllerId(), toPrevent));
-
- Player targetPlayer = game.getPlayer(source.getTargets().get(1).getFirstTarget());
- if (targetPlayer != null) {
- targetPlayer.damage(toPrevent, source.getSourceId(), game, false, true);
- game.informPlayers("Acolyte's Reward deals " + toPrevent + " damage to " + targetPlayer.getLogName());
- } else {
- Permanent targetDamageCreature = game.getPermanent(source.getTargets().get(1).getFirstTarget());
- if (targetDamageCreature != null) {
- targetDamageCreature.damage(toPrevent, source.getSourceId(), game, false, true);
- game.informPlayers("Acolyte's Reward deals " + toPrevent + " damage to " + targetDamageCreature.getName());
- }
- }
- }
- }
+ GameEvent preventEvent = new PreventDamageEvent(source.getControllerId(), source.getSourceId(), source.getControllerId(), toPrevent, ((DamageEvent) event).isCombatDamage());
+ if (game.replaceEvent(preventEvent)) {
+ return result;
}
+ Permanent targetCreature = game.getPermanent(source.getFirstTarget());
+ 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(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE,
+ source.getControllerId(), source.getSourceId(), source.getControllerId(), toPrevent));
+
+ Player targetPlayer = game.getPlayer(source.getTargets().get(1).getFirstTarget());
+ if (targetPlayer != null) {
+ targetPlayer.damage(toPrevent, source.getSourceId(), game, false, true);
+ 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(), game, false, true);
+ game.informPlayers("Acolyte's Reward deals " + toPrevent + " damage to " + targetDamageCreature.getName());
return result;
}
diff --git a/Mage.Sets/src/mage/cards/a/AetherBarrier.java b/Mage.Sets/src/mage/cards/a/AetherBarrier.java
index 67821d2d5a1..d7b6233e9c6 100644
--- a/Mage.Sets/src/mage/cards/a/AetherBarrier.java
+++ b/Mage.Sets/src/mage/cards/a/AetherBarrier.java
@@ -25,7 +25,7 @@ public final class AetherBarrier extends CardImpl {
public AetherBarrier(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
- // Whenever a player casts a creature spell, that player sacrifices a permanent unless he or she pays {1}.
+ // Whenever a player casts a creature spell, that player sacrifices a permanent unless they pay {1}.
this.addAbility(new SpellCastAllTriggeredAbility(Zone.BATTLEFIELD, new AetherBarrierEffect(),
StaticFilters.FILTER_SPELL_A_CREATURE, false, SetTargetPointer.PLAYER));
}
@@ -44,7 +44,7 @@ class AetherBarrierEffect extends SacrificeEffect {
AetherBarrierEffect() {
super(new FilterPermanent("permanent to sacrifice"), 1, "that player");
- this.staticText = "that player sacrifices a permanent unless he or she pays {1}";
+ this.staticText = "that player sacrifices a permanent unless they pay {1}";
}
AetherBarrierEffect(final AetherBarrierEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/a/AetherCharge.java b/Mage.Sets/src/mage/cards/a/AetherCharge.java
index 6563c83d149..091d0f168c3 100644
--- a/Mage.Sets/src/mage/cards/a/AetherCharge.java
+++ b/Mage.Sets/src/mage/cards/a/AetherCharge.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
@@ -20,8 +18,9 @@ import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.target.common.TargetOpponentOrPlaneswalker;
+import java.util.UUID;
+
/**
- *
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
public final class AetherCharge extends CardImpl {
@@ -69,7 +68,7 @@ class AetherChargeTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
- if (permanent.isCreature() && permanent.hasSubtype(SubType.BEAST, game)
+ if (permanent != null && permanent.isCreature() && permanent.hasSubtype(SubType.BEAST, game)
&& permanent.isControlledBy(this.controllerId)) {
Effect effect = this.getEffects().get(0);
effect.setValue("damageSource", event.getTargetId());
diff --git a/Mage.Sets/src/mage/cards/a/Aetherspouts.java b/Mage.Sets/src/mage/cards/a/Aetherspouts.java
index 4c565abaad6..20c3cbd87e6 100644
--- a/Mage.Sets/src/mage/cards/a/Aetherspouts.java
+++ b/Mage.Sets/src/mage/cards/a/Aetherspouts.java
@@ -1,4 +1,3 @@
-
package mage.cards.a;
import mage.abilities.Ability;
@@ -21,13 +20,12 @@ import java.util.List;
import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class Aetherspouts extends CardImpl {
public Aetherspouts(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{U}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}{U}");
// For each attacking creature, its owner puts it on the top or bottom of their library.
@@ -73,14 +71,14 @@ class AetherspoutsEffect extends OneShotEffect {
game.getPlayerList();
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- PlayerList playerList = game.getPlayerList();
+ PlayerList playerList = game.getPlayerList().copy();
playerList.setCurrent(game.getActivePlayerId());
Player player = game.getPlayer(game.getActivePlayerId());
Player activePlayer = player;
do {
List permanentsToTop = new ArrayList<>();
List permanentsToBottom = new ArrayList<>();
- for (Permanent permanent:game.getState().getBattlefield().getActivePermanents(new FilterAttackingCreature(), player.getId(), source.getSourceId(), game)) {
+ for (Permanent permanent : game.getState().getBattlefield().getActivePermanents(new FilterAttackingCreature(), player.getId(), source.getSourceId(), game)) {
if (permanent.isOwnedBy(player.getId())) {
if (player.chooseUse(outcome, "Put " + permanent.getLogName() + " to the top? (else it goes to bottom)", source, game)) {
permanentsToTop.add(permanent);
@@ -94,7 +92,7 @@ class AetherspoutsEffect extends OneShotEffect {
// cards to top
Cards cards = new CardsImpl();
List toLibrary = new ArrayList<>();
- for (Permanent permanent: permanentsToTop) {
+ for (Permanent permanent : permanentsToTop) {
if (permanent instanceof PermanentToken) {
toLibrary.add(permanent);
} else {
@@ -128,13 +126,13 @@ class AetherspoutsEffect extends OneShotEffect {
}
}
// move all permanents to lib at the same time
- for(Permanent permanent: toLibrary) {
+ for (Permanent permanent : toLibrary) {
player.moveCardToLibraryWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD, true, false);
}
// cards to bottom
cards.clear();
toLibrary.clear();
- for (Permanent permanent: permanentsToBottom) {
+ for (Permanent permanent : permanentsToBottom) {
if (permanent instanceof PermanentToken) {
toLibrary.add(permanent);
} else {
@@ -161,15 +159,15 @@ class AetherspoutsEffect extends OneShotEffect {
if (cards.size() == 1) {
Card card = cards.get(cards.iterator().next(), game);
Permanent permanent = game.getPermanent(card.getId());
- if (permanent != null) {
+ if (permanent != null) {
toLibrary.add(permanent);
}
}
// move all permanents to lib at the same time
- for(Permanent permanent: toLibrary) {
+ for (Permanent permanent : toLibrary) {
player.moveCardToLibraryWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD, false, false);
}
- player = playerList.getNext(game);
+ player = playerList.getNext(game, false);
} while (player != null && !player.getId().equals(game.getActivePlayerId()) && activePlayer.canRespond());
return true;
}
diff --git a/Mage.Sets/src/mage/cards/a/AetherworksMarvel.java b/Mage.Sets/src/mage/cards/a/AetherworksMarvel.java
index 9fdf02cfa5a..7d751ce034f 100644
--- a/Mage.Sets/src/mage/cards/a/AetherworksMarvel.java
+++ b/Mage.Sets/src/mage/cards/a/AetherworksMarvel.java
@@ -1,4 +1,3 @@
-
package mage.cards.a;
import java.util.Set;
@@ -34,10 +33,15 @@ public final class AetherworksMarvel extends CardImpl {
addSuperType(SuperType.LEGENDARY);
// Whenever a permanent you control is put into a graveyard, you get {E}.
- this.addAbility(new PutIntoGraveFromBattlefieldAllTriggeredAbility(new GetEnergyCountersControllerEffect(1), false, new FilterControlledPermanent("a permanent you control"), false));
+ this.addAbility(new PutIntoGraveFromBattlefieldAllTriggeredAbility(
+ new GetEnergyCountersControllerEffect(1), false,
+ new FilterControlledPermanent("a permanent you control"), false));
- // {T}, Pay {E}{E}{E}{E}{E}{E}: Look at the top six cards of your library. You may cast a card from among them without paying its mana cost. Put the rest on the bottom of your library in a random order.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AetherworksMarvelEffect(), new TapSourceCost());
+ // {T}, Pay {E}{E}{E}{E}{E}{E}: Look at the top six cards of your library.
+ // You may cast a card from among them without paying its mana cost.
+ // Put the rest on the bottom of your library in a random order.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
+ new AetherworksMarvelEffect(), new TapSourceCost());
ability.addCost(new PayEnergyCost(6));
this.addAbility(ability);
}
@@ -56,7 +60,10 @@ class AetherworksMarvelEffect extends OneShotEffect {
AetherworksMarvelEffect() {
super(Outcome.PlayForFree);
- this.staticText = "Look at the top six cards of your library. You may cast a card from among them without paying its mana cost. Put the rest on the bottom of your library in a random order";
+ this.staticText = "Look at the top six cards of your library. "
+ + "You may cast a card from among them without paying "
+ + "its mana cost. Put the rest on the bottom of your "
+ + "library in a random order";
}
AetherworksMarvelEffect(final AetherworksMarvelEffect effect) {
@@ -74,11 +81,18 @@ class AetherworksMarvelEffect extends OneShotEffect {
if (controller != null) {
Set cardsSet = controller.getLibrary().getTopCards(game, 6);
Cards cards = new CardsImpl(cardsSet);
- TargetCard target = new TargetCardInLibrary(0, 1, new FilterNonlandCard("card to cast without paying its mana cost"));
+ TargetCard target = new TargetCardInLibrary(0, 1,
+ new FilterNonlandCard("card to cast without paying its mana cost"));
if (controller.choose(Outcome.PlayForFree, cards, target, game)) {
Card card = controller.getLibrary().getCard(target.getFirstTarget(), game);
- if (card != null && controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
- cards.remove(card);
+ if (card != null) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (cardWasCast) {
+ cards.remove(card);
+ }
}
}
controller.putCardsOnBottomOfLibrary(cards, game, source, false);
diff --git a/Mage.Sets/src/mage/cards/a/AjaniValiantProtector.java b/Mage.Sets/src/mage/cards/a/AjaniValiantProtector.java
index 7bec5ea3f33..146fe5af3ec 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniValiantProtector.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniValiantProtector.java
@@ -1,4 +1,3 @@
-
package mage.cards.a;
import java.util.UUID;
@@ -19,7 +18,7 @@ import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.counters.CounterType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCreaturePermanent;
/**
@@ -41,7 +40,7 @@ public final class AjaniValiantProtector extends CardImpl {
this.addAbility(ability);
// +1: Reveal cards from the top of your library until you reveal a creature card. Put that card into your hand and the rest on the bottom of your library in a random order.
- this.addAbility(new LoyaltyAbility(new RevealCardsFromLibraryUntilEffect(new FilterCreatureCard(), Zone.HAND, Zone.LIBRARY), 1));
+ this.addAbility(new LoyaltyAbility(new RevealCardsFromLibraryUntilEffect(StaticFilters.FILTER_CARD_CREATURE, Zone.HAND, Zone.LIBRARY), 1));
// -11: Put X +1/+1 counters on target creature, where X is your life total. That creature gains trample until end of turn.
Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(), ControllerLifeCount.instance);
diff --git a/Mage.Sets/src/mage/cards/a/AkoumHellkite.java b/Mage.Sets/src/mage/cards/a/AkoumHellkite.java
index 24a13cc1423..9a512bb57c8 100644
--- a/Mage.Sets/src/mage/cards/a/AkoumHellkite.java
+++ b/Mage.Sets/src/mage/cards/a/AkoumHellkite.java
@@ -23,7 +23,6 @@ import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
- *
* @author fireshoes
*/
public final class AkoumHellkite extends CardImpl {
@@ -56,9 +55,6 @@ public final class AkoumHellkite extends CardImpl {
class AkoumHellkiteTriggeredAbility extends TriggeredAbilityImpl {
- private static final String text = "Landfall — Whenever a land enters the battlefield under your control, {this} deals 1 damage to any target. "
- + "If that land is a Mountain, Akoum Hellkite deals 2 damage to that permanent or player instead.";
-
public AkoumHellkiteTriggeredAbility() {
super(Zone.BATTLEFIELD, new AkoumHellkiteDamageEffect());
}
@@ -98,7 +94,8 @@ class AkoumHellkiteTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
- return text;
+ return "Landfall — Whenever a land enters the battlefield under your control, " +
+ "{this} deals 1 damage to any target. If that land is a Mountain, {this} deals 2 damage instead.";
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AlelaArtfulProvocateur.java b/Mage.Sets/src/mage/cards/a/AlelaArtfulProvocateur.java
new file mode 100644
index 00000000000..eb7db509d7b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AlelaArtfulProvocateur.java
@@ -0,0 +1,79 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.common.SpellCastControllerTriggeredAbility;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.continuous.BoostAllEffect;
+import mage.abilities.keyword.DeathtouchAbility;
+import mage.abilities.keyword.FlyingAbility;
+import mage.abilities.keyword.LifelinkAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterSpell;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.AbilityPredicate;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.game.permanent.token.FaerieToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AlelaArtfulProvocateur extends CardImpl {
+
+ private static final FilterCreaturePermanent filter
+ = new FilterCreaturePermanent("creatures you control with flying");
+ private static final FilterSpell filter2 = new FilterSpell("an artifact or enchantment spell");
+
+ static {
+ filter.add(new AbilityPredicate(FlyingAbility.class));
+ filter.add(new ControllerPredicate(TargetController.YOU));
+ filter2.add(Predicates.or(
+ new CardTypePredicate(CardType.ARTIFACT),
+ new CardTypePredicate(CardType.ENCHANTMENT)
+ ));
+ }
+
+ public AlelaArtfulProvocateur(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}{B}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.FAERIE);
+ this.subtype.add(SubType.WARLOCK);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Deathtouch
+ this.addAbility(DeathtouchAbility.getInstance());
+
+ // Lifelink
+ this.addAbility(LifelinkAbility.getInstance());
+
+ // Other creatures you control with flying get +1/+0.
+ this.addAbility(new SimpleStaticAbility(new BoostAllEffect(
+ 1, 0, Duration.WhileOnBattlefield, filter, true
+ )));
+
+ // Whenever you cast an artifact or enchantment spell, create a 1/1 blue Faerie creature token with flying.
+ this.addAbility(new SpellCastControllerTriggeredAbility(
+ new CreateTokenEffect(new FaerieToken()), filter2, false
+ ));
+ }
+
+ private AlelaArtfulProvocateur(final AlelaArtfulProvocateur card) {
+ super(card);
+ }
+
+ @Override
+ public AlelaArtfulProvocateur copy() {
+ return new AlelaArtfulProvocateur(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AllIsDust.java b/Mage.Sets/src/mage/cards/a/AllIsDust.java
index 1dc704a3e2c..d7cfaffe113 100644
--- a/Mage.Sets/src/mage/cards/a/AllIsDust.java
+++ b/Mage.Sets/src/mage/cards/a/AllIsDust.java
@@ -38,7 +38,7 @@ class AllIsDustEffect extends OneShotEffect {
AllIsDustEffect() {
super(Outcome.DestroyPermanent);
- staticText = "Each player sacrifices all colored permanents he or she controls";
+ staticText = "Each player sacrifices all colored permanents they control";
}
AllIsDustEffect(final AllIsDustEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/a/AllThatGlitters.java b/Mage.Sets/src/mage/cards/a/AllThatGlitters.java
new file mode 100644
index 00000000000..830f1f8e00e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AllThatGlitters.java
@@ -0,0 +1,61 @@
+package mage.cards.a;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterArtifactOrEnchantmentPermanent;
+import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AllThatGlitters extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterArtifactOrEnchantmentPermanent();
+
+ static {
+ filter.add(new ControllerPredicate(TargetController.YOU));
+ }
+
+ private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
+
+ public AllThatGlitters(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
+
+ this.subtype.add(SubType.AURA);
+
+ // Enchant creature
+ TargetPermanent auraTarget = new TargetCreaturePermanent();
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // Enchanted creature gets +1/+1 for each artifact and/or enchantment you control.
+ this.addAbility(new SimpleStaticAbility(new BoostEnchantedEffect(
+ xValue, xValue, Duration.WhileOnBattlefield
+ ).setText("enchanted creature gets +1/+1 for each artifact and/or enchantment you control")));
+ }
+
+ private AllThatGlitters(final AllThatGlitters card) {
+ super(card);
+ }
+
+ @Override
+ public AllThatGlitters copy() {
+ return new AllThatGlitters(this);
+ }
+}
+// someBODY
diff --git a/Mage.Sets/src/mage/cards/a/AlliedStrategies.java b/Mage.Sets/src/mage/cards/a/AlliedStrategies.java
index 51f02229423..4a62fb0f8b1 100644
--- a/Mage.Sets/src/mage/cards/a/AlliedStrategies.java
+++ b/Mage.Sets/src/mage/cards/a/AlliedStrategies.java
@@ -19,7 +19,7 @@ public final class AlliedStrategies extends CardImpl {
public AlliedStrategies(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}");
- // Domain - Target player draws a card for each basic land type among lands he or she controls.
+ // Domain - Target player draws a card for each basic land type among lands they control.
this.getSpellAbility().addEffect(new DrawCardTargetEffect(new DomainValue(true)));
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().setAbilityWord(AbilityWord.DOMAIN);
diff --git a/Mage.Sets/src/mage/cards/a/AllureOfTheUnknown.java b/Mage.Sets/src/mage/cards/a/AllureOfTheUnknown.java
new file mode 100644
index 00000000000..168a48842d1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AllureOfTheUnknown.java
@@ -0,0 +1,96 @@
+package mage.cards.a;
+
+import mage.MageObjectReference;
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.*;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.TargetCard;
+import mage.target.common.TargetCardInLibrary;
+import mage.target.common.TargetOpponent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AllureOfTheUnknown extends CardImpl {
+
+ public AllureOfTheUnknown(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}{R}");
+
+ // Reveal the top six cards of your library. An opponent exiles a nonland card from among them, then you put the rest into your hand. That opponent may cast the exiled card without paying its mana cost.
+ this.getSpellAbility().addEffect(new AllureOfTheUnknownEffect());
+ }
+
+ private AllureOfTheUnknown(final AllureOfTheUnknown card) {
+ super(card);
+ }
+
+ @Override
+ public AllureOfTheUnknown copy() {
+ return new AllureOfTheUnknown(this);
+ }
+}
+
+class AllureOfTheUnknownEffect extends OneShotEffect {
+
+ AllureOfTheUnknownEffect() {
+ super(Outcome.Benefit);
+ staticText = "Reveal the top six cards of your library. " +
+ "An opponent exiles a nonland card from among them, " +
+ "then you put the rest into your hand. " +
+ "That opponent may cast the exiled card without paying its mana cost.";
+ }
+
+ private AllureOfTheUnknownEffect(final AllureOfTheUnknownEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public AllureOfTheUnknownEffect copy() {
+ return new AllureOfTheUnknownEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 6));
+ player.revealCards(source, cards, game);
+ if (cards.count(StaticFilters.FILTER_CARD_NON_LAND, game) == 0) {
+ return player.moveCards(cards, Zone.HAND, source, game);
+ }
+ TargetOpponent targetOpponent = new TargetOpponent(true);
+ if (!player.choose(outcome, targetOpponent, source.getSourceId(), game)) {
+ return false;
+ }
+ Player opponent = game.getPlayer(targetOpponent.getFirstTarget());
+ if (opponent == null) {
+ return false;
+ }
+ TargetCard targetCard = new TargetCardInLibrary(StaticFilters.FILTER_CARD_A_NON_LAND);
+ opponent.choose(Outcome.Exile, cards, targetCard, game);
+ Card card = game.getCard(targetCard.getFirstTarget());
+ if (player.moveCards(card, Zone.EXILED, source, game)
+ && card != null
+ && game.getState().getZone(card.getId()) == Zone.EXILED) {
+ cards.remove(card);
+ }
+ player.moveCards(cards, Zone.HAND, source, game);
+ if (opponent.chooseUse(outcome, "Cast the exiled card without paying its mana cost?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ opponent.cast(opponent.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/a/AltarOfBone.java b/Mage.Sets/src/mage/cards/a/AltarOfBone.java
index ec907a76de4..cbfd837b189 100644
--- a/Mage.Sets/src/mage/cards/a/AltarOfBone.java
+++ b/Mage.Sets/src/mage/cards/a/AltarOfBone.java
@@ -1,4 +1,3 @@
-
package mage.cards.a;
import java.util.UUID;
@@ -7,8 +6,8 @@ import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
+import mage.filter.StaticFilters;
import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
-import mage.filter.common.FilterCreatureCard;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetControlledCreaturePermanent;
@@ -24,7 +23,7 @@ public final class AltarOfBone extends CardImpl {
// As an additional cost to cast Altar of Bone, sacrifice a creature.
this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
// Search your library for a creature card, reveal that card, and put it into your hand. Then shuffle your library.
- this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(new FilterCreatureCard()), true));
+ this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_CREATURE), true));
}
public AltarOfBone(final AltarOfBone card) {
diff --git a/Mage.Sets/src/mage/cards/a/AminatouTheFateShifter.java b/Mage.Sets/src/mage/cards/a/AminatouTheFateshifter.java
similarity index 96%
rename from Mage.Sets/src/mage/cards/a/AminatouTheFateShifter.java
rename to Mage.Sets/src/mage/cards/a/AminatouTheFateshifter.java
index bdd8b1e1ed1..b9a89f87e3f 100644
--- a/Mage.Sets/src/mage/cards/a/AminatouTheFateShifter.java
+++ b/Mage.Sets/src/mage/cards/a/AminatouTheFateshifter.java
@@ -34,7 +34,7 @@ import java.util.UUID;
*
* @author Colin Redman
*/
-public class AminatouTheFateShifter extends CardImpl {
+public class AminatouTheFateshifter extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("permanent you own");
@@ -43,7 +43,7 @@ public class AminatouTheFateShifter extends CardImpl {
filter.add(AnotherPredicate.instance);
}
- public AminatouTheFateShifter(UUID ownerId, CardSetInfo setInfo) {
+ public AminatouTheFateshifter(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{W}{U}{B}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AMINATOU);
@@ -69,13 +69,13 @@ public class AminatouTheFateShifter extends CardImpl {
this.addAbility(CanBeYourCommanderAbility.getInstance());
}
- public AminatouTheFateShifter(final AminatouTheFateShifter card) {
+ public AminatouTheFateshifter(final AminatouTheFateshifter card) {
super(card);
}
@Override
- public AminatouTheFateShifter copy() {
- return new AminatouTheFateShifter(this);
+ public AminatouTheFateshifter copy() {
+ return new AminatouTheFateshifter(this);
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AminatousAugury.java b/Mage.Sets/src/mage/cards/a/AminatousAugury.java
index 8741698be09..9e230a447ca 100644
--- a/Mage.Sets/src/mage/cards/a/AminatousAugury.java
+++ b/Mage.Sets/src/mage/cards/a/AminatousAugury.java
@@ -1,12 +1,25 @@
package mage.cards.a;
import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.OneShotEffect;
-import mage.cards.*;
-import mage.constants.*;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.cards.Cards;
+import mage.cards.CardsImpl;
+import mage.choices.Choice;
+import mage.choices.ChoiceImpl;
+import mage.constants.AsThoughEffectType;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.ExileZone;
import mage.game.Game;
@@ -14,9 +27,6 @@ import mage.players.Player;
import mage.target.TargetCard;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
-import java.util.UUID;
-import mage.choices.Choice;
-import mage.choices.ChoiceImpl;
/**
*
@@ -81,12 +91,14 @@ class AminatousAuguryEffect extends OneShotEffect {
Zone.EXILED,
StaticFilters.FILTER_CARD_LAND_A
);
- if (controller.chooseUse(Outcome.PutLandInPlay, "Put a land from among the exiled cards into play?", source, game)) {
- if (controller.choose(Outcome.PutLandInPlay, cardsToCast, target, game)) {
- Card card = cardsToCast.get(target.getFirstTarget(), game);
- if (card != null) {
- cardsToCast.remove(card);
- controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null);
+ if (cardsToCast.count(StaticFilters.FILTER_CARD_LAND, game) > 0) {
+ if (controller.chooseUse(Outcome.PutLandInPlay, "Put a land from among the exiled cards into play?", source, game)) {
+ if (controller.choose(Outcome.PutLandInPlay, cardsToCast, target, game)) {
+ Card card = cardsToCast.get(target.getFirstTarget(), game);
+ if (card != null) {
+ cardsToCast.remove(card);
+ controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null);
+ }
}
}
}
@@ -124,12 +136,12 @@ class AminatousAuguryCastFromExileEffect extends AsThoughEffectImpl {
@Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
Player player = game.getPlayer(affectedControllerId);
- EnumSet cardTypes = EnumSet.noneOf(CardType.class);
- Boolean checkType = false;
+ EnumSet usedCardTypes = EnumSet.noneOf(CardType.class);
+
if (game.getState().getValue(source.getSourceId().toString() + "cardTypes") != null) {
- cardTypes = (EnumSet) game.getState().getValue(source.getSourceId().toString() + "cardTypes");
+ usedCardTypes = (EnumSet) game.getState().getValue(source.getSourceId().toString() + "cardTypes");
}
- //TODO add code for choosing from multiple card types and adding additional costs to the card
+ //TODO add code for adding additional costs to the card
if (player != null
&& sourceId != null
&& sourceId.equals(getTargetPointer().getFirst(game, source))
@@ -137,15 +149,35 @@ class AminatousAuguryCastFromExileEffect extends AsThoughEffectImpl {
Card card = game.getCard(sourceId);
if (card != null
&& game.getState().getZone(sourceId) == Zone.EXILED) {
- for (CardType cardT : cardTypes) {
- if (card.getCardType().contains(cardT)) {
- checkType = true;
+ EnumSet unusedCardTypes = EnumSet.noneOf(CardType.class);
+ for (CardType cardT : card.getCardType()) {
+ if (!usedCardTypes.contains(cardT)) {
+ unusedCardTypes.add(cardT);
}
}
- if (!checkType) {
- player.setCastSourceIdWithAlternateMana(sourceId, null, null);
- cardTypes.addAll(card.getCardType());
- game.getState().setValue(source.getSourceId().toString() + "cardTypes", cardTypes);
+ if (!unusedCardTypes.isEmpty()) {
+ if (!game.inCheckPlayableState()) { // some actions may not be done while the game only checks if a card can be cast
+ // Select the card type to consume and remove all not seleczted card types
+ if (unusedCardTypes.size() > 1) {
+ Choice choice = new ChoiceImpl(true);
+ choice.setMessage("Which card type do you want to consume?");
+ Set choices = choice.getChoices();
+ for (CardType cardType : unusedCardTypes) {
+ choices.add(cardType.toString());
+ }
+ player.choose(Outcome.Detriment, choice, game);
+ for (Iterator iterator = unusedCardTypes.iterator(); iterator.hasNext();) {
+ CardType next = iterator.next();
+ if (!next.toString().equals(choice.getChoice())) {
+ iterator.remove();
+ }
+ }
+ usedCardTypes.add(CardType.fromString(choice.getChoice()));
+ }
+ usedCardTypes.addAll(unusedCardTypes);
+ player.setCastSourceIdWithAlternateMana(sourceId, null, null);
+ game.getState().setValue(source.getSourceId().toString() + "cardTypes", usedCardTypes);
+ }
return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/AncientRunes.java b/Mage.Sets/src/mage/cards/a/AncientRunes.java
index 32ed6fdb308..1ab81ed7941 100644
--- a/Mage.Sets/src/mage/cards/a/AncientRunes.java
+++ b/Mage.Sets/src/mage/cards/a/AncientRunes.java
@@ -25,7 +25,7 @@ public final class AncientRunes extends CardImpl {
public AncientRunes(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}");
- // At the beginning of each player's upkeep, Ancient Runes deals damage to that player equal to the number of artifacts he or she controls.
+ // At the beginning of each player's upkeep, Ancient Runes deals damage to that player equal to the number of artifacts they control.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new AncientRunesDamageTargetEffect(), TargetController.ANY, false, true));
}
@@ -53,7 +53,7 @@ class AncientRunesDamageTargetEffect extends OneShotEffect{
@Override
public String getText(Mode mode) {
- return "{this} deals damage to that player equal to the number of artifacts he or she controls";
+ return "{this} deals damage to that player equal to the number of artifacts they control";
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/AngelOfSerenity.java b/Mage.Sets/src/mage/cards/a/AngelOfSerenity.java
index 4dfb63bbc40..dbcca3ae73a 100644
--- a/Mage.Sets/src/mage/cards/a/AngelOfSerenity.java
+++ b/Mage.Sets/src/mage/cards/a/AngelOfSerenity.java
@@ -1,6 +1,5 @@
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -13,18 +12,21 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard;
+import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardIdPredicate;
import mage.target.Target;
import mage.target.common.TargetCardInGraveyardOrBattlefield;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class AngelOfSerenity extends CardImpl {
-
+
private static final String rule = "you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards.";
public AngelOfSerenity(UUID ownerId, CardSetInfo setInfo) {
@@ -38,10 +40,11 @@ public final class AngelOfSerenity extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// When Angel of Serenity enters the battlefield, you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards.
- FilterCreatureCard filter = new FilterCreatureCard("creatures from the battlefield and/or a graveyard");
- filter.add(Predicates.not(new CardIdPredicate(this.getId())));
+ FilterCreaturePermanent filterBattle = new FilterCreaturePermanent("other target creatures");
+ filterBattle.add(Predicates.not(new CardIdPredicate(this.getId())));
+ FilterCreatureCard filterGrave = StaticFilters.FILTER_CARD_CREATURE;
Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetForSourceEffect().setText(rule), true);
- Target target = new TargetCardInGraveyardOrBattlefield(0, 3, filter);
+ Target target = new TargetCardInGraveyardOrBattlefield(0, 3, filterGrave, filterBattle);
ability.addTarget(target);
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/a/AngelicChorus.java b/Mage.Sets/src/mage/cards/a/AngelicChorus.java
index 7bf37261066..e9c789a5553 100644
--- a/Mage.Sets/src/mage/cards/a/AngelicChorus.java
+++ b/Mage.Sets/src/mage/cards/a/AngelicChorus.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
@@ -16,14 +14,15 @@ import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.players.Player;
+import java.util.UUID;
+
/**
- *
* @author Backfir3
*/
public final class AngelicChorus extends CardImpl {
public AngelicChorus(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{W}");
// Whenever a creature enters the battlefield under your control, you gain life equal to its toughness.
this.addAbility(new AngelicChorusTriggeredAbility());
@@ -57,7 +56,8 @@ class AngelicChorusTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
- if (permanent.isCreature()
+ if (permanent != null
+ && permanent.isCreature()
&& permanent.isControlledBy(this.controllerId)) {
this.getEffects().get(0).setValue("lifeSource", event.getTargetId());
return true;
diff --git a/Mage.Sets/src/mage/cards/a/AnimalMagnetism.java b/Mage.Sets/src/mage/cards/a/AnimalMagnetism.java
index c5a369e1a8a..58f04dd0a61 100644
--- a/Mage.Sets/src/mage/cards/a/AnimalMagnetism.java
+++ b/Mage.Sets/src/mage/cards/a/AnimalMagnetism.java
@@ -1,4 +1,3 @@
-
package mage.cards.a;
import java.util.Set;
@@ -10,7 +9,7 @@ import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.Target;
@@ -24,7 +23,7 @@ import mage.target.common.TargetOpponent;
public final class AnimalMagnetism extends CardImpl {
public AnimalMagnetism(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}");
// Reveal the top five cards of your library. An opponent chooses a creature card from among them. Put that card onto the battlefield and the rest into your graveyard.
this.getSpellAbility().addEffect(new AnimalMagnetismEffect());
@@ -76,7 +75,7 @@ class AnimalMagnetismEffect extends OneShotEffect {
controller.chooseTarget(Outcome.Detriment, target, source, game);
opponent = game.getPlayer(target.getFirstTarget());
}
- TargetCard target = new TargetCard(1, Zone.LIBRARY, new FilterCreatureCard());
+ TargetCard target = new TargetCard(1, Zone.LIBRARY, StaticFilters.FILTER_CARD_CREATURE);
opponent.chooseTarget(outcome, cards, target, source, game);
cardToBattlefield = game.getCard(target.getFirstTarget());
}
diff --git a/Mage.Sets/src/mage/cards/a/AnimatingFaerie.java b/Mage.Sets/src/mage/cards/a/AnimatingFaerie.java
new file mode 100644
index 00000000000..64f2f4ece3f
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AnimatingFaerie.java
@@ -0,0 +1,66 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.effects.common.continuous.AddCardTypeTargetEffect;
+import mage.abilities.effects.common.continuous.SetPowerToughnessTargetEffect;
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledArtifactPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AnimatingFaerie extends AdventureCard {
+
+ private static final FilterPermanent filter
+ = new FilterControlledArtifactPermanent("noncreature artifact you control");
+
+ static {
+ filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
+ }
+
+ public AnimatingFaerie(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{2}{U}", "Bring to Life", "{2}{U}");
+
+ this.subtype.add(SubType.FAERIE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Bring to Life
+ // Target noncreature artifact you control becomes a 0/0 artifact creature. Put four +1/+1 counters on it.
+ this.getSpellCard().getSpellAbility().addEffect(new AddCardTypeTargetEffect(
+ Duration.EndOfGame, CardType.ARTIFACT, CardType.CREATURE
+ ).setText("Target noncreature artifact you control becomes"));
+ this.getSpellCard().getSpellAbility().addEffect(new SetPowerToughnessTargetEffect(
+ 0, 0, Duration.EndOfGame
+ ).setText("a 0/0 artifact creature."));
+ this.getSpellCard().getSpellAbility().addEffect(new AddCountersTargetEffect(
+ CounterType.P1P1.createInstance(4)
+ ).setText("Put four +1/+1 counters on it."));
+ this.getSpellCard().getSpellAbility().addTarget(new TargetPermanent(filter));
+ }
+
+ private AnimatingFaerie(final AnimatingFaerie card) {
+ super(card);
+ }
+
+ @Override
+ public AnimatingFaerie copy() {
+ return new AnimatingFaerie(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/Apathy.java b/Mage.Sets/src/mage/cards/a/Apathy.java
new file mode 100644
index 00000000000..5469844970b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/Apathy.java
@@ -0,0 +1,93 @@
+package mage.cards.a;
+
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect;
+import mage.abilities.keyword.EnchantAbility;
+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.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class Apathy extends CardImpl {
+
+ public Apathy(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}");
+
+ this.subtype.add(SubType.AURA);
+
+ // Enchant creature
+ TargetPermanent auraTarget = new TargetCreaturePermanent();
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // Enchanted creature doesn't untap during its controller's untap step.
+ this.addAbility(new SimpleStaticAbility(new DontUntapInControllersUntapStepEnchantedEffect()));
+
+ // At the beginning of the upkeep of enchanted creature’s controller, that player may discard a card at random. If the player does, untap that creature.
+ this.addAbility(new BeginningOfUpkeepTriggeredAbility(
+ new ApathyEffect(), TargetController.CONTROLLER_ATTACHED_TO, false
+ ));
+ }
+
+ private Apathy(final Apathy card) {
+ super(card);
+ }
+
+ @Override
+ public Apathy copy() {
+ return new Apathy(this);
+ }
+}
+
+class ApathyEffect extends OneShotEffect {
+
+ ApathyEffect() {
+ super(Outcome.Benefit);
+ staticText = "that player may discard a card at random. If the player does, untap that creature";
+ }
+
+ private ApathyEffect(final ApathyEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ApathyEffect copy() {
+ return new ApathyEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(game.getActivePlayerId());
+ if (player == null) {
+ return false;
+ }
+ if (!player.chooseUse(outcome, "Discard a card at random to untap enchanted creature?", source, game)
+ || player.discardOne(true, source, game) == null) {
+ return false;
+ }
+ Permanent permanent = game.getPermanent(source.getSourceId());
+ if (permanent == null) {
+ return false;
+ }
+ permanent = game.getPermanent(permanent.getAttachedTo());
+ return permanent != null && permanent.untap(game);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/a/ArcanistsOwl.java b/Mage.Sets/src/mage/cards/a/ArcanistsOwl.java
new file mode 100644
index 00000000000..eb42874e684
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/ArcanistsOwl.java
@@ -0,0 +1,55 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.dynamicvalue.common.StaticValue;
+import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.FilterCard;
+import mage.filter.common.FilterArtifactOrEnchantmentCard;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ArcanistsOwl extends CardImpl {
+
+ private static final FilterCard filter = new FilterArtifactOrEnchantmentCard();
+
+ public ArcanistsOwl(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{W/U}{W/U}{W/U}{W/U}");
+
+ this.subtype.add(SubType.BIRD);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // When Arcanist's Owl enters the battlefield, look at the top four cards of your library. You may reveal an artifact or enchantment card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(
+ new LookLibraryAndPickControllerEffect(
+ new StaticValue(4), false, new StaticValue(1), filter,
+ Zone.LIBRARY, false, true, false, Zone.HAND,
+ true, false, false
+ ).setBackInRandomOrder(true).setText("Look at the top four cards of your library. " +
+ "You may reveal an artifact or enchantment from among them and put it into your hand. " +
+ "Put the rest on the bottom of your library in a random order.")
+ ));
+ }
+
+ private ArcanistsOwl(final ArcanistsOwl card) {
+ super(card);
+ }
+
+ @Override
+ public ArcanistsOwl copy() {
+ return new ArcanistsOwl(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/ArchfiendOfDepravity.java b/Mage.Sets/src/mage/cards/a/ArchfiendOfDepravity.java
index d95b95c2ace..08b3f76ec44 100644
--- a/Mage.Sets/src/mage/cards/a/ArchfiendOfDepravity.java
+++ b/Mage.Sets/src/mage/cards/a/ArchfiendOfDepravity.java
@@ -36,7 +36,7 @@ public final class ArchfiendOfDepravity extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
- // At the beginning of each opponent's end step, that player chooses up to two creatures he or she controls, then sacrifices the rest.
+ // At the beginning of each opponent's end step, that player chooses up to two creatures they control, then sacrifices the rest.
this.addAbility(new BeginningOfEndStepTriggeredAbility(new ArchfiendOfDepravityEffect(), TargetController.OPPONENT, false));
}
@@ -54,7 +54,7 @@ class ArchfiendOfDepravityEffect extends OneShotEffect {
public ArchfiendOfDepravityEffect() {
super(Outcome.Benefit); // AI should select two creatures if possible so it has to be a benefit
- this.staticText = "that player chooses up to two creatures he or she controls, then sacrifices the rest";
+ this.staticText = "that player chooses up to two creatures they control, then sacrifices the rest";
}
public ArchfiendOfDepravityEffect(final ArchfiendOfDepravityEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/a/ArchfiendOfSpite.java b/Mage.Sets/src/mage/cards/a/ArchfiendOfSpite.java
index be750846580..fc186f0ba0e 100644
--- a/Mage.Sets/src/mage/cards/a/ArchfiendOfSpite.java
+++ b/Mage.Sets/src/mage/cards/a/ArchfiendOfSpite.java
@@ -73,7 +73,7 @@ class ArchfiendOfSpiteAbility extends TriggeredAbilityImpl {
@Override
public boolean checkEventType(GameEvent event, Game game) {
- return event.getType() == GameEvent.EventType.DAMAGED_PLAYER;
+ return event.getType() == GameEvent.EventType.DAMAGED_CREATURE;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/ArchonOfAbsolution.java b/Mage.Sets/src/mage/cards/a/ArchonOfAbsolution.java
new file mode 100644
index 00000000000..f1aec8f3df4
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/ArchonOfAbsolution.java
@@ -0,0 +1,49 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.ObjectColor;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.combat.CantAttackYouUnlessPayManaAllEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.abilities.keyword.ProtectionAbility;
+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 ArchonOfAbsolution extends CardImpl {
+
+ public ArchonOfAbsolution(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
+
+ this.subtype.add(SubType.ARCHON);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(2);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Protection from white
+ this.addAbility(ProtectionAbility.from(ObjectColor.WHITE));
+
+ // Creatures can't attack you or a planeswalker you control unless their controller pays {1} for each of those creatures.
+ this.addAbility(new SimpleStaticAbility(
+ new CantAttackYouUnlessPayManaAllEffect(new ManaCostsImpl("{1}"), true)
+ ));
+ }
+
+ private ArchonOfAbsolution(final ArchonOfAbsolution card) {
+ super(card);
+ }
+
+ @Override
+ public ArchonOfAbsolution copy() {
+ return new ArchonOfAbsolution(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/ArchonOfRedemption.java b/Mage.Sets/src/mage/cards/a/ArchonOfRedemption.java
index 4107f3f9901..c450ed30746 100644
--- a/Mage.Sets/src/mage/cards/a/ArchonOfRedemption.java
+++ b/Mage.Sets/src/mage/cards/a/ArchonOfRedemption.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.GainLifeEffect;
@@ -16,6 +14,8 @@ import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
+import java.util.UUID;
+
/**
* @author Loki
*/
@@ -66,7 +66,8 @@ class ArchonOfRedemptionTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
- if (permanent.isControlledBy(getControllerId())
+ if (permanent != null
+ && permanent.isControlledBy(getControllerId())
&& permanent.isCreature()
&& (permanent.getId().equals(getSourceId())
|| (permanent.getAbilities().contains(FlyingAbility.getInstance())))) {
diff --git a/Mage.Sets/src/mage/cards/a/ArcticFoxes.java b/Mage.Sets/src/mage/cards/a/ArcticFoxes.java
new file mode 100644
index 00000000000..a7a503331c4
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/ArcticFoxes.java
@@ -0,0 +1,74 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.decorator.ConditionalRestrictionEffect;
+import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.common.FilterLandPermanent;
+import mage.filter.predicate.mageobject.PowerPredicate;
+import mage.filter.predicate.mageobject.SupertypePredicate;
+import mage.game.Game;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ArcticFoxes extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
+
+ static {
+ filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 1));
+ }
+
+ public ArcticFoxes(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
+
+ this.subtype.add(SubType.FOX);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Creatures with power 2 or greater can't block Arctic Foxes as long as defending player controls a snow land.
+ this.addAbility(new SimpleStaticAbility(new ConditionalRestrictionEffect(
+ new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield),
+ ArcticFoxesCondition.instance, "creatures with power 2 or greater can't block {this}" +
+ " as long as defending player controls a snow land"
+ )));
+ }
+
+ private ArcticFoxes(final ArcticFoxes card) {
+ super(card);
+ }
+
+ @Override
+ public ArcticFoxes copy() {
+ return new ArcticFoxes(this);
+ }
+}
+
+enum ArcticFoxesCondition implements Condition {
+ instance;
+
+ private static final FilterPermanent filter = new FilterLandPermanent();
+
+ static {
+ filter.add(new SupertypePredicate(SuperType.SNOW));
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ UUID defenderId = game.getCombat().getDefendingPlayerId(source.getSourceId(), game);
+ if (defenderId == null) {
+ return false;
+ }
+ return game.getBattlefield().contains(filter, defenderId, 1, game);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/a/ArdenvalePaladin.java b/Mage.Sets/src/mage/cards/a/ArdenvalePaladin.java
new file mode 100644
index 00000000000..4c93d789588
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/ArdenvalePaladin.java
@@ -0,0 +1,46 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.condition.common.AdamantCondition;
+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.watchers.common.ManaSpentToCastWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ArdenvalePaladin extends CardImpl {
+
+ public ArdenvalePaladin(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(5);
+
+ // Adamant — If at least three white mana was spent to cast this spell, Ardenvale Paladin enters the battlefield with a +1/+1 counter on it.
+ this.addAbility(new EntersBattlefieldAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
+ AdamantCondition.WHITE, "
Adamant — " +
+ "If at least three white mana was spent to cast this spell, " +
+ "{this} enters the battlefield with a +1/+1 counter on it.", ""
+ ), new ManaSpentToCastWatcher());
+ }
+
+ private ArdenvalePaladin(final ArdenvalePaladin card) {
+ super(card);
+ }
+
+ @Override
+ public ArdenvalePaladin copy() {
+ return new ArdenvalePaladin(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/ArdenvaleTactician.java b/Mage.Sets/src/mage/cards/a/ArdenvaleTactician.java
new file mode 100644
index 00000000000..bc14efe0b1a
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/ArdenvaleTactician.java
@@ -0,0 +1,44 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.abilities.effects.common.TapTargetEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ArdenvaleTactician extends AdventureCard {
+
+ public ArdenvaleTactician(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.INSTANT}, "{1}{W}{W}", "Dizzying Swoop", "{1}{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Dizzying Swoop
+ // Tap up to two target creatures.
+ this.getSpellCard().getSpellAbility().addEffect(new TapTargetEffect());
+ this.getSpellCard().getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2));
+ }
+
+ private ArdenvaleTactician(final ArdenvaleTactician card) {
+ super(card);
+ }
+
+ @Override
+ public ArdenvaleTactician copy() {
+ return new ArdenvaleTactician(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/Arena.java b/Mage.Sets/src/mage/cards/a/Arena.java
index 8ecb5ab263c..4e5cf769f93 100644
--- a/Mage.Sets/src/mage/cards/a/Arena.java
+++ b/Mage.Sets/src/mage/cards/a/Arena.java
@@ -28,7 +28,7 @@ public final class Arena extends CardImpl {
public Arena(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
- // {3}, {tap}: Tap target creature you control and target creature of an opponent's choice he or she controls. Those creatures fight each other.
+ // {3}, {tap}: Tap target creature you control and target creature of an opponent's choice they control. Those creatures fight each other.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ArenaEffect(), new GenericManaCost(3));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetControlledCreaturePermanent());
@@ -50,7 +50,7 @@ class ArenaEffect extends OneShotEffect {
ArenaEffect() {
super(Outcome.Benefit);
- this.staticText = "Tap target creature you control and target creature of an opponent's choice he or she controls. Those creatures fight each other.";
+ this.staticText = "Tap target creature you control and target creature of an opponent's choice they control. Those creatures fight each other.";
}
ArenaEffect(final ArenaEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/a/AshiokNightmareMuse.java b/Mage.Sets/src/mage/cards/a/AshiokNightmareMuse.java
new file mode 100644
index 00000000000..71dbffd254d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AshiokNightmareMuse.java
@@ -0,0 +1,145 @@
+package mage.cards.a;
+
+import mage.abilities.Ability;
+import mage.abilities.LoyaltyAbility;
+import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterCard;
+import mage.filter.predicate.other.OwnerPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.token.AshiokNightmareMuseToken;
+import mage.players.Player;
+import mage.target.common.TargetCardInExile;
+import mage.target.common.TargetCardInHand;
+import mage.target.common.TargetNonlandPermanent;
+
+import java.util.UUID;
+import mage.MageObject;
+import mage.MageObjectReference;
+import mage.cards.Card;
+
+/**
+ * @author TheElk801
+ */
+public final class AshiokNightmareMuse extends CardImpl {
+
+ public AshiokNightmareMuse(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{3}{U}{B}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.ASHIOK);
+ this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+
+ // +1: Create a 2/3 blue and black Nightmare creature token with "Whenever this creature attacks or blocks, each opponent exiles the top two cards of their library."
+ this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new AshiokNightmareMuseToken()), 1));
+
+ // −3: Return target nonland permanent to its owner's hand, then that player exiles a card from their hand.
+ Ability ability = new LoyaltyAbility(new AshiokNightmareMuseBounceEffect(), -3);
+ ability.addTarget(new TargetNonlandPermanent());
+ this.addAbility(ability);
+
+ // −7: You may cast up to three face-up cards your opponents own from exile without paying their mana costs.
+ this.addAbility(new LoyaltyAbility(new AshiokNightmareMuseCastEffect(), -7));
+ }
+
+ private AshiokNightmareMuse(final AshiokNightmareMuse card) {
+ super(card);
+ }
+
+ @Override
+ public AshiokNightmareMuse copy() {
+ return new AshiokNightmareMuse(this);
+ }
+}
+
+class AshiokNightmareMuseBounceEffect extends OneShotEffect {
+
+ AshiokNightmareMuseBounceEffect() {
+ super(Outcome.Discard);
+ staticText = "return target nonland permanent to its owner's hand, "
+ + "then that player exiles a card from their hand";
+ }
+
+ private AshiokNightmareMuseBounceEffect(final AshiokNightmareMuseBounceEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public AshiokNightmareMuseBounceEffect copy() {
+ return new AshiokNightmareMuseBounceEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = game.getPermanent(source.getFirstTarget());
+ Player player = game.getPlayer(game.getOwnerId(source.getFirstTarget()));
+ if (permanent == null || player == null) {
+ return false;
+ }
+ player.moveCards(permanent, Zone.HAND, source, game);
+ if (player.getHand().isEmpty()) {
+ return true;
+ }
+ TargetCardInHand target = new TargetCardInHand();
+ if (!player.choose(outcome, player.getHand(), target, game)) {
+ return false;
+ }
+ return player.moveCards(game.getCard(target.getFirstTarget()), Zone.EXILED, source, game);
+ }
+}
+
+class AshiokNightmareMuseCastEffect extends OneShotEffect {
+
+ private static final FilterCard filter = new FilterCard("face-up cards your opponents own from exile");
+
+ static {
+ filter.add(new OwnerPredicate(TargetController.OPPONENT));
+ }
+
+ AshiokNightmareMuseCastEffect() {
+ super(Outcome.Discard);
+ staticText = "You may cast up to three face-up cards your opponents own from exile without paying their mana costs.";
+ }
+
+ private AshiokNightmareMuseCastEffect(final AshiokNightmareMuseCastEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public AshiokNightmareMuseCastEffect copy() {
+ return new AshiokNightmareMuseCastEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) {
+ return false;
+ }
+ TargetCardInExile target = new TargetCardInExile(0, 3, filter, null);
+ target.setNotTarget(true);
+ if (!controller.chooseTarget(outcome, target, source, game)) { // method is fine, controller is still choosing the card
+ return false;
+ }
+ for (UUID targetId : target.getTargets()) {
+ if (targetId != null) {
+ Card chosenCard = game.getCard(targetId);
+ if (chosenCard != null
+ && game.getState().getZone(chosenCard.getId()) == Zone.EXILED // must be exiled
+ && game.getOpponents(controller.getId()).contains(chosenCard.getOwnerId()) // must be owned by an opponent
+ && controller.chooseUse(outcome, "Cast " + chosenCard.getName() + " without paying its mana cost?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + chosenCard.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(chosenCard, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + chosenCard.getId(), null);
+ }
+ }
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AshiokSculptorOfFears.java b/Mage.Sets/src/mage/cards/a/AshiokSculptorOfFears.java
new file mode 100644
index 00000000000..16e900a3601
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AshiokSculptorOfFears.java
@@ -0,0 +1,91 @@
+package mage.cards.a;
+
+import mage.abilities.Ability;
+import mage.abilities.LoyaltyAbility;
+import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveEachPlayerEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
+import mage.abilities.effects.common.continuous.GainControlAllEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterCard;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreatureCard;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.permanent.ControllerIdPredicate;
+import mage.game.Game;
+import mage.target.common.TargetCardInGraveyard;
+import mage.target.common.TargetOpponent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AshiokSculptorOfFears extends CardImpl {
+
+ private static final FilterCard filter = new FilterCreatureCard("creature card from a graveyard");
+
+ public AshiokSculptorOfFears(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{U}{B}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.ASHIOK);
+ this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
+
+ // +2: Draw a card. Each player puts the top two cards of their library into their graveyard.
+ Ability ability = new LoyaltyAbility(
+ new DrawCardSourceControllerEffect(1).setText("draw a card."), 2
+ );
+ ability.addEffect(new PutTopCardOfLibraryIntoGraveEachPlayerEffect(2, TargetController.ANY));
+ this.addAbility(ability);
+
+ // −5: Put target creature card from a graveyard onto the battlefield under you control.
+ ability = new LoyaltyAbility(new ReturnFromGraveyardToBattlefieldTargetEffect()
+ .setText("put target creature card from a graveyard onto the battlefield under you control"), -5);
+ ability.addTarget(new TargetCardInGraveyard(filter));
+ this.addAbility(ability);
+
+ // −11: Gain control of all creatures target opponent controls.
+ ability = new LoyaltyAbility(new AshiokSculptorOfFearsEffect(), -11);
+ ability.addTarget(new TargetOpponent());
+ this.addAbility(ability);
+ }
+
+ private AshiokSculptorOfFears(final AshiokSculptorOfFears card) {
+ super(card);
+ }
+
+ @Override
+ public AshiokSculptorOfFears copy() {
+ return new AshiokSculptorOfFears(this);
+ }
+}
+
+class AshiokSculptorOfFearsEffect extends OneShotEffect {
+
+ AshiokSculptorOfFearsEffect() {
+ super(Outcome.Benefit);
+ staticText = "gain control of all creatures target opponent controls";
+ }
+
+ private AshiokSculptorOfFearsEffect(final AshiokSculptorOfFearsEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public AshiokSculptorOfFearsEffect copy() {
+ return new AshiokSculptorOfFearsEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ FilterPermanent filter = new FilterCreaturePermanent();
+ filter.add(new ControllerIdPredicate(source.getFirstTarget()));
+ game.addEffect(new GainControlAllEffect(Duration.Custom, filter), source);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/a/AshlingTheExtinguisher.java b/Mage.Sets/src/mage/cards/a/AshlingTheExtinguisher.java
index 70eb75951fa..ad83866f6e0 100644
--- a/Mage.Sets/src/mage/cards/a/AshlingTheExtinguisher.java
+++ b/Mage.Sets/src/mage/cards/a/AshlingTheExtinguisher.java
@@ -31,7 +31,7 @@ public final class AshlingTheExtinguisher extends CardImpl {
this.subtype.add(SubType.ELEMENTAL);
this.subtype.add(SubType.SHAMAN);
- // Whenever Ashling, the Extinguisher deals combat damage to a player, choose target creature that player controls. He or she sacrifices that creature.
+ // Whenever Ashling, the Extinguisher deals combat damage to a player, choose target creature that player controls. they sacrifice that creature.
this.power = new MageInt(4);
this.toughness = new MageInt(4);
this.addAbility(new AshlingTheExtinguisherTriggeredAbility());
diff --git a/Mage.Sets/src/mage/cards/a/AspectOfHydra.java b/Mage.Sets/src/mage/cards/a/AspectOfHydra.java
index a940843666d..32af5769fcf 100644
--- a/Mage.Sets/src/mage/cards/a/AspectOfHydra.java
+++ b/Mage.Sets/src/mage/cards/a/AspectOfHydra.java
@@ -1,37 +1,33 @@
-
package mage.cards.a;
-import java.util.UUID;
-import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.DevotionCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.ColoredManaSymbol;
import mage.constants.Duration;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class AspectOfHydra extends CardImpl {
public AspectOfHydra(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{G}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}");
// Target creature gets +X/+X until end of turn, where X is your devotion to green.
- DynamicValue greenDevotion = new DevotionCount(ColoredManaSymbol.G);
- Effect effect = new BoostTargetEffect(greenDevotion, greenDevotion, Duration.EndOfTurn, true);
+ Effect effect = new BoostTargetEffect(DevotionCount.G, DevotionCount.G, Duration.EndOfTurn, true);
effect.setText("Target creature gets +X/+X until end of turn, where X is your devotion to green");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
+ this.getSpellAbility().addHint(DevotionCount.G.getHint());
}
- public AspectOfHydra(final AspectOfHydra card) {
+ private AspectOfHydra(final AspectOfHydra card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/a/AthreosGodOfPassage.java b/Mage.Sets/src/mage/cards/a/AthreosGodOfPassage.java
index 8bdca274c75..94e9d1d7831 100644
--- a/Mage.Sets/src/mage/cards/a/AthreosGodOfPassage.java
+++ b/Mage.Sets/src/mage/cards/a/AthreosGodOfPassage.java
@@ -1,7 +1,5 @@
-
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
@@ -27,8 +25,9 @@ import mage.game.events.ZoneChangeEvent;
import mage.players.Player;
import mage.target.common.TargetOpponent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class AthreosGodOfPassage extends CardImpl {
@@ -50,10 +49,11 @@ public final class AthreosGodOfPassage extends CardImpl {
// Indestructible
this.addAbility(IndestructibleAbility.getInstance());
+
// As long as your devotion to white and black is less than seven, Athreos isn't a creature.
- Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.W, ColoredManaSymbol.B), 7);
- effect.setText("As long as your devotion to white and black is less than seven, Athreos isn't a creature");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.WB, 7))
+ .addHint(DevotionCount.WB.getHint()));
+
// Whenever another creature you own dies, return it to your hand unless target opponent pays 3 life.
Ability ability = new AthreosDiesCreatureTriggeredAbility(new AthreosGodOfPassageReturnEffect(), false, filter);
ability.addTarget(new TargetOpponent());
@@ -61,7 +61,7 @@ public final class AthreosGodOfPassage extends CardImpl {
}
- public AthreosGodOfPassage(final AthreosGodOfPassage card) {
+ private AthreosGodOfPassage(final AthreosGodOfPassage card) {
super(card);
}
@@ -73,12 +73,12 @@ public final class AthreosGodOfPassage extends CardImpl {
class AthreosGodOfPassageReturnEffect extends OneShotEffect {
- public AthreosGodOfPassageReturnEffect() {
+ AthreosGodOfPassageReturnEffect() {
super(Outcome.Benefit);
this.staticText = "return it to your hand unless target opponent pays 3 life";
}
- public AthreosGodOfPassageReturnEffect(final AthreosGodOfPassageReturnEffect effect) {
+ private AthreosGodOfPassageReturnEffect(final AthreosGodOfPassageReturnEffect effect) {
super(effect);
}
@@ -90,30 +90,29 @@ class AthreosGodOfPassageReturnEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- UUID creatureId = (UUID) this.getValue("creatureId");
- Card creature = game.getCard(creatureId);
- if (creature != null) {
- Player opponent = game.getPlayer(source.getFirstTarget());
- boolean paid = false;
- if (opponent != null) {
- Cost cost = new PayLifeCost(3);
- if (cost.canPay(source, source.getSourceId(), opponent.getId(), game)
- && opponent.chooseUse(outcome, "Pay 3 life to prevent that " + creature.getLogName() + " returns to " + controller.getLogName() + "'s hand?", source, game)) {
- if (cost.pay(source, game, source.getSourceId(), opponent.getId(), false, null)) {
- paid = true;
- }
- }
- }
- if (opponent == null || !paid) {
- if (game.getState().getZone(creature.getId()) == Zone.GRAVEYARD) {
- controller.moveCards(creature, Zone.HAND, source, game);
- }
- }
- }
+ if (controller == null) {
+ return false;
+ }
+ UUID creatureId = (UUID) this.getValue("creatureId");
+ Card creature = game.getCard(creatureId);
+ if (creature == null) {
return true;
}
- return false;
+ Player opponent = game.getPlayer(source.getFirstTarget());
+ boolean paid = false;
+ if (opponent != null) {
+ Cost cost = new PayLifeCost(3);
+ if (cost.canPay(source, source.getSourceId(), opponent.getId(), game)
+ && opponent.chooseUse(outcome, "Pay 3 life to prevent that " + creature.getLogName() + " returns to " + controller.getLogName() + "'s hand?", source, game)
+ && cost.pay(source, game, source.getSourceId(), opponent.getId(), false, null)) {
+ paid = true;
+ }
+ }
+ if ((opponent != null && paid) || game.getState().getZone(creature.getId()) != Zone.GRAVEYARD) {
+ return true;
+ }
+ controller.moveCards(creature, Zone.HAND, source, game);
+ return true;
}
}
@@ -121,12 +120,12 @@ class AthreosDiesCreatureTriggeredAbility extends TriggeredAbilityImpl {
protected FilterCreaturePermanent filter;
- public AthreosDiesCreatureTriggeredAbility(Effect effect, boolean optional, FilterCreaturePermanent filter) {
+ AthreosDiesCreatureTriggeredAbility(Effect effect, boolean optional, FilterCreaturePermanent filter) {
super(Zone.BATTLEFIELD, effect, optional);
this.filter = filter;
}
- public AthreosDiesCreatureTriggeredAbility(AthreosDiesCreatureTriggeredAbility ability) {
+ private AthreosDiesCreatureTriggeredAbility(AthreosDiesCreatureTriggeredAbility ability) {
super(ability);
this.filter = ability.filter;
}
@@ -144,15 +143,16 @@ class AthreosDiesCreatureTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
- if (zEvent.isDiesEvent()) {
- if (zEvent.getTarget() != null && filter.match(zEvent.getTarget(), sourceId, controllerId, game)) {
- for (Effect effect : this.getEffects()) {
- effect.setValue("creatureId", event.getTargetId());
- }
- return true;
- }
+ if (!zEvent.isDiesEvent()) {
+ return false;
}
- return false;
+ if (zEvent.getTarget() == null || !filter.match(zEvent.getTarget(), sourceId, controllerId, game)) {
+ return false;
+ }
+ for (Effect effect : this.getEffects()) {
+ effect.setValue("creatureId", event.getTargetId());
+ }
+ return true;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/AthreosShroudVeiled.java b/Mage.Sets/src/mage/cards/a/AthreosShroudVeiled.java
new file mode 100644
index 00000000000..9e57afad23e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AthreosShroudVeiled.java
@@ -0,0 +1,155 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.MageObjectReference;
+import mage.abilities.Ability;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.common.DevotionCount;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.abilities.keyword.IndestructibleAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.counters.CounterType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.events.ZoneChangeEvent;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AthreosShroudVeiled extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterCreaturePermanent("another target creature");
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ }
+
+ public AthreosShroudVeiled(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{4}{W}{B}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.GOD);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(7);
+
+ // Indestructible
+ this.addAbility(IndestructibleAbility.getInstance());
+
+ // As long as your devotion to white and black is less than seven, Athreos isn't a creature.
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.WB, 7))
+ .addHint(DevotionCount.WB.getHint()));
+
+ // At the beginning of your end step, put a coin counter on another target creature.
+ Ability ability = new BeginningOfEndStepTriggeredAbility(
+ new AddCountersTargetEffect(CounterType.COIN.createInstance()),
+ TargetController.YOU, false
+ );
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(ability);
+
+ // Whenever a creature with a coin counter on it dies or is put into exile, return that card to the battlefield under your control.
+ this.addAbility(new AthreosShroudVeiledTriggeredAbility());
+ }
+
+ private AthreosShroudVeiled(final AthreosShroudVeiled card) {
+ super(card);
+ }
+
+ @Override
+ public AthreosShroudVeiled copy() {
+ return new AthreosShroudVeiled(this);
+ }
+}
+
+class AthreosShroudVeiledTriggeredAbility extends TriggeredAbilityImpl {
+
+ AthreosShroudVeiledTriggeredAbility() {
+ super(Zone.BATTLEFIELD, null, false);
+ }
+
+ private AthreosShroudVeiledTriggeredAbility(final AthreosShroudVeiledTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ if (event.getType() != GameEvent.EventType.ZONE_CHANGE) {
+ return false;
+ }
+ ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
+ return zEvent.getFromZone() == Zone.BATTLEFIELD
+ && (zEvent.getToZone() == Zone.GRAVEYARD
+ || zEvent.getToZone() == Zone.EXILED);
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
+ Permanent permanent = zEvent.getTarget();
+ if (permanent == null
+ || !permanent.isCreature()
+ || !permanent.getCounters(game).containsKey(CounterType.COIN)) {
+ return false;
+ }
+ this.getEffects().clear();
+ this.addEffect(new AthreosShroudVeiledEffect(new MageObjectReference(zEvent.getTarget(), game)));
+ return true;
+ }
+
+ @Override
+ public AthreosShroudVeiledTriggeredAbility copy() {
+ return new AthreosShroudVeiledTriggeredAbility(this);
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever a creature with a coin counter on it dies or is put into exile, " +
+ "return that card to the battlefield under your control.";
+ }
+}
+
+class AthreosShroudVeiledEffect extends OneShotEffect {
+
+ private final MageObjectReference mor;
+
+ AthreosShroudVeiledEffect(MageObjectReference mor) {
+ super(Outcome.Benefit);
+ this.mor = mor;
+ }
+
+ private AthreosShroudVeiledEffect(final AthreosShroudVeiledEffect effect) {
+ super(effect);
+ this.mor = effect.mor;
+ }
+
+ @Override
+ public AthreosShroudVeiledEffect copy() {
+ return new AthreosShroudVeiledEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ Card card = game.getCard(mor.getSourceId());
+ return card.getZoneChangeCounter(game) - 1 == mor.getZoneChangeCounter()
+ && player.moveCards(card, Zone.BATTLEFIELD, source, game);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AureliasFury.java b/Mage.Sets/src/mage/cards/a/AureliasFury.java
index 634de83e29e..859e15973c9 100644
--- a/Mage.Sets/src/mage/cards/a/AureliasFury.java
+++ b/Mage.Sets/src/mage/cards/a/AureliasFury.java
@@ -38,10 +38,10 @@ import java.util.UUID;
*
* Aurelia's Fury can't deal damage to both a planeswalker and that
* planeswalker's controller. If damage dealt by Aurelia's Fury is redirected
- * from a player to a planeswalker he or she controls, that player will be able
+ * from a player to a planeswalker they control, that player will be able
* to cast noncreature spells that turn. If you want to stop a player from
* casting noncreature spells this turn, you can't choose to redirect the
- * damage to a planeswalker he or she controls.
+ * damage to a planeswalker they control.
*
* If Aurelia's Fury has multiple targets, and some but not all of them are
* illegal targets when Aurelia's Fury resolves, Aurelia's Fury will still
diff --git a/Mage.Sets/src/mage/cards/a/AuriokReplica.java b/Mage.Sets/src/mage/cards/a/AuriokReplica.java
index fec795b60aa..e8c4105c651 100644
--- a/Mage.Sets/src/mage/cards/a/AuriokReplica.java
+++ b/Mage.Sets/src/mage/cards/a/AuriokReplica.java
@@ -1,8 +1,5 @@
-
-
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -16,17 +13,20 @@ import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.target.TargetSource;
+import java.util.UUID;
+
/**
- *
* @author BetaSteward_at_googlemail.com
*/
public final class AuriokReplica extends CardImpl {
public AuriokReplica(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{3}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}");
this.subtype.add(SubType.CLERIC);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
@@ -77,7 +77,7 @@ class AuriokReplicaEffect extends PreventionEffectImpl {
}
private void preventDamage(GameEvent event, Ability source, UUID target, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, target, source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(target, source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
event.setAmount(0);
@@ -88,9 +88,7 @@ class AuriokReplicaEffect extends PreventionEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
- if (event.getTargetId().equals(source.getControllerId()) && event.getSourceId().equals(this.getTargetPointer().getFirst(game, source))) {
- return true;
- }
+ return event.getTargetId().equals(source.getControllerId()) && event.getSourceId().equals(this.getTargetPointer().getFirst(game, source));
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/a/AurraSingBaneOfJedi.java b/Mage.Sets/src/mage/cards/a/AurraSingBaneOfJedi.java
index 074f1e164db..f2191c503bd 100644
--- a/Mage.Sets/src/mage/cards/a/AurraSingBaneOfJedi.java
+++ b/Mage.Sets/src/mage/cards/a/AurraSingBaneOfJedi.java
@@ -50,7 +50,7 @@ public final class AurraSingBaneOfJedi extends CardImpl {
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
- // -6: Each player discards their hand and sacrificies all creatures he or she controls. Each player's life total becomes 1."
+ // -6: Each player discards their hand and sacrificies all creatures they control. Each player's life total becomes 1."
ability = new LoyaltyAbility(new DiscardHandAllEffect(), -6);
ability.addEffect(new SacrificeAllEffect());
Effect effect = new SetPlayerLifeAllEffect(1, TargetController.ANY);
@@ -103,7 +103,7 @@ class SacrificeAllEffect extends OneShotEffect {
SacrificeAllEffect() {
super(Outcome.DestroyPermanent);
- staticText = "and sacrificies all creatures he or she controls";
+ staticText = "and sacrificies all creatures they control";
}
SacrificeAllEffect(final SacrificeAllEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/a/AvacynsCollar.java b/Mage.Sets/src/mage/cards/a/AvacynsCollar.java
index 027984cfb05..007439cbc27 100644
--- a/Mage.Sets/src/mage/cards/a/AvacynsCollar.java
+++ b/Mage.Sets/src/mage/cards/a/AvacynsCollar.java
@@ -1,6 +1,7 @@
package mage.cards.a;
+import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.GenericManaCost;
@@ -32,10 +33,15 @@ public final class AvacynsCollar extends CardImpl {
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +1/+0 and has vigilance.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 0)));
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.EQUIPMENT)));
+ Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(1, 0));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ VigilanceAbility.getInstance(), AttachmentType.EQUIPMENT).setText("and has vigilance")
+ );
+ this.addAbility(ability);
+
// Whenever equipped creature dies, if it was a Human, create a 1/1 white Spirit creature token with flying.
this.addAbility(new AvacynsCollarTriggeredAbility());
+
// Equip {2}
this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(2)));
}
diff --git a/Mage.Sets/src/mage/cards/a/AvatarOfFury.java b/Mage.Sets/src/mage/cards/a/AvatarOfFury.java
index eed329a4e25..9153c0a4f99 100644
--- a/Mage.Sets/src/mage/cards/a/AvatarOfFury.java
+++ b/Mage.Sets/src/mage/cards/a/AvatarOfFury.java
@@ -1,4 +1,3 @@
-
package mage.cards.a;
import java.util.UUID;
@@ -7,18 +6,19 @@ import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.costs.AdjustingSourceCosts;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
+import mage.constants.CostModificationType;
import mage.constants.Duration;
+import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.FilterPermanent;
-import mage.filter.common.FilterLandPermanent;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.util.CardUtil;
@@ -36,7 +36,7 @@ public final class AvatarOfFury extends CardImpl {
this.toughness = new MageInt(6);
// If an opponent controls seven or more lands, Avatar of Fury costs {6} less to cast.
- this.addAbility(new AvatarOfFuryAdjustingCostsAbility());
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new AvatarOfFuryAdjustingCostsEffect()));
// Flying
this.addAbility(FlyingAbility.getInstance());
// {R}: Avatar of Fury gets +1/+0 until end of turn.
@@ -53,36 +53,39 @@ public final class AvatarOfFury extends CardImpl {
}
}
-class AvatarOfFuryAdjustingCostsAbility extends SimpleStaticAbility implements AdjustingSourceCosts {
+class AvatarOfFuryAdjustingCostsEffect extends CostModificationEffectImpl {
- public AvatarOfFuryAdjustingCostsAbility() {
- super(Zone.OUTSIDE, null /*new AvatarOfFuryAdjustingCostsEffect()*/);
+ AvatarOfFuryAdjustingCostsEffect() {
+ super(Duration.EndOfGame, Outcome.Benefit, CostModificationType.REDUCE_COST);
+ staticText = "If an opponent controls seven or more lands, {this} costs {6} less to cast";
}
- public AvatarOfFuryAdjustingCostsAbility(final AvatarOfFuryAdjustingCostsAbility ability) {
- super(ability);
+ AvatarOfFuryAdjustingCostsEffect(AvatarOfFuryAdjustingCostsEffect effect) {
+ super(effect);
}
@Override
- public SimpleStaticAbility copy() {
- return new AvatarOfFuryAdjustingCostsAbility(this);
+ public boolean apply(Game game, Ability source, Ability abilityToModify) {
+ CardUtil.reduceCost(abilityToModify, 6);
+ return true;
}
@Override
- public String getRule() {
- return "If an opponent controls seven or more lands, Avatar of Fury costs {6} less to cast";
- }
-
- @Override
- public void adjustCosts(Ability ability, Game game) {
- if (ability instanceof SpellAbility) { // Prevent adjustment of activated ability
- FilterPermanent filter = new FilterLandPermanent();
- for (UUID playerId : game.getOpponents(ability.getControllerId())) {
- if (game.getBattlefield().countAll(filter, playerId, game) > 6) {
- CardUtil.adjustCost((SpellAbility) ability, 6);
- break;
+ public boolean applies(Ability abilityToModify, Ability source, Game game) {
+ if (abilityToModify.getSourceId().equals(source.getSourceId())
+ && (abilityToModify instanceof SpellAbility)) {
+ for (UUID playerId : game.getOpponents(abilityToModify.getControllerId())) {
+ if (game.getBattlefield().countAll(StaticFilters.FILTER_LAND, playerId, game) > 6) {
+ return true;
}
}
}
+ return false;
}
-}
\ No newline at end of file
+
+ @Override
+ public AvatarOfFuryAdjustingCostsEffect copy() {
+ return new AvatarOfFuryAdjustingCostsEffect(this);
+ }
+
+}
diff --git a/Mage.Sets/src/mage/cards/a/AvatarOfHope.java b/Mage.Sets/src/mage/cards/a/AvatarOfHope.java
index 5f542b155e0..d1e82950fe5 100644
--- a/Mage.Sets/src/mage/cards/a/AvatarOfHope.java
+++ b/Mage.Sets/src/mage/cards/a/AvatarOfHope.java
@@ -1,13 +1,10 @@
-
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
-import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.costs.AdjustingSourceCosts;
import mage.abilities.effects.common.combat.CanBlockAdditionalCreatureEffect;
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.abilities.keyword.FlyingAbility;
@@ -32,7 +29,7 @@ public final class AvatarOfHope extends CardImpl {
this.toughness = new MageInt(9);
// If you have 3 or less life, Avatar of Hope costs {6} less to cast.
- this.addAbility(new AdjustingCostsAbility());
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new AvatarOfHopeAdjustingCostsEffect()));
// Flying
this.addAbility(FlyingAbility.getInstance());
// Avatar of Hope can block any number of creatures.
@@ -49,76 +46,39 @@ public final class AvatarOfHope extends CardImpl {
}
}
-class AdjustingCostsAbility extends SimpleStaticAbility implements AdjustingSourceCosts {
+class AvatarOfHopeAdjustingCostsEffect extends CostModificationEffectImpl {
- public AdjustingCostsAbility() {
- super(Zone.OUTSIDE, new AdjustingCostsEffect());
+ AvatarOfHopeAdjustingCostsEffect() {
+ super(Duration.EndOfGame, Outcome.Benefit, CostModificationType.REDUCE_COST);
+ staticText = "If you have 3 or less life, {this} costs {6} less to cast";
}
- public AdjustingCostsAbility(final AdjustingCostsAbility ability) {
- super(ability);
- }
-
- @Override
- public SimpleStaticAbility copy() {
- return new AdjustingCostsAbility(this);
- }
-
- @Override
- public String getRule() {
- return "If you have 3 or less life, {this} costs {6} less to cast";
- }
-
- @Override
- public void adjustCosts(Ability ability, Game game) {
- if (ability.getAbilityType() == AbilityType.SPELL) {
- Player player = game.getPlayer(ability.getControllerId());
- if (player != null && player.getLife() < 4) {
- CardUtil.adjustCost((SpellAbility) ability, 6);
- }
- }
- }
-}
-
-class AdjustingCostsEffect extends CostModificationEffectImpl {
-
- public AdjustingCostsEffect() {
- super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST);
- }
-
- public AdjustingCostsEffect(final AdjustingCostsEffect effect) {
+ AvatarOfHopeAdjustingCostsEffect(AvatarOfHopeAdjustingCostsEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
- SpellAbility spellAbility = (SpellAbility) abilityToModify;
- Mana mana = spellAbility.getManaCostsToPay().getMana();
- Player player = game.getPlayer(source.getControllerId());
-
- if (mana.getGeneric() > 0 && player != null && player.getLife() < 4) {
- int newCount = mana.getGeneric() - 6;
- if (newCount < 0) {
- newCount = 0;
- }
- mana.setGeneric(newCount);
- spellAbility.getManaCostsToPay().load(mana.toString());
- return true;
- }
- return false;
+ CardUtil.reduceCost(abilityToModify, 6);
+ return true;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
- if ((abilityToModify instanceof SpellAbility)
- && abilityToModify.getSourceId().equals(source.getSourceId())) {
- return true;
+ if (abilityToModify.getSourceId().equals(source.getSourceId())
+ && (abilityToModify instanceof SpellAbility)) {
+ Player player = game.getPlayer(abilityToModify.getControllerId());
+ if (player != null && player.getLife() < 4) {
+ return true;
+ }
}
+
return false;
}
@Override
- public AdjustingCostsEffect copy() {
- return new AdjustingCostsEffect(this);
+ public AvatarOfHopeAdjustingCostsEffect copy() {
+ return new AvatarOfHopeAdjustingCostsEffect(this);
}
+
}
diff --git a/Mage.Sets/src/mage/cards/a/AvatarOfWoe.java b/Mage.Sets/src/mage/cards/a/AvatarOfWoe.java
index b3e5e9516cf..a8f9ca18931 100644
--- a/Mage.Sets/src/mage/cards/a/AvatarOfWoe.java
+++ b/Mage.Sets/src/mage/cards/a/AvatarOfWoe.java
@@ -1,4 +1,3 @@
-
package mage.cards.a;
import java.util.UUID;
@@ -16,7 +15,7 @@ import mage.abilities.keyword.FearAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.target.common.TargetCreaturePermanent;
@@ -27,17 +26,17 @@ import mage.target.common.TargetCreaturePermanent;
public final class AvatarOfWoe extends CardImpl {
public AvatarOfWoe(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{6}{B}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{B}{B}");
this.subtype.add(SubType.AVATAR);
this.power = new MageInt(6);
this.toughness = new MageInt(5);
// If there are ten or more creature cards total in all graveyards, Avatar of Woe costs {6} less to cast.
this.addAbility(new SimpleStaticAbility(Zone.STACK, new AvatarOfWoeCostReductionEffect()));
-
+
// Fear
this.addAbility(FearAbility.getInstance());
-
+
// {tap}: Destroy target creature. It can't be regenerated.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(true), new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
@@ -83,9 +82,9 @@ class AvatarOfWoeCostReductionEffect extends CostModificationEffectImpl {
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
- return abilityToModify.getSourceId().equals(source.getSourceId())
- && (abilityToModify instanceof SpellAbility)
- && new CardsInAllGraveyardsCount(new FilterCreatureCard()).calculate(game, source, this) >= 10;
+ return abilityToModify.getSourceId().equals(source.getSourceId())
+ && (abilityToModify instanceof SpellAbility)
+ && new CardsInAllGraveyardsCount(StaticFilters.FILTER_CARD_CREATURE).calculate(game, source, this) >= 10;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/AwesomePresence.java b/Mage.Sets/src/mage/cards/a/AwesomePresence.java
index 604d293a3c0..2d45ef5aeda 100644
--- a/Mage.Sets/src/mage/cards/a/AwesomePresence.java
+++ b/Mage.Sets/src/mage/cards/a/AwesomePresence.java
@@ -1,29 +1,28 @@
package mage.cards.a;
-import java.util.UUID;
-import mage.constants.SubType;
-import mage.target.common.TargetCreaturePermanent;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.PayCostToAttackBlockEffectImpl;
-import mage.abilities.effects.PayCostToAttackBlockEffectImpl.RestrictType;
import mage.abilities.effects.common.AttachEffect;
-import mage.constants.Outcome;
-import mage.target.TargetPermanent;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
/**
- *
* @author jeffwadsworth
*/
public final class AwesomePresence extends CardImpl {
@@ -40,7 +39,7 @@ public final class AwesomePresence extends CardImpl {
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
- // Enchanted creature can't be blocked unless defending player pays {3} for each creature he or she controls that's blocking it.
+ // Enchanted creature can't be blocked unless defending player pays {3} for each creature they control that's blocking it.
this.addAbility(new SimpleStaticAbility(new AwesomePresenceRestrictionEffect(new ManaCostsImpl("{3}"))));
}
@@ -63,7 +62,7 @@ class AwesomePresenceRestrictionEffect extends PayCostToAttackBlockEffectImpl {
+ " can't be blocked "
+ "unless defending player pays "
+ (manaCosts == null ? "" : manaCosts.getText()
- + " for each creature he or she controls that's blocking it");
+ + " for each creature they control that's blocking it");
}
public AwesomePresenceRestrictionEffect(AwesomePresenceRestrictionEffect effect) {
@@ -77,13 +76,12 @@ class AwesomePresenceRestrictionEffect extends PayCostToAttackBlockEffectImpl {
Permanent enchantment = game.getPermanent(source.getSourceId());
if (blockingCreature != null
&& enchantedAttackingCreature != null
+ && enchantment != null
&& enchantment.isAttachedTo(enchantedAttackingCreature.getId())) {
Player defendingPlayer = game.getPlayer(blockingCreature.getControllerId());
if (defendingPlayer != null) {
- if (manaCosts.canPay(source, source.getSourceId(), defendingPlayer.getId(), game)
- && manaCosts.pay(source, game, source.getSourceId(), defendingPlayer.getId(), false)) {
- return false;
- }
+ return !manaCosts.canPay(source, source.getSourceId(), defendingPlayer.getId(), game)
+ || !manaCosts.pay(source, game, source.getSourceId(), defendingPlayer.getId(), false);
}
}
return true;
diff --git a/Mage.Sets/src/mage/cards/a/AyaraFirstOfLocthwain.java b/Mage.Sets/src/mage/cards/a/AyaraFirstOfLocthwain.java
new file mode 100644
index 00000000000..15d2e1a9f47
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/AyaraFirstOfLocthwain.java
@@ -0,0 +1,70 @@
+package mage.cards.a;
+
+import mage.MageInt;
+import mage.ObjectColor;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.effects.common.LoseLifeOpponentsEffect;
+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.FilterControlledCreaturePermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.ColorPredicate;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class AyaraFirstOfLocthwain extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterCreaturePermanent("{this} or another black creature");
+ private static final FilterControlledPermanent filter2
+ = new FilterControlledCreaturePermanent("another black creature");
+
+ static {
+ filter.add(new ColorPredicate(ObjectColor.BLACK));
+ filter2.add(new ColorPredicate(ObjectColor.BLACK));
+ }
+
+ public AyaraFirstOfLocthwain(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{B}{B}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.ELF);
+ this.subtype.add(SubType.NOBLE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // Whenever Ayara, First of Locthwain or another black creature enters the battlefield under your control, each opponent loses 1 life and you gain 1 life.
+ Ability ability = new EntersBattlefieldControlledTriggeredAbility(new LoseLifeOpponentsEffect(1), filter);
+ ability.addEffect(new GainLifeEffect(1).concatBy("and"));
+ this.addAbility(ability);
+
+ // {T}, Sacrifice another black creature: Draw a card.
+ ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new TapSourceCost());
+ ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2)));
+ this.addAbility(ability);
+ }
+
+ private AyaraFirstOfLocthwain(final AyaraFirstOfLocthwain card) {
+ super(card);
+ }
+
+ @Override
+ public AyaraFirstOfLocthwain copy() {
+ return new AyaraFirstOfLocthwain(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AzoriusAEthermage.java b/Mage.Sets/src/mage/cards/a/AzoriusAethermage.java
similarity index 92%
rename from Mage.Sets/src/mage/cards/a/AzoriusAEthermage.java
rename to Mage.Sets/src/mage/cards/a/AzoriusAethermage.java
index 851c91793a6..16aed74a471 100644
--- a/Mage.Sets/src/mage/cards/a/AzoriusAEthermage.java
+++ b/Mage.Sets/src/mage/cards/a/AzoriusAethermage.java
@@ -23,11 +23,11 @@ import mage.game.permanent.Permanent;
*
* @author jeffwadsworth
*/
-public final class AzoriusAEthermage extends CardImpl {
+public final class AzoriusAethermage extends CardImpl {
private static final String rule = "Whenever a permanent is returned to your hand, ";
- public AzoriusAEthermage(UUID ownerId, CardSetInfo setInfo) {
+ public AzoriusAethermage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}");
this.subtype.add(SubType.HUMAN);
@@ -40,13 +40,13 @@ public final class AzoriusAEthermage extends CardImpl {
this.addAbility(new AzoriusAEthermageAbility(Zone.BATTLEFIELD, Zone.BATTLEFIELD, Zone.HAND, effect, new FilterPermanent(), rule, true));
}
- public AzoriusAEthermage(final AzoriusAEthermage card) {
+ public AzoriusAethermage(final AzoriusAethermage card) {
super(card);
}
@Override
- public AzoriusAEthermage copy() {
- return new AzoriusAEthermage(this);
+ public AzoriusAethermage copy() {
+ return new AzoriusAethermage(this);
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BakeIntoAPie.java b/Mage.Sets/src/mage/cards/b/BakeIntoAPie.java
new file mode 100644
index 00000000000..3039e189305
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BakeIntoAPie.java
@@ -0,0 +1,36 @@
+package mage.cards.b;
+
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DestroyTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.game.permanent.token.FoodToken;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author jmharmon
+ */
+
+public final class BakeIntoAPie extends CardImpl {
+
+ public BakeIntoAPie(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}{B}");
+
+ // Destroy target creature. Create a Food token.
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent());
+ this.getSpellAbility().addEffect(new DestroyTargetEffect());
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new FoodToken(), 1));
+ }
+
+ public BakeIntoAPie(final BakeIntoAPie card) {
+ super(card);
+ }
+
+ @Override
+ public BakeIntoAPie copy() {
+ return new BakeIntoAPie(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/Balance.java b/Mage.Sets/src/mage/cards/b/Balance.java
index d198ae74ef2..153b24ecc5c 100644
--- a/Mage.Sets/src/mage/cards/b/Balance.java
+++ b/Mage.Sets/src/mage/cards/b/Balance.java
@@ -26,7 +26,7 @@ public final class Balance extends CardImpl {
public Balance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{W}");
- // Each player chooses a number of lands he or she controls equal to the number of lands controlled by the player who controls the fewest, then sacrifices the rest. Players discard cards and sacrifice creatures the same way.
+ // Each player chooses a number of lands they control equal to the number of lands controlled by the player who controls the fewest, then sacrifices the rest. Players discard cards and sacrifice creatures the same way.
this.getSpellAbility().addEffect(new BalanceEffect());
}
diff --git a/Mage.Sets/src/mage/cards/b/BalancingAct.java b/Mage.Sets/src/mage/cards/b/BalancingAct.java
index a6e85bb8a3f..2052ec14e87 100644
--- a/Mage.Sets/src/mage/cards/b/BalancingAct.java
+++ b/Mage.Sets/src/mage/cards/b/BalancingAct.java
@@ -28,7 +28,7 @@ public final class BalancingAct extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{W}{W}");
- // Each player chooses a number of permanents he or she controls equal to the number of permanents controlled by the player who controls the fewest, then sacrifices the rest. Each player discards cards the same way.
+ // Each player chooses a number of permanents they control equal to the number of permanents controlled by the player who controls the fewest, then sacrifices the rest. Each player discards cards the same way.
this.getSpellAbility().addEffect(new BalancingActEffect());
}
@@ -47,7 +47,7 @@ class BalancingActEffect extends OneShotEffect {
public BalancingActEffect() {
super(Outcome.Sacrifice);
- staticText = "Each player chooses a number of permanents he or she controls equal to the number of permanents controlled by the player who controls the fewest, then sacrifices the rest. Each player discards cards the same way";
+ staticText = "Each player chooses a number of permanents they control equal to the number of permanents controlled by the player who controls the fewest, then sacrifices the rest. Each player discards cards the same way";
}
public BalancingActEffect(final BalancingActEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/b/BalduvianDead.java b/Mage.Sets/src/mage/cards/b/BalduvianDead.java
index 4b5c00f242e..c22274e13a0 100644
--- a/Mage.Sets/src/mage/cards/b/BalduvianDead.java
+++ b/Mage.Sets/src/mage/cards/b/BalduvianDead.java
@@ -1,4 +1,3 @@
-
package mage.cards.b;
import java.util.UUID;
@@ -18,7 +17,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.BalduvianToken;
@@ -39,7 +38,7 @@ public final class BalduvianDead extends CardImpl {
// {2}{R}, Exile a creature card from your graveyard: Create a 3/1 black and red Graveborn creature token with haste. Sacrifice it at the beginning of the next end step.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BalduvianDeadEffect(), new ManaCostsImpl("{2}{R}"));
- TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(new FilterCreatureCard());
+ TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE);
ability.addCost(new ExileFromGraveCost(target));
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/b/BalustradeSpy.java b/Mage.Sets/src/mage/cards/b/BalustradeSpy.java
index 9207b113003..0cdba688cee 100644
--- a/Mage.Sets/src/mage/cards/b/BalustradeSpy.java
+++ b/Mage.Sets/src/mage/cards/b/BalustradeSpy.java
@@ -35,7 +35,7 @@ public final class BalustradeSpy extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
- // When Balustrade Spy enters the battlefield, target player reveals cards from the top of their library until he or she reveals a land card, then puts those cards into their graveyard.
+ // When Balustrade Spy enters the battlefield, target player reveals cards from the top of their library until they reveal a land card, then puts those cards into their graveyard.
Ability ability = new EntersBattlefieldTriggeredAbility(new BalustradeSpyEffect(), false);
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
@@ -55,7 +55,7 @@ class BalustradeSpyEffect extends OneShotEffect {
public BalustradeSpyEffect() {
super(Outcome.Discard);
- this.staticText = "target player reveals cards from the top of their library until he or she reveals a land card, then puts those cards into their graveyard";
+ this.staticText = "target player reveals cards from the top of their library until they reveal a land card, then puts those cards into their graveyard";
}
public BalustradeSpyEffect(final BalustradeSpyEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/b/BaneOfBalaGed.java b/Mage.Sets/src/mage/cards/b/BaneOfBalaGed.java
index 7df9d2b0a3a..c47445ff4bc 100644
--- a/Mage.Sets/src/mage/cards/b/BaneOfBalaGed.java
+++ b/Mage.Sets/src/mage/cards/b/BaneOfBalaGed.java
@@ -32,7 +32,7 @@ public final class BaneOfBalaGed extends CardImpl {
this.power = new MageInt(7);
this.toughness = new MageInt(5);
- // Whenever Bane of Bala Ged attacks, defending player exiles two permanents he or she controls.
+ // Whenever Bane of Bala Ged attacks, defending player exiles two permanents they control.
this.addAbility(new AttacksTriggeredAbility(new BaneOfBalaGedEffect(), false, "", SetTargetPointer.PLAYER));
}
@@ -50,7 +50,7 @@ class BaneOfBalaGedEffect extends OneShotEffect {
public BaneOfBalaGedEffect() {
super(Outcome.Benefit);
- this.staticText = "defending player exiles two permanents he or she controls";
+ this.staticText = "defending player exiles two permanents they control";
}
public BaneOfBalaGedEffect(final BaneOfBalaGedEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/b/BanishIntoFable.java b/Mage.Sets/src/mage/cards/b/BanishIntoFable.java
new file mode 100644
index 00000000000..285f88d1ce4
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BanishIntoFable.java
@@ -0,0 +1,127 @@
+package mage.cards.b;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CastSourceTriggeredAbility;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.token.KnightToken;
+import mage.game.stack.Spell;
+import mage.target.common.TargetNonlandPermanent;
+import mage.watchers.common.CastFromHandWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BanishIntoFable extends CardImpl {
+
+ public BanishIntoFable(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{W}{U}");
+
+ // When you cast this spell from your hand, copy it if you control an artifact, then copy it if you control an enchantment. You may choose new targets for the copies.
+ this.addAbility(new BanishIntoFableTriggeredAbility());
+
+ // Return target nonland permanent to its owner's hand. You create a 2/2 white Knight creature token with vigilance.
+ this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
+ this.getSpellAbility().addTarget(new TargetNonlandPermanent());
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new KnightToken())
+ .setText("You create a 2/2 white Knight creature token with vigilance"));
+ }
+
+ private BanishIntoFable(final BanishIntoFable card) {
+ super(card);
+ }
+
+ @Override
+ public BanishIntoFable copy() {
+ return new BanishIntoFable(this);
+ }
+}
+
+class BanishIntoFableTriggeredAbility extends CastSourceTriggeredAbility {
+
+ BanishIntoFableTriggeredAbility() {
+ super(null, false);
+ this.addWatcher(new CastFromHandWatcher());
+ this.setRuleAtTheTop(true);
+ }
+
+ private BanishIntoFableTriggeredAbility(BanishIntoFableTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ if (!super.checkTrigger(event, game)) {
+ return false;
+ }
+ CastFromHandWatcher watcher = game.getState().getWatcher(CastFromHandWatcher.class);
+ if (watcher == null || !watcher.spellWasCastFromHand(event.getSourceId())) {
+ return false;
+ }
+ Spell spell = game.getState().getStack().getSpell(event.getSourceId());
+ if (spell == null) {
+ return false;
+ }
+ this.getEffects().clear();
+ this.addEffect(new BanishIntoFableEffect(spell.getId()));
+ return true;
+ }
+
+ @Override
+ public BanishIntoFableTriggeredAbility copy() {
+ return new BanishIntoFableTriggeredAbility(this);
+ }
+}
+
+class BanishIntoFableEffect extends OneShotEffect {
+
+ private final UUID spellId;
+
+ BanishIntoFableEffect(UUID spellId) {
+ super(Outcome.Benefit);
+ this.spellId = spellId;
+ }
+
+ private BanishIntoFableEffect(final BanishIntoFableEffect effect) {
+ super(effect);
+ this.spellId = effect.spellId;
+ }
+
+ @Override
+ public BanishIntoFableEffect copy() {
+ return new BanishIntoFableEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Spell spell = game.getSpellOrLKIStack(spellId);
+ if (spell == null) {
+ return false;
+ }
+ if (game.getBattlefield()
+ .getAllActivePermanents(source.getControllerId())
+ .stream()
+ .filter(Permanent::isArtifact)
+ .count() > 0) {
+ spell.createCopyOnStack(game, source, source.getControllerId(), true);
+ }
+ if (game.getBattlefield()
+ .getAllActivePermanents(source.getControllerId())
+ .stream()
+ .filter(Permanent::isEnchantment)
+ .count() > 0) {
+ spell.createCopyOnStack(game, source, source.getControllerId(), true);
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BarbarianBully.java b/Mage.Sets/src/mage/cards/b/BarbarianBully.java
index d9c6ebfd503..38853f5fec3 100644
--- a/Mage.Sets/src/mage/cards/b/BarbarianBully.java
+++ b/Mage.Sets/src/mage/cards/b/BarbarianBully.java
@@ -32,7 +32,7 @@ public final class BarbarianBully extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- // Discard a card at random: Barbarian Bully gets +2/+2 until end of turn unless a player has Barbarian Bully deal 4 damage to him or her. Activate this ability only once each turn.
+ // Discard a card at random: Barbarian Bully gets +2/+2 until end of turn unless a player has Barbarian Bully deal 4 damage to them. Activate this ability only once each turn.
this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new BarbarianBullyEffect(), new DiscardCardCost(true)));
}
diff --git a/Mage.Sets/src/mage/cards/b/BargeIn.java b/Mage.Sets/src/mage/cards/b/BargeIn.java
new file mode 100644
index 00000000000..6f3e297b92d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BargeIn.java
@@ -0,0 +1,52 @@
+package mage.cards.b;
+
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
+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.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.filter.predicate.permanent.AttackingPredicate;
+import mage.target.common.TargetAttackingCreature;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BargeIn extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterCreaturePermanent("Each attacking non-Human creature");
+
+ static {
+ filter.add(AttackingPredicate.instance);
+ filter.add(Predicates.not(new SubtypePredicate(SubType.HUMAN)));
+ }
+
+ public BargeIn(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}");
+
+ // Target attacking creature gets +2/+2 until end of turn. Each attacking non-Human creature gains trample until end of turn.
+ this.getSpellAbility().addEffect(new BoostTargetEffect(2, 2, Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new GainAbilityAllEffect(
+ TrampleAbility.getInstance(), Duration.EndOfTurn, filter
+ ));
+ this.getSpellAbility().addTarget(new TargetAttackingCreature());
+ }
+
+ private BargeIn(final BargeIn card) {
+ super(card);
+ }
+
+ @Override
+ public BargeIn copy() {
+ return new BargeIn(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BaronSengir.java b/Mage.Sets/src/mage/cards/b/BaronSengir.java
index 41375fb1ce3..f97a75dbd97 100644
--- a/Mage.Sets/src/mage/cards/b/BaronSengir.java
+++ b/Mage.Sets/src/mage/cards/b/BaronSengir.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DealtDamageAndDiedTriggeredAbility;
@@ -22,12 +20,13 @@ import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class BaronSengir extends CardImpl {
-
+
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another target Vampire");
static {
@@ -36,18 +35,18 @@ public final class BaronSengir extends CardImpl {
}
public BaronSengir(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{B}{B}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}{B}");
addSuperType(SuperType.LEGENDARY);
- this.subtype.add(SubType.VAMPIRE);
+ this.subtype.add(SubType.VAMPIRE, SubType.NOBLE);
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// Flying
this.addAbility(FlyingAbility.getInstance());
-
+
// Whenever a creature dealt damage by Baron Sengir this turn dies, put a +2/+2 counter on Baron Sengir.
this.addAbility(new DealtDamageAndDiedTriggeredAbility(new AddCountersSourceEffect(CounterType.P2P2.createInstance()), false));
-
+
// {tap}: Regenerate another target Vampire.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateTargetEffect(), new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent(filter));
diff --git a/Mage.Sets/src/mage/cards/b/BarrowWitches.java b/Mage.Sets/src/mage/cards/b/BarrowWitches.java
new file mode 100644
index 00000000000..f442b28e5c9
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BarrowWitches.java
@@ -0,0 +1,50 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterCard;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.target.common.TargetCardInYourGraveyard;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BarrowWitches extends CardImpl {
+
+ private static final FilterCard filter = new FilterCard("Knight card from your graveyard");
+
+ static {
+ filter.add(new SubtypePredicate(SubType.KNIGHT));
+ }
+
+ public BarrowWitches(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.WARLOCK);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(4);
+
+ // When Barrow Witches enters the battlefield, return target Knight card from your graveyard to your hand.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect());
+ ability.addTarget(new TargetCardInYourGraveyard(filter));
+ this.addAbility(ability);
+ }
+
+ private BarrowWitches(final BarrowWitches card) {
+ super(card);
+ }
+
+ @Override
+ public BarrowWitches copy() {
+ return new BarrowWitches(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BarteredCow.java b/Mage.Sets/src/mage/cards/b/BarteredCow.java
new file mode 100644
index 00000000000..07fb03f4e69
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BarteredCow.java
@@ -0,0 +1,66 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.MageObject;
+import mage.abilities.common.DiesTriggeredAbility;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DiscardCardControllerTriggeredAbility;
+import mage.abilities.meta.OrTriggeredAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.FilterCard;
+import mage.filter.predicate.ObjectSourcePlayer;
+import mage.filter.predicate.ObjectSourcePlayerPredicate;
+import mage.game.Game;
+import mage.game.permanent.token.FoodToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BarteredCow extends CardImpl {
+
+ private static final FilterCard filter = new FilterCard();
+
+ static {
+ filter.add(BarteredCowPredicate.instance);
+ }
+
+ public BarteredCow(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
+
+ this.subtype.add(SubType.OX);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // When Bartered Cow dies or when you discard it, create a Food token.
+ this.addAbility(new OrTriggeredAbility(
+ Zone.ALL, new CreateTokenEffect(new FoodToken()), false,
+ "When {this} dies or when you discard it, ", new DiesTriggeredAbility((Effect) null),
+ new DiscardCardControllerTriggeredAbility(null, false, filter)
+ ));
+ }
+
+ private BarteredCow(final BarteredCow card) {
+ super(card);
+ }
+
+ @Override
+ public BarteredCow copy() {
+ return new BarteredCow(this);
+ }
+}
+
+enum BarteredCowPredicate implements ObjectSourcePlayerPredicate> {
+ instance;
+
+ @Override
+ public boolean apply(ObjectSourcePlayer input, Game game) {
+ return input.getObject().getId().equals(input.getSourceId());
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BattletideAlchemist.java b/Mage.Sets/src/mage/cards/b/BattletideAlchemist.java
index 345086c7dfd..8a03fb89a77 100644
--- a/Mage.Sets/src/mage/cards/b/BattletideAlchemist.java
+++ b/Mage.Sets/src/mage/cards/b/BattletideAlchemist.java
@@ -1,8 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
-
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
@@ -13,10 +10,14 @@ import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
+import mage.game.events.PreventDamageEvent;
import mage.players.Player;
+import java.util.UUID;
+
/**
* @author emerald000
*/
@@ -67,7 +68,7 @@ class BattletideAlchemistEffect extends PreventionEffectImpl {
int numberOfClericsControlled = new PermanentsOnBattlefieldCount(new FilterControlledCreaturePermanent(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 GameEvent(GameEvent.EventType.PREVENT_DAMAGE, targetPlayer.getId(), source.getSourceId(), source.getControllerId(), toPrevent, false);
+ GameEvent preventEvent = new PreventDamageEvent(targetPlayer.getId(), source.getSourceId(), source.getControllerId(), toPrevent, ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
if (event.getAmount() >= toPrevent) {
event.setAmount(event.getAmount() - toPrevent);
diff --git a/Mage.Sets/src/mage/cards/b/BatwingBrume.java b/Mage.Sets/src/mage/cards/b/BatwingBrume.java
index bfd0ffc933e..2094141eaba 100644
--- a/Mage.Sets/src/mage/cards/b/BatwingBrume.java
+++ b/Mage.Sets/src/mage/cards/b/BatwingBrume.java
@@ -33,14 +33,14 @@ public final class BatwingBrume extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W/B}");
- // Prevent all combat damage that would be dealt this turn if {W} was spent to cast Batwing Brume. Each player loses 1 life for each attacking creature he or she controls if {B} was spent to cast Batwing Brume.
+ // Prevent all combat damage that would be dealt this turn if {W} was spent to cast Batwing Brume. Each player loses 1 life for each attacking creature they control if {B} was spent to cast Batwing Brume.
Effect effect = new ConditionalReplacementEffect(new PreventAllDamageByAllPermanentsEffect(Duration.EndOfTurn, true),
new LockedInCondition(new ManaWasSpentCondition(ColoredManaSymbol.W)));
- effect.setText("Prevent all combat damage that would be dealt this turn if {W} was spent to cast {this}");
+ effect.setText("Prevent all combat damage that would be dealt this turn if {W} was spent to cast this spell");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new BatwingBrumeEffect(),
- new ManaWasSpentCondition(ColoredManaSymbol.B), "Each player loses 1 life for each attacking creature he or she controls if {B} was spent to cast {this}"));
+ new ManaWasSpentCondition(ColoredManaSymbol.B), "Each player loses 1 life for each attacking creature they control if {B} was spent to cast this spell"));
this.getSpellAbility().addEffect(new InfoEffect("(Do both if {W}{B} was spent.)"));
this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher());
diff --git a/Mage.Sets/src/mage/cards/b/BeanstalkGiant.java b/Mage.Sets/src/mage/cards/b/BeanstalkGiant.java
new file mode 100644
index 00000000000..533ba125904
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BeanstalkGiant.java
@@ -0,0 +1,53 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect;
+import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.StaticFilters;
+import mage.target.common.TargetCardInLibrary;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BeanstalkGiant extends AdventureCard {
+
+ private static final DynamicValue xValue
+ = new PermanentsOnBattlefieldCount(StaticFilters.FILTER_CONTROLLED_PERMANENT_LANDS);
+
+ public BeanstalkGiant(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{6}{G}", "Fertile Footsteps", "{2}{G}");
+
+ this.subtype.add(SubType.GIANT);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(0);
+
+ // Beanstalk Giant's power and toughness are each equal to the number of lands you control.
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(xValue, Duration.EndOfGame)));
+
+ // Fertile Footsteps
+ // Search your library for a basic land card, put it onto the battlefield, then shuffle your library.
+ this.getSpellCard().getSpellAbility().addEffect(
+ new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND))
+ );
+ }
+
+ private BeanstalkGiant(final BeanstalkGiant card) {
+ super(card);
+ }
+
+ @Override
+ public BeanstalkGiant copy() {
+ return new BeanstalkGiant(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BedlamReveler.java b/Mage.Sets/src/mage/cards/b/BedlamReveler.java
index 6bd1228508f..6f6175f7ccf 100644
--- a/Mage.Sets/src/mage/cards/b/BedlamReveler.java
+++ b/Mage.Sets/src/mage/cards/b/BedlamReveler.java
@@ -1,27 +1,33 @@
package mage.cards.b;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.effects.Effect;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.cost.SourceCostReductionForEachCardInGraveyardEffect;
import mage.abilities.effects.common.discard.DiscardHandControllerEffect;
+import mage.abilities.hint.ValueHint;
import mage.abilities.keyword.ProwessAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
-import mage.filter.common.FilterInstantOrSorceryCard;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.StaticFilters;
+
+import java.util.UUID;
/**
- *
* @author fireshoes
*/
public final class BedlamReveler extends CardImpl {
+ private static final DynamicValue cardsCount = new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY);
+
public BedlamReveler(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{R}{R}");
this.subtype.add(SubType.DEVIL, SubType.HORROR);
@@ -29,22 +35,22 @@ public final class BedlamReveler extends CardImpl {
this.toughness = new MageInt(4);
// Bedlam Reveler costs {1} less to cast for each instant or sorcery card in your graveyard.
- Ability ability = new SimpleStaticAbility(Zone.ALL, new SourceCostReductionForEachCardInGraveyardEffect(new FilterInstantOrSorceryCard()));
- ability.setRuleAtTheTop(true);
- this.addAbility(ability);
+ this.addAbility(new SimpleStaticAbility(
+ Zone.ALL, new SourceCostReductionForEachCardInGraveyardEffect(StaticFilters.FILTER_CARD_INSTANT_AND_SORCERY)
+ ).addHint(new ValueHint("Instant and sorcery cards in your graveyard", cardsCount)));
// Prowess
this.addAbility(new ProwessAbility());
// When Bedlam Reveler enters the battlefield, discard your hand, then draw three cards.
- ability = new EntersBattlefieldTriggeredAbility(new DiscardHandControllerEffect());
- Effect effect = new DrawCardSourceControllerEffect(3);
- effect.setText("then draw three cards");
- ability.addEffect(effect);
+ Ability ability = new EntersBattlefieldTriggeredAbility(
+ new DiscardHandControllerEffect().setText("discard your hand,")
+ );
+ ability.addEffect(new DrawCardSourceControllerEffect(3).setText("then draw three cards"));
this.addAbility(ability);
}
- public BedlamReveler(final BedlamReveler card) {
+ private BedlamReveler(final BedlamReveler card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/b/BelleOfTheBrawl.java b/Mage.Sets/src/mage/cards/b/BelleOfTheBrawl.java
new file mode 100644
index 00000000000..e4a47729e43
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BelleOfTheBrawl.java
@@ -0,0 +1,49 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.effects.common.continuous.BoostControlledEffect;
+import mage.abilities.keyword.MenaceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.common.FilterCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BelleOfTheBrawl extends CardImpl {
+
+ private static final FilterCreaturePermanent filter
+ = new FilterCreaturePermanent(SubType.KNIGHT, "Knights");
+
+ public BelleOfTheBrawl(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(2);
+
+ // Menace
+ this.addAbility(new MenaceAbility());
+
+ // Whenever Belle of the Brawl attacks, other Knights you control get +1/+0 until end of turn.
+ this.addAbility(new AttacksTriggeredAbility(new BoostControlledEffect(
+ 1, 0, Duration.EndOfTurn, filter, true
+ ), false));
+ }
+
+ private BelleOfTheBrawl(final BelleOfTheBrawl card) {
+ super(card);
+ }
+
+ @Override
+ public BelleOfTheBrawl copy() {
+ return new BelleOfTheBrawl(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BelovedPrincess.java b/Mage.Sets/src/mage/cards/b/BelovedPrincess.java
new file mode 100644
index 00000000000..ecba10b8ae8
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BelovedPrincess.java
@@ -0,0 +1,55 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
+import mage.abilities.keyword.LifelinkAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.PowerPredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BelovedPrincess extends CardImpl {
+
+ private static final FilterCreaturePermanent filter
+ = new FilterCreaturePermanent("creatures with power 3 or greater");
+
+ static {
+ filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 2));
+ }
+
+ public BelovedPrincess(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.NOBLE);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Lifelink
+ this.addAbility(LifelinkAbility.getInstance());
+
+ // Beloved Princess can't be blocked by creatures with power 3 or greater.
+ this.addAbility(new SimpleStaticAbility(
+ new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield)
+ ));
+ }
+
+ private BelovedPrincess(final BelovedPrincess card) {
+ super(card);
+ }
+
+ @Override
+ public BelovedPrincess copy() {
+ return new BelovedPrincess(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BendOrBreak.java b/Mage.Sets/src/mage/cards/b/BendOrBreak.java
index 19cd360d8f9..bc522120400 100644
--- a/Mage.Sets/src/mage/cards/b/BendOrBreak.java
+++ b/Mage.Sets/src/mage/cards/b/BendOrBreak.java
@@ -146,7 +146,7 @@ class BendOrBreakEffect extends OneShotEffect {
if (chosenOpponent != null) {
List firstPile = playerPiles.getValue().get(0);
List secondPile = playerPiles.getValue().get(1);
- game.informPlayers(player.getLogName() + " chose " + chosenOpponent.getLogName() + " to choose his pile");
+ game.informPlayers(player.getLogName() + " chose " + chosenOpponent.getLogName() + " to choose their pile");
if (chosenOpponent.choosePile(outcome, "Piles of " + player.getName(), firstPile, secondPile, game)) {
List> lists = playerPiles.getValue();
lists.clear();
diff --git a/Mage.Sets/src/mage/cards/b/BenevolentOffering.java b/Mage.Sets/src/mage/cards/b/BenevolentOffering.java
index 6c685d83efe..1a708b23439 100644
--- a/Mage.Sets/src/mage/cards/b/BenevolentOffering.java
+++ b/Mage.Sets/src/mage/cards/b/BenevolentOffering.java
@@ -31,7 +31,7 @@ public final class BenevolentOffering extends CardImpl {
// Choose an opponent. You and that player each create three 1/1 white Spirit creature tokens with flying.
this.getSpellAbility().addEffect(new BenevolentOfferingEffect1());
- // Choose an opponent. You gain 2 life for each creature you control and that player gains 2 life for each creature he or she controls.
+ // Choose an opponent. You gain 2 life for each creature you control and that player gains 2 life for each creature they control.
this.getSpellAbility().addEffect(new BenevolentOfferingEffect2());
}
@@ -84,7 +84,7 @@ class BenevolentOfferingEffect2 extends OneShotEffect {
BenevolentOfferingEffect2() {
super(Outcome.Sacrifice);
- this.staticText = "Choose an opponent. You gain 2 life for each creature you control and that player gains 2 life for each creature he or she controls";
+ this.staticText = "Choose an opponent. You gain 2 life for each creature you control and that player gains 2 life for each creature they control";
}
BenevolentOfferingEffect2(final BenevolentOfferingEffect2 effect) {
diff --git a/Mage.Sets/src/mage/cards/b/BiomancersFamiliar.java b/Mage.Sets/src/mage/cards/b/BiomancersFamiliar.java
index 99f4667c1ac..ced7a58d5f7 100644
--- a/Mage.Sets/src/mage/cards/b/BiomancersFamiliar.java
+++ b/Mage.Sets/src/mage/cards/b/BiomancersFamiliar.java
@@ -37,12 +37,10 @@ public final class BiomancersFamiliar extends CardImpl {
this.toughness = new MageInt(2);
// Activated abilities of creatures you control cost {2} less to activate. This effect can't reduce the amount of mana an ability costs to activate to less than one mana.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BiomancersFamiliarCostReductionEffect()));
+ this.addAbility(new SimpleStaticAbility(new BiomancersFamiliarCostReductionEffect()));
// {T}: The next time target creature adapts this turn, it adapts as though it had no +1/+1 counters on it.
- Ability ability = new SimpleActivatedAbility(
- new BiomancersFamiliarReplacementEffect(), new TapSourceCost()
- );
+ Ability ability = new SimpleActivatedAbility(new BiomancersFamiliarReplacementEffect(), new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
@@ -74,47 +72,48 @@ class BiomancersFamiliarCostReductionEffect extends CostModificationEffectImpl {
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
Player controller = game.getPlayer(abilityToModify.getControllerId());
- if (controller != null) {
- Mana mana = abilityToModify.getManaCostsToPay().getMana();
- int reduceMax = mana.getGeneric();
- if (reduceMax > 0 && mana.count() == mana.getGeneric()) {
- reduceMax--;
- }
- if (reduceMax > 2) {
- reduceMax = 2;
- }
- if (reduceMax > 0) {
- ChoiceImpl choice = new ChoiceImpl(true);
- Set set = new LinkedHashSet<>();
-
- for (int i = 0; i <= reduceMax; i++) {
- set.add(String.valueOf(i));
- }
- choice.setChoices(set);
- choice.setMessage("Reduce ability cost");
- if (!controller.choose(Outcome.Benefit, choice, game)) {
- return false;
- }
- int reduce = Integer.parseInt(choice.getChoice());
- CardUtil.reduceCost(abilityToModify, reduce);
- }
+ if (controller == null) {
+ return false;
+ }
+ Mana mana = abilityToModify.getManaCostsToPay().getMana();
+ int reduceMax = mana.getGeneric();
+ if (reduceMax > 0 && mana.count() == mana.getGeneric()) {
+ reduceMax--;
+ }
+ if (reduceMax > 2) {
+ reduceMax = 2;
+ }
+ if (reduceMax <= 0) {
return true;
}
+ ChoiceImpl choice = new ChoiceImpl(true);
+ Set set = new LinkedHashSet<>();
+
+ for (int i = 0; i <= reduceMax; i++) {
+ set.add(String.valueOf(i));
+ }
+ choice.setChoices(set);
+ choice.setMessage("Reduce ability cost");
+ if (!controller.choose(Outcome.Benefit, choice, game)) {
+ return false;
+ }
+ int reduce = Integer.parseInt(choice.getChoice());
+ CardUtil.reduceCost(abilityToModify, reduce);
+ return true;
- return false;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
- if (abilityToModify.getAbilityType() == AbilityType.ACTIVATED
- || (abilityToModify.getAbilityType() == AbilityType.MANA && abilityToModify instanceof ActivatedAbility)) {
- //Activated abilities of creatures you control
- Permanent permanent = game.getPermanent(abilityToModify.getSourceId());
- if (permanent != null && permanent.isCreature() && permanent.isControlledBy(source.getControllerId())) {
- return true;
- }
+ if (abilityToModify.getAbilityType() != AbilityType.ACTIVATED
+ && (abilityToModify.getAbilityType() != AbilityType.MANA
+ || !(abilityToModify instanceof ActivatedAbility))) {
+ return false;
}
- return false;
+ //Activated abilities of creatures you control
+ Permanent permanent = game.getPermanent(abilityToModify.getSourceId());
+ return permanent != null && permanent.isCreature()
+ && permanent.isControlledBy(source.getControllerId());
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/Biorhythm.java b/Mage.Sets/src/mage/cards/b/Biorhythm.java
index c1172047225..1101fde01f6 100644
--- a/Mage.Sets/src/mage/cards/b/Biorhythm.java
+++ b/Mage.Sets/src/mage/cards/b/Biorhythm.java
@@ -21,7 +21,7 @@ public final class Biorhythm extends CardImpl {
public Biorhythm(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{6}{G}{G}");
- // Each player's life total becomes the number of creatures he or she controls.
+ // Each player's life total becomes the number of creatures they control.
this.getSpellAbility().addEffect(new BiorhythmEffect());
}
@@ -41,7 +41,7 @@ class BiorhythmEffect extends OneShotEffect {
public BiorhythmEffect() {
super(Outcome.Neutral);
- this.staticText = "Each player's life total becomes the number of creatures he or she controls";
+ this.staticText = "Each player's life total becomes the number of creatures they control";
}
public BiorhythmEffect(final BiorhythmEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/b/BlackbladeReforged.java b/Mage.Sets/src/mage/cards/b/BlackbladeReforged.java
index 16ccb69fbda..a3ab6f157ad 100644
--- a/Mage.Sets/src/mage/cards/b/BlackbladeReforged.java
+++ b/Mage.Sets/src/mage/cards/b/BlackbladeReforged.java
@@ -5,30 +5,35 @@
*/
package mage.cards.b;
-import java.util.UUID;
-import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.common.SimpleStaticAbility;
-import mage.filter.common.FilterControlledLandPermanent;
-import mage.filter.common.FilterControlledPermanent;
-import mage.abilities.effects.common.continuous.BoostEquippedEffect;
import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.effects.common.continuous.BoostEquippedEffect;
import mage.abilities.keyword.EquipAbility;
-import mage.abilities.keyword.EquipLegendaryAbility;
+import mage.abilities.keyword.EquipFilterAbility;
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.constants.Zone;
+import mage.constants.*;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.mageobject.SupertypePredicate;
+
+import java.util.UUID;
/**
- *
* @author Rystan
*/
public final class BlackbladeReforged extends CardImpl {
- private static final FilterControlledPermanent filter = new FilterControlledLandPermanent();
+ private static final DynamicValue count
+ = new PermanentsOnBattlefieldCount(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND);
+ private static final FilterControlledCreaturePermanent filter
+ = new FilterControlledCreaturePermanent("legendary creature");
+
+ static {
+ filter.add(new SupertypePredicate(SuperType.LEGENDARY));
+ }
public BlackbladeReforged(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
@@ -36,17 +41,16 @@ public final class BlackbladeReforged extends CardImpl {
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +1/+1 for each land you control.
- PermanentsOnBattlefieldCount count = new PermanentsOnBattlefieldCount(filter);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(count, count)));
// Equip legendary creature (3)
- this.addAbility(new EquipLegendaryAbility(Outcome.AddAbility, new GenericManaCost(3)));
+ this.addAbility(new EquipFilterAbility(filter, new GenericManaCost(3)));
// Equip {7}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(7)));
}
- public BlackbladeReforged(final BlackbladeReforged card) {
+ private BlackbladeReforged(final BlackbladeReforged card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/b/BlacklanceParagon.java b/Mage.Sets/src/mage/cards/b/BlacklanceParagon.java
new file mode 100644
index 00000000000..f7b066a634f
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BlacklanceParagon.java
@@ -0,0 +1,61 @@
+
+package mage.cards.b;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.effects.Effect;
+import mage.abilities.keyword.DeathtouchAbility;
+import mage.abilities.keyword.LifelinkAbility;
+import mage.abilities.keyword.FlashAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author Tsirides
+ */
+public final class BlacklanceParagon extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.KNIGHT, "Knight");
+
+ public BlacklanceParagon(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(1);
+
+ // Flash
+ this.addAbility(FlashAbility.getInstance());
+
+
+ // When Blacklance Paragon enters the battlefield, target Knight gains deathtouch and lifelink until end of turn.
+ Effect effect = new GainAbilityTargetEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn);
+ effect.setText("target Knight gains deathtouch");
+ Ability ability = new EntersBattlefieldTriggeredAbility(effect);
+ effect = new GainAbilityTargetEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn);
+ effect.setText("and lifelink until end of turn");
+ ability.addEffect(effect);
+ ability.addTarget(new TargetCreaturePermanent(filter));
+ this.addAbility(ability);
+
+ }
+
+ public BlacklanceParagon(final BlacklanceParagon card) {
+ super(card);
+ }
+
+ @Override
+ public BlacklanceParagon copy() {
+ return new BlacklanceParagon(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BlazingSalvo.java b/Mage.Sets/src/mage/cards/b/BlazingSalvo.java
index 15d5d177c08..cff5ba54fae 100644
--- a/Mage.Sets/src/mage/cards/b/BlazingSalvo.java
+++ b/Mage.Sets/src/mage/cards/b/BlazingSalvo.java
@@ -22,7 +22,7 @@ public final class BlazingSalvo extends CardImpl {
public BlazingSalvo(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}");
- // Blazing Salvo deals 3 damage to target creature unless that creature's controller has Blazing Salvo deal 5 damage to him or her.
+ // Blazing Salvo deals 3 damage to target creature unless that creature's controller has Blazing Salvo deal 5 damage to them.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new BlazingSalvoEffect());
}
@@ -41,7 +41,7 @@ class BlazingSalvoEffect extends OneShotEffect {
public BlazingSalvoEffect() {
super(Outcome.Damage);
- this.staticText = "{this} deals 3 damage to target creature unless that creature's controller has {this} deal 5 damage to him or her";
+ this.staticText = "{this} deals 3 damage to target creature unless that creature's controller has {this} deal 5 damage to them";
}
public BlazingSalvoEffect(final BlazingSalvoEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/b/BlightSickle.java b/Mage.Sets/src/mage/cards/b/BlightSickle.java
index f960b0e7c88..920fedb594e 100644
--- a/Mage.Sets/src/mage/cards/b/BlightSickle.java
+++ b/Mage.Sets/src/mage/cards/b/BlightSickle.java
@@ -2,6 +2,8 @@
package mage.cards.b;
import java.util.UUID;
+
+import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
@@ -23,8 +25,13 @@ public final class BlightSickle extends CardImpl {
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +1/+0 and has wither.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 0)));
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(WitherAbility.getInstance(), AttachmentType.EQUIPMENT)));
+ Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(1, 0));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ WitherAbility.getInstance(), AttachmentType.EQUIPMENT).setText("and has wither")
+ );
+ this.addAbility(ability);
+
+ // Equip {2}
this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(2)));
}
diff --git a/Mage.Sets/src/mage/cards/b/BlindFury.java b/Mage.Sets/src/mage/cards/b/BlindFury.java
new file mode 100644
index 00000000000..cd7a9bb007d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BlindFury.java
@@ -0,0 +1,83 @@
+package mage.cards.b;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.ReplacementEffectImpl;
+import mage.abilities.effects.common.continuous.LoseAbilityAllEffect;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.events.DamageCreatureEvent;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BlindFury extends CardImpl {
+
+ public BlindFury(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}{R}");
+
+ // All creatures lose trample until end of turn. If a creature would deal combat damage to a creature this turn, it deals double that damage to that creature instead.
+ this.getSpellAbility().addEffect(new LoseAbilityAllEffect(
+ TrampleAbility.getInstance(), Duration.EndOfTurn,
+ StaticFilters.FILTER_PERMANENT_CREATURES
+ ).setText("All creatures lose trample until end of turn."));
+ this.getSpellAbility().addEffect(new FurnaceOfRathEffect());
+ }
+
+ private BlindFury(final BlindFury card) {
+ super(card);
+ }
+
+ @Override
+ public BlindFury copy() {
+ return new BlindFury(this);
+ }
+}
+
+class FurnaceOfRathEffect extends ReplacementEffectImpl {
+
+ FurnaceOfRathEffect() {
+ super(Duration.EndOfTurn, Outcome.Damage);
+ staticText = "If a creature would deal combat damage to a creature this turn, " +
+ "it deals double that damage to that creature instead";
+ }
+
+ private FurnaceOfRathEffect(final FurnaceOfRathEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public FurnaceOfRathEffect copy() {
+ return new FurnaceOfRathEffect(this);
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.DAMAGE_CREATURE;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ Permanent permanent = game.getPermanent(event.getSourceId());
+ return permanent != null
+ && permanent.isCreature()
+ && ((DamageCreatureEvent) event).isCombatDamage();
+
+ }
+
+ @Override
+ public boolean replaceEvent(GameEvent event, Ability source, Game game) {
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BlindZealot.java b/Mage.Sets/src/mage/cards/b/BlindZealot.java
index c1de1d9731b..4fb163cab21 100644
--- a/Mage.Sets/src/mage/cards/b/BlindZealot.java
+++ b/Mage.Sets/src/mage/cards/b/BlindZealot.java
@@ -1,6 +1,5 @@
package mage.cards.b;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
@@ -16,13 +15,15 @@ import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game;
+import mage.game.events.DamagedEvent;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author North
*/
public final class BlindZealot extends CardImpl {
@@ -42,7 +43,7 @@ public final class BlindZealot extends CardImpl {
this.addAbility(ability);
}
- public BlindZealot(final BlindZealot card) {
+ private BlindZealot(final BlindZealot card) {
super(card);
}
@@ -54,11 +55,11 @@ public final class BlindZealot extends CardImpl {
class BlindZealotTriggeredAbility extends TriggeredAbilityImpl {
- public BlindZealotTriggeredAbility() {
+ BlindZealotTriggeredAbility() {
super(Zone.BATTLEFIELD, new DoIfCostPaid(new DestroyTargetEffect(), new SacrificeSourceCost()), true);
}
- public BlindZealotTriggeredAbility(final BlindZealotTriggeredAbility ability) {
+ private BlindZealotTriggeredAbility(final BlindZealotTriggeredAbility ability) {
super(ability);
}
@@ -75,14 +76,16 @@ class BlindZealotTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Player opponent = game.getPlayer(event.getPlayerId());
- if (opponent != null && event.getSourceId().equals(this.sourceId)) {
- FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + opponent.getLogName() + " controls");
- filter.add(new ControllerIdPredicate(opponent.getId()));
- this.getTargets().clear();
- this.addTarget(new TargetCreaturePermanent(filter));
- return true;
+ if (opponent == null
+ || !event.getSourceId().equals(this.sourceId)
+ || !((DamagedEvent) event).isCombatDamage()) {
+ return false;
}
- return false;
+ FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + opponent.getLogName() + " controls");
+ filter.add(new ControllerIdPredicate(opponent.getId()));
+ this.getTargets().clear();
+ this.addTarget(new TargetCreaturePermanent(filter));
+ return true;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/BlindingFog.java b/Mage.Sets/src/mage/cards/b/BlindingFog.java
index cd3628ef37e..fd0094616e3 100644
--- a/Mage.Sets/src/mage/cards/b/BlindingFog.java
+++ b/Mage.Sets/src/mage/cards/b/BlindingFog.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.abilities.effects.common.PreventAllDamageToAllEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.HexproofAbility;
@@ -9,11 +7,13 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
+import mage.filter.StaticFilters;
+
+import java.util.UUID;
+
import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURE;
-import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES;
/**
- *
* @author LevelX2
*/
public final class BlindingFog extends CardImpl {
@@ -22,7 +22,8 @@ public final class BlindingFog extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}");
// Prevent all damage that would be dealt to creatures this turn.
- this.getSpellAbility().addEffect(new PreventAllDamageToAllEffect(Duration.EndOfTurn, FILTER_PERMANENT_CREATURES));
+ this.getSpellAbility().addEffect(new PreventAllDamageToAllEffect(Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURES));
+
// Creatures you control gain hexproof until end of turn.
this.getSpellAbility().addEffect(new GainAbilityControlledEffect(HexproofAbility.getInstance(), Duration.EndOfTurn, FILTER_PERMANENT_CREATURE, false));
}
diff --git a/Mage.Sets/src/mage/cards/b/BlinkmothUrn.java b/Mage.Sets/src/mage/cards/b/BlinkmothUrn.java
index 06fa539b03e..fd56ff4c515 100644
--- a/Mage.Sets/src/mage/cards/b/BlinkmothUrn.java
+++ b/Mage.Sets/src/mage/cards/b/BlinkmothUrn.java
@@ -32,7 +32,7 @@ public final class BlinkmothUrn extends CardImpl {
// At the beginning of each player's precombat main phase, if
// Blinkmoth Urn is untapped, that player adds {1} to their
- // mana pool for each artifact he or she controls.
+ // mana pool for each artifact they control.
this.addAbility(new BeginningOfPreCombatMainTriggeredAbility(new BlinkmothUrnEffect(), TargetController.ANY, false));
}
@@ -51,7 +51,7 @@ class BlinkmothUrnEffect extends OneShotEffect {
public BlinkmothUrnEffect() {
super(Outcome.PutManaInPool);
- this.staticText = "if Blinkmoth Urn is untapped, that player adds {1} for each artifact he or she controls";
+ this.staticText = "if Blinkmoth Urn is untapped, that player adds {1} for each artifact they control";
}
public BlinkmothUrnEffect(final BlinkmothUrnEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/b/BlizzardSpecter.java b/Mage.Sets/src/mage/cards/b/BlizzardSpecter.java
index 1fb2a4c3a27..cac621a40ec 100644
--- a/Mage.Sets/src/mage/cards/b/BlizzardSpecter.java
+++ b/Mage.Sets/src/mage/cards/b/BlizzardSpecter.java
@@ -36,7 +36,7 @@ public final class BlizzardSpecter extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever Blizzard Specter deals combat damage to a player, choose one
- // - That player returns a permanent he or she controls to its owner's hand;
+ // - That player returns a permanent they control to its owner's hand;
Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new ReturnToHandEffect(), false, true);
// or that player discards a card.
@@ -61,7 +61,7 @@ class ReturnToHandEffect extends OneShotEffect {
public ReturnToHandEffect() {
super(Outcome.ReturnToHand);
- staticText = "That player returns a permanent he or she controls to its owner's hand";
+ staticText = "That player returns a permanent they control to its owner's hand";
}
public ReturnToHandEffect(final ReturnToHandEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/b/BloodClock.java b/Mage.Sets/src/mage/cards/b/BloodClock.java
index c24cfd06342..886ca0006cc 100644
--- a/Mage.Sets/src/mage/cards/b/BloodClock.java
+++ b/Mage.Sets/src/mage/cards/b/BloodClock.java
@@ -26,7 +26,7 @@ public final class BloodClock extends CardImpl {
public BloodClock(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
- // At the beginning of each player's upkeep, that player returns a permanent he or she controls to its owner's hand unless he or she pays 2 life.
+ // At the beginning of each player's upkeep, that player returns a permanent they control to its owner's hand unless they pay 2 life.
Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new BloodClockEffect(), TargetController.ANY, false, true);
this.addAbility(ability);
}
@@ -45,7 +45,7 @@ class BloodClockEffect extends OneShotEffect {
public BloodClockEffect() {
super(Outcome.ReturnToHand);
- this.staticText = "that player returns a permanent he or she controls to its owner's hand unless he or she pays 2 life";
+ this.staticText = "that player returns a permanent they control to its owner's hand unless they pay 2 life";
}
public BloodClockEffect(final BloodClockEffect effect) {
@@ -65,7 +65,7 @@ class BloodClockEffect extends OneShotEffect {
}
if (player.getLife() > 2 && player.chooseUse(Outcome.Neutral, "Pay 2 life? If you don't, return a permanent you control to its owner's hand.", source, game)) {
player.loseLife(2, game, false);
- game.informPlayers(player.getLogName() + " pays 2 life. He will not return a permanent he or she controls.");
+ game.informPlayers(player.getLogName() + " pays 2 life. They will not return a permanent they control.");
return true;
} else {
Target target = new TargetControlledPermanent();
diff --git a/Mage.Sets/src/mage/cards/b/BloodForBones.java b/Mage.Sets/src/mage/cards/b/BloodForBones.java
index e04e4a2717b..c0c4ea3716c 100644
--- a/Mage.Sets/src/mage/cards/b/BloodForBones.java
+++ b/Mage.Sets/src/mage/cards/b/BloodForBones.java
@@ -56,7 +56,7 @@ class BloodForBonesEffect extends OneShotEffect {
= new FilterCreatureCard("creature card in your graveyard (to put into your hand");
BloodForBonesEffect() {
- super(Outcome.Benefit);
+ super(Outcome.PutCardInPlay);
staticText = "Return a creature card from your graveyard to the battlefield, " +
"then return another creature card from your graveyard to your hand.";
}
diff --git a/Mage.Sets/src/mage/cards/b/BloodhazeWolverine.java b/Mage.Sets/src/mage/cards/b/BloodhazeWolverine.java
new file mode 100644
index 00000000000..38b7b6e5131
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BloodhazeWolverine.java
@@ -0,0 +1,47 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.DrawSecondCardTriggeredAbility;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.FirstStrikeAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BloodhazeWolverine extends CardImpl {
+
+ public BloodhazeWolverine(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
+
+ this.subtype.add(SubType.WOLVERINE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(1);
+
+ // Whenever you draw your second card each turn, Bloodhaze Wolverine gets +1/+1 and gains first strike until end of turn.
+ Ability ability = new DrawSecondCardTriggeredAbility(new BoostSourceEffect(
+ 1, 1, Duration.EndOfTurn
+ ).setText("{this} gets +1/+1"), false);
+ ability.addEffect(new GainAbilitySourceEffect(
+ FirstStrikeAbility.getInstance(), Duration.EndOfTurn
+ ).setText("and gains first strike until end of turn"));
+ this.addAbility(ability);
+ }
+
+ private BloodhazeWolverine(final BloodhazeWolverine card) {
+ super(card);
+ }
+
+ @Override
+ public BloodhazeWolverine copy() {
+ return new BloodhazeWolverine(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BloodthirstyBlade.java b/Mage.Sets/src/mage/cards/b/BloodthirstyBlade.java
index a1a1da7ac00..9e1502a5fe8 100644
--- a/Mage.Sets/src/mage/cards/b/BloodthirstyBlade.java
+++ b/Mage.Sets/src/mage/cards/b/BloodthirstyBlade.java
@@ -4,8 +4,8 @@ import mage.abilities.Ability;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.GenericManaCost;
-import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.RestrictionEffect;
+import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.combat.AttacksIfAbleAttachedEffect;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
import mage.cards.CardImpl;
@@ -17,8 +17,6 @@ import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
-import static mage.constants.Outcome.Benefit;
-
/**
* @author TheElk801
*/
@@ -39,7 +37,10 @@ public final class BloodthirstyBlade extends CardImpl {
// {1}: Attach Bloodthirsty Blade to target creature an opponent controls. Active this ability only any time you could cast a sorcery.
ability = new ActivateAsSorceryActivatedAbility(
- Zone.BATTLEFIELD, new BloodthirstyBladeEffect(), new GenericManaCost(1)
+ Zone.BATTLEFIELD,
+ new AttachEffect(
+ Outcome.Benefit, "Attach {this} to target creature an opponent controls"
+ ), new GenericManaCost(1)
);
ability.addTarget(new TargetOpponentsCreaturePermanent());
this.addAbility(ability);
@@ -86,30 +87,3 @@ class BloodthirstyBladeAttackEffect extends RestrictionEffect {
return !defenderId.equals(source.getControllerId());
}
}
-
-class BloodthirstyBladeEffect extends OneShotEffect {
-
- BloodthirstyBladeEffect() {
- super(Benefit);
- staticText = "attach {this} to target creature an opponent controls";
- }
-
- private BloodthirstyBladeEffect(final BloodthirstyBladeEffect effect) {
- super(effect);
- }
-
- @Override
- public BloodthirstyBladeEffect copy() {
- return new BloodthirstyBladeEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Permanent permanent = game.getPermanent(source.getSourceId());
- if (permanent == null) {
- return false;
- }
- permanent.attachTo(source.getFirstTarget(), game);
- return true;
- }
-}
diff --git a/Mage.Sets/src/mage/cards/b/BlossomingWreath.java b/Mage.Sets/src/mage/cards/b/BlossomingWreath.java
index 6c2267a97b5..ccd0d2970a4 100644
--- a/Mage.Sets/src/mage/cards/b/BlossomingWreath.java
+++ b/Mage.Sets/src/mage/cards/b/BlossomingWreath.java
@@ -1,4 +1,3 @@
-
package mage.cards.b;
import java.util.UUID;
@@ -8,7 +7,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
@@ -19,7 +18,7 @@ import mage.players.Player;
public final class BlossomingWreath extends CardImpl {
public BlossomingWreath(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}");
// You gain life equal to the number of creature cards in your graveyard.
this.getSpellAbility().addEffect(new BlossomingWreathEffect());
@@ -54,7 +53,7 @@ public final class BlossomingWreath extends CardImpl {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- controller.gainLife(controller.getGraveyard().count(new FilterCreatureCard(), game), game, source);
+ controller.gainLife(controller.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game), game, source);
return true;
}
return false;
diff --git a/Mage.Sets/src/mage/cards/b/BlowYourHouseDown.java b/Mage.Sets/src/mage/cards/b/BlowYourHouseDown.java
new file mode 100644
index 00000000000..4c8bc31c286
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BlowYourHouseDown.java
@@ -0,0 +1,70 @@
+package mage.cards.b;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.combat.CantBlockTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.game.Game;
+import mage.target.Target;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.Collection;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BlowYourHouseDown extends CardImpl {
+
+ public BlowYourHouseDown(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}");
+
+ // Up to three target creatures can't block this turn. Destroy any of them that are Walls.
+ this.getSpellAbility().addEffect(new CantBlockTargetEffect(Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new BlowYourHouseDownEffect());
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 3));
+ }
+
+ private BlowYourHouseDown(final BlowYourHouseDown card) {
+ super(card);
+ }
+
+ @Override
+ public BlowYourHouseDown copy() {
+ return new BlowYourHouseDown(this);
+ }
+}
+
+class BlowYourHouseDownEffect extends OneShotEffect {
+
+ BlowYourHouseDownEffect() {
+ super(Outcome.Benefit);
+ staticText = "Destroy any of them that are Walls";
+ }
+
+ private BlowYourHouseDownEffect(final BlowYourHouseDownEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public BlowYourHouseDownEffect copy() {
+ return new BlowYourHouseDownEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ source.getTargets()
+ .stream()
+ .map(Target::getTargets)
+ .flatMap(Collection::stream)
+ .map(game::getPermanent)
+ .filter(permanent -> permanent != null && permanent.hasSubtype(SubType.WALL, game))
+ .forEach(permanent -> permanent.destroy(source.getSourceId(), game, false));
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/b/BogNaughty.java b/Mage.Sets/src/mage/cards/b/BogNaughty.java
new file mode 100644
index 00000000000..39aa74ef30d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BogNaughty.java
@@ -0,0 +1,55 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.common.FilterControlledPermanent;
+import mage.target.common.TargetControlledPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BogNaughty extends CardImpl {
+
+ private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.FOOD, "a Food");
+
+ public BogNaughty(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
+
+ this.subtype.add(SubType.FAERIE);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // {2}{B}, Sacrifice a Food: Target creature gets -3/-3 until end of turn.
+ Ability ability = new SimpleActivatedAbility(
+ new BoostTargetEffect(-3, -3, Duration.EndOfTurn), new ManaCostsImpl("{2}{B}")
+ );
+ ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter)));
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+ }
+
+ private BogNaughty(final BogNaughty card) {
+ super(card);
+ }
+
+ @Override
+ public BogNaughty copy() {
+ return new BogNaughty(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BolassCitadel.java b/Mage.Sets/src/mage/cards/b/BolassCitadel.java
index b66b461f2bf..f7b9fa3b549 100644
--- a/Mage.Sets/src/mage/cards/b/BolassCitadel.java
+++ b/Mage.Sets/src/mage/cards/b/BolassCitadel.java
@@ -1,118 +1,123 @@
-package mage.cards.b;
-
-import mage.abilities.Ability;
-import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.costs.Costs;
-import mage.abilities.costs.CostsImpl;
-import mage.abilities.costs.common.PayLifeCost;
-import mage.abilities.costs.common.SacrificeTargetCost;
-import mage.abilities.costs.common.TapSourceCost;
-import mage.abilities.effects.AsThoughEffectImpl;
-import mage.abilities.effects.common.LoseLifeOpponentsEffect;
-import mage.abilities.effects.common.continuous.LookAtTopCardOfLibraryAnyTimeEffect;
-import mage.cards.Card;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-import mage.constants.*;
-import mage.filter.common.FilterControlledPermanent;
-import mage.filter.predicate.Predicates;
-import mage.filter.predicate.mageobject.CardTypePredicate;
-import mage.game.Game;
-import mage.players.Player;
-import mage.target.common.TargetControlledPermanent;
-
-import java.util.UUID;
-import mage.abilities.costs.Cost;
-
-/**
- * @author jeffwadsworth
- */
-public final class BolassCitadel extends CardImpl {
-
- private static final FilterControlledPermanent filter = new FilterControlledPermanent("nonland permanents");
-
- static {
- filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
- }
-
- public BolassCitadel(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}{B}{B}{B}");
-
- this.addSuperType(SuperType.LEGENDARY);
-
- // You may look at the top card of your library any time.
- this.addAbility(new SimpleStaticAbility(new LookAtTopCardOfLibraryAnyTimeEffect()));
-
- // You may play the top card of your library. If you cast a spell this way, pay life equal to its converted mana cost rather than pay its mana cost.
- this.addAbility(new SimpleStaticAbility(new BolassCitadelPlayTheTopCardEffect()));
-
- // {T}, Sacrifice ten nonland permanents: Each opponent loses 10 life.
- Ability ability = new SimpleActivatedAbility(new LoseLifeOpponentsEffect(10), new TapSourceCost());
- ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(
- 10, 10, filter, true
- )));
- this.addAbility(ability);
- }
-
- private BolassCitadel(final BolassCitadel card) {
- super(card);
- }
-
- @Override
- public BolassCitadel copy() {
- return new BolassCitadel(this);
- }
-}
-
-class BolassCitadelPlayTheTopCardEffect extends AsThoughEffectImpl {
-
- BolassCitadelPlayTheTopCardEffect() {
- super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE,
- Duration.WhileOnBattlefield, Outcome.AIDontUseIt); // AI will need help with this
- staticText = "You may play the top card of your library. If you cast a spell this way, "
- + "pay life equal to its converted mana cost rather than pay its mana cost.";
- }
-
- private BolassCitadelPlayTheTopCardEffect(final BolassCitadelPlayTheTopCardEffect effect) {
- super(effect);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- return true;
- }
-
- @Override
- public BolassCitadelPlayTheTopCardEffect copy() {
- return new BolassCitadelPlayTheTopCardEffect(this);
- }
-
- @Override
- public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
- Card cardOnTop = game.getCard(objectId);
- if (cardOnTop == null) {
- return false;
- }
- if (affectedControllerId.equals(source.getControllerId())
- && cardOnTop.isOwnedBy(source.getControllerId())) {
- Player controller = game.getPlayer(cardOnTop.getOwnerId());
- if (controller != null
- && cardOnTop.equals(controller.getLibrary().getFromTop(game))) {
- // add the life cost first
- PayLifeCost cost = new PayLifeCost(cardOnTop.getManaCost().convertedManaCost());
- Costs costs = new CostsImpl();
- costs.add(cost);
- // check for additional costs that must be paid
- if (cardOnTop.getSpellAbility() != null) {
- for (Cost additionalCost : cardOnTop.getSpellAbility().getCosts()) {
- costs.add(additionalCost);
- }
- }
- controller.setCastSourceIdWithAlternateMana(cardOnTop.getId(), null, costs);
- return true;
- }
- }
- return false;
- }
-}
+package mage.cards.b;
+
+import mage.abilities.Ability;
+import mage.abilities.ActivatedAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.Costs;
+import mage.abilities.costs.CostsImpl;
+import mage.abilities.costs.common.PayLifeCost;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.AsThoughEffectImpl;
+import mage.abilities.effects.common.LoseLifeOpponentsEffect;
+import mage.abilities.effects.common.continuous.LookAtTopCardOfLibraryAnyTimeEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.common.TargetControlledPermanent;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author jeffwadsworth
+ */
+public final class BolassCitadel extends CardImpl {
+
+ private static final FilterControlledPermanent filter = new FilterControlledPermanent("nonland permanents");
+
+ static {
+ filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
+ }
+
+ public BolassCitadel(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}{B}{B}{B}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+
+ // You may look at the top card of your library any time.
+ this.addAbility(new SimpleStaticAbility(new LookAtTopCardOfLibraryAnyTimeEffect()));
+
+ // You may play the top card of your library. If you cast a spell this way, pay life equal to its converted mana cost rather than pay its mana cost.
+ this.addAbility(new SimpleStaticAbility(new BolassCitadelPlayTheTopCardEffect()));
+
+ // {T}, Sacrifice ten nonland permanents: Each opponent loses 10 life.
+ Ability ability = new SimpleActivatedAbility(new LoseLifeOpponentsEffect(10), new TapSourceCost());
+ ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(
+ 10, 10, filter, true
+ )));
+ this.addAbility(ability);
+ }
+
+ private BolassCitadel(final BolassCitadel card) {
+ super(card);
+ }
+
+ @Override
+ public BolassCitadel copy() {
+ return new BolassCitadel(this);
+ }
+}
+
+class BolassCitadelPlayTheTopCardEffect extends AsThoughEffectImpl {
+
+ BolassCitadelPlayTheTopCardEffect() {
+ super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE,
+ Duration.WhileOnBattlefield, Outcome.AIDontUseIt); // AI will need help with this
+ staticText = "You may play the top card of your library. If you cast a spell this way, "
+ + "pay life equal to its converted mana cost rather than pay its mana cost.";
+ }
+
+ private BolassCitadelPlayTheTopCardEffect(final BolassCitadelPlayTheTopCardEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public BolassCitadelPlayTheTopCardEffect copy() {
+ return new BolassCitadelPlayTheTopCardEffect(this);
+ }
+
+ @Override
+ public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
+ return applies(objectId, null, source, game, affectedControllerId);
+ }
+
+ @Override
+ public boolean applies(UUID objectId, Ability affectedAbility, Ability source, Game game, UUID playerId) {
+ Card cardToCheck = game.getCard(objectId);
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
+
+ if (cardToCheck != null
+ && playerId.equals(source.getControllerId())
+ && cardToCheck.isOwnedBy(source.getControllerId())) {
+ Player controller = game.getPlayer(cardToCheck.getOwnerId());
+ if (controller != null
+ && controller.getLibrary().getFromTop(game) != null
+ && objectId.equals(controller.getLibrary().getFromTop(game).getId())) {
+ if (affectedAbility instanceof ActivatedAbility) {
+ ActivatedAbility activatedAbility = (ActivatedAbility) affectedAbility;
+ // add the life cost first
+ PayLifeCost cost = new PayLifeCost(activatedAbility.getManaCosts().convertedManaCost());
+ Costs costs = new CostsImpl();
+ costs.add(cost);
+ costs.addAll(activatedAbility.getCosts());
+ controller.setCastSourceIdWithAlternateMana(activatedAbility.getSourceId(), null, costs);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BoldwyrHeavyweights.java b/Mage.Sets/src/mage/cards/b/BoldwyrHeavyweights.java
index f86567ffc29..3a0cc593f7c 100644
--- a/Mage.Sets/src/mage/cards/b/BoldwyrHeavyweights.java
+++ b/Mage.Sets/src/mage/cards/b/BoldwyrHeavyweights.java
@@ -1,4 +1,3 @@
-
package mage.cards.b;
import java.util.HashSet;
@@ -16,7 +15,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
@@ -28,7 +27,7 @@ import mage.target.common.TargetCardInLibrary;
public final class BoldwyrHeavyweights extends CardImpl {
public BoldwyrHeavyweights(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
this.subtype.add(SubType.GIANT, SubType.WARRIOR);
this.power = new MageInt(8);
this.toughness = new MageInt(8);
@@ -72,7 +71,7 @@ class BoldwyrHeavyweightsEffect extends OneShotEffect {
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentId);
if (opponent != null && opponent.chooseUse(Outcome.PutCreatureInPlay, "Search your library for a creature card and put it onto the battlefield?", source, game)) {
- TargetCardInLibrary target = new TargetCardInLibrary(new FilterCreatureCard());
+ TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_CREATURE);
if (opponent.searchLibrary(target, source, game)) {
Card targetCard = opponent.getLibrary().getCard(target.getFirstTarget(), game);
if (targetCard != null) {
diff --git a/Mage.Sets/src/mage/cards/b/BonePicker.java b/Mage.Sets/src/mage/cards/b/BonePicker.java
index 8588ed14857..504e1c08078 100644
--- a/Mage.Sets/src/mage/cards/b/BonePicker.java
+++ b/Mage.Sets/src/mage/cards/b/BonePicker.java
@@ -1,4 +1,3 @@
-
package mage.cards.b;
import java.util.UUID;
@@ -7,12 +6,15 @@ import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.MorbidCondition;
-import mage.abilities.costs.AdjustingSourceCosts;
+import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
+import mage.constants.CostModificationType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
@@ -33,7 +35,7 @@ public final class BonePicker extends CardImpl {
this.toughness = new MageInt(2);
// Bone Picker costs {3} less to cast if a creature died this turn.
- this.addAbility(new BonePickerCostAdjustmentAbility(), new MorbidWatcher());
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new BonePickerAdjustingCostsEffect()), new MorbidWatcher());
// Flying
this.addAbility(FlyingAbility.getInstance());
@@ -53,32 +55,37 @@ public final class BonePicker extends CardImpl {
}
}
-class BonePickerCostAdjustmentAbility extends SimpleStaticAbility implements AdjustingSourceCosts {
+class BonePickerAdjustingCostsEffect extends CostModificationEffectImpl {
- public BonePickerCostAdjustmentAbility() {
- super(Zone.OUTSIDE, null);
+ BonePickerAdjustingCostsEffect() {
+ super(Duration.EndOfGame, Outcome.Benefit, CostModificationType.REDUCE_COST);
+ staticText = "{this} costs {3} less to cast if a creature died this turn";
}
- public BonePickerCostAdjustmentAbility(final BonePickerCostAdjustmentAbility ability) {
- super(ability);
+ BonePickerAdjustingCostsEffect(BonePickerAdjustingCostsEffect effect) {
+ super(effect);
}
@Override
- public SimpleStaticAbility copy() {
- return new BonePickerCostAdjustmentAbility(this);
+ public boolean apply(Game game, Ability source, Ability abilityToModify) {
+ CardUtil.reduceCost(abilityToModify, 3);
+ return true;
}
@Override
- public String getRule() {
- return "If a creature died this turn, {this} costs {3} less to cast.";
- }
-
- @Override
- public void adjustCosts(Ability ability, Game game) {
- if (ability instanceof SpellAbility) { // Prevent adjustment of activated ability
- if (MorbidCondition.instance.apply(game, ability)) {
- CardUtil.adjustCost((SpellAbility) ability, 3);
+ public boolean applies(Ability abilityToModify, Ability source, Game game) {
+ if (abilityToModify.getSourceId().equals(source.getSourceId())
+ && (abilityToModify instanceof SpellAbility)) {
+ if (MorbidCondition.instance.apply(game, abilityToModify)) {
+ return true;
}
}
+
+ return false;
+ }
+
+ @Override
+ public BonePickerAdjustingCostsEffect copy() {
+ return new BonePickerAdjustingCostsEffect(this);
}
}
diff --git a/Mage.Sets/src/mage/cards/b/BonecrusherGiant.java b/Mage.Sets/src/mage/cards/b/BonecrusherGiant.java
new file mode 100644
index 00000000000..8a756691c2e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BonecrusherGiant.java
@@ -0,0 +1,82 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.BecomesTargetTriggeredAbility;
+import mage.abilities.effects.ReplacementEffectImpl;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.target.common.TargetAnyTarget;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BonecrusherGiant extends AdventureCard {
+
+ public BonecrusherGiant(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.INSTANT}, "{2}{R}", "Stomp", "{1}{R}");
+
+ this.subtype.add(SubType.GIANT);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(3);
+
+ // Whenever Bonecrusher Giant becomes the target of a spell, Bonecrusher Giant deals 2 damage to that spell's controller.
+ this.addAbility(new BecomesTargetTriggeredAbility(new DamageTargetEffect(
+ 2, true, "that's spell's controller", "{this}"
+ ), StaticFilters.FILTER_SPELL_A, SetTargetPointer.PLAYER));
+
+ // Stomp
+ // Damage can’t be prevented this turn. Stomp deals 2 damage to any target.
+ this.getSpellCard().getSpellAbility().addEffect(new StompEffect());
+ this.getSpellCard().getSpellAbility().addEffect(new DamageTargetEffect(2));
+ this.getSpellCard().getSpellAbility().addTarget(new TargetAnyTarget());
+ }
+
+ private BonecrusherGiant(final BonecrusherGiant card) {
+ super(card);
+ }
+
+ @Override
+ public BonecrusherGiant copy() {
+ return new BonecrusherGiant(this);
+ }
+}
+
+class StompEffect extends ReplacementEffectImpl {
+
+ StompEffect() {
+ super(Duration.EndOfTurn, Outcome.Benefit);
+ staticText = "Damage can't be prevented this turn.";
+ }
+
+ private StompEffect(final StompEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public StompEffect copy() {
+ return new StompEffect(this);
+ }
+
+ @Override
+ public boolean replaceEvent(GameEvent event, Ability source, Game game) {
+ return true;
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.PREVENT_DAMAGE;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/Bonehoard.java b/Mage.Sets/src/mage/cards/b/Bonehoard.java
index 5ff585c7e20..db147be0cd8 100644
--- a/Mage.Sets/src/mage/cards/b/Bonehoard.java
+++ b/Mage.Sets/src/mage/cards/b/Bonehoard.java
@@ -1,4 +1,3 @@
-
package mage.cards.b;
import java.util.UUID;
@@ -15,7 +14,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
* @author North
@@ -30,7 +29,7 @@ public final class Bonehoard extends CardImpl {
this.addAbility(new LivingWeaponAbility());
// Equipped creature gets +X/+X, where X is the number of creature cards in all graveyards.
- CardsInAllGraveyardsCount value = new CardsInAllGraveyardsCount(new FilterCreatureCard());
+ CardsInAllGraveyardsCount value = new CardsInAllGraveyardsCount(StaticFilters.FILTER_CARD_CREATURE);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(value, value)));
// Equip {2}
diff --git a/Mage.Sets/src/mage/cards/b/BoneyardWurm.java b/Mage.Sets/src/mage/cards/b/BoneyardWurm.java
index 224c6eb2b39..42a921d7714 100644
--- a/Mage.Sets/src/mage/cards/b/BoneyardWurm.java
+++ b/Mage.Sets/src/mage/cards/b/BoneyardWurm.java
@@ -1,4 +1,3 @@
-
package mage.cards.b;
import java.util.UUID;
@@ -12,7 +11,7 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
* @author nantuko
@@ -20,12 +19,11 @@ import mage.filter.common.FilterCreatureCard;
public final class BoneyardWurm extends CardImpl {
public BoneyardWurm(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.WURM);
-
// Boneyard Wurm's power and toughness are each equal to the number of creature cards in your graveyard.
- DynamicValue value = new CardsInControllerGraveyardCount(new FilterCreatureCard());
+ DynamicValue value = new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE);
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(value, Duration.EndOfGame)));
}
diff --git a/Mage.Sets/src/mage/cards/b/BonfireOfTheDamned.java b/Mage.Sets/src/mage/cards/b/BonfireOfTheDamned.java
index 54a4f3ed72f..6a80e99dfb5 100644
--- a/Mage.Sets/src/mage/cards/b/BonfireOfTheDamned.java
+++ b/Mage.Sets/src/mage/cards/b/BonfireOfTheDamned.java
@@ -27,7 +27,7 @@ public final class BonfireOfTheDamned extends CardImpl {
public BonfireOfTheDamned(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{X}{R}");
- // Bonfire of the Damned deals X damage to target player and each creature he or she controls.
+ // Bonfire of the Damned deals X damage to target player and each creature they control.
this.getSpellAbility().addEffect(new BonfireOfTheDamnedEffect());
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
diff --git a/Mage.Sets/src/mage/cards/b/BoobyTrap.java b/Mage.Sets/src/mage/cards/b/BoobyTrap.java
index ed7c8d844b3..fb098ef4c75 100644
--- a/Mage.Sets/src/mage/cards/b/BoobyTrap.java
+++ b/Mage.Sets/src/mage/cards/b/BoobyTrap.java
@@ -34,7 +34,7 @@ public final class BoobyTrap extends CardImpl {
etbAbility.addEffect(new ChooseOpponentEffect(Outcome.Damage));
this.addAbility(etbAbility);
- // The chosen player reveals each card he or she draws.
+ // The chosen player reveals each card they draw.
// When the chosen player draws the named card, sacrifice Booby Trap. If you do, Booby Trap deals 10 damage to that player.
this.addAbility(new BoobyTrapTriggeredAbility());
}
@@ -91,7 +91,7 @@ class BoobyTrapTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
- return "The chosen player reveals each card he or she draws.\n" +
+ return "The chosen player reveals each card they draw.\n" +
"When the chosen player draws the named card, sacrifice {this}. If you do, {this} deals 10 damage to that player.";
}
}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/b/BookBurning.java b/Mage.Sets/src/mage/cards/b/BookBurning.java
index dc287d32b40..5301fee9c85 100644
--- a/Mage.Sets/src/mage/cards/b/BookBurning.java
+++ b/Mage.Sets/src/mage/cards/b/BookBurning.java
@@ -23,7 +23,7 @@ public final class BookBurning extends CardImpl {
public BookBurning(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{R}");
- // Any player may have Book Burning deal 6 damage to him or her. If no one does, target player puts the top six cards of their library into their graveyard.
+ // Any player may have Book Burning deal 6 damage to them. If no one does, target player puts the top six cards of their library into their graveyard.
this.getSpellAbility().addEffect(new BookBurningMillEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
}
@@ -42,7 +42,7 @@ class BookBurningMillEffect extends OneShotEffect {
public BookBurningMillEffect() {
super(Outcome.Detriment);
- staticText = "Any player may have {source} deal 6 damage to him or her. If no one does, target player puts the top six cards of their library into their graveyard";
+ staticText = "Any player may have {source} deal 6 damage to them. If no one does, target player puts the top six cards of their library into their graveyard";
}
public BookBurningMillEffect(final BookBurningMillEffect effect) {
@@ -64,7 +64,7 @@ class BookBurningMillEffect extends OneShotEffect {
if (player != null && player.chooseUse(Outcome.Detriment, "Have " + sourceObject.getLogName() + " deal 6 damage to you?", source, game)) {
millCards = false;
player.damage(6, source.getSourceId(), game, false, true);
- game.informPlayers(player.getLogName() + " has " + sourceObject.getLogName() + " deal 6 damage to him or her");
+ game.informPlayers(player.getLogName() + " has " + sourceObject.getLogName() + " deal 6 damage to them");
}
}
if (millCards) {
diff --git a/Mage.Sets/src/mage/cards/b/BorGullet.java b/Mage.Sets/src/mage/cards/b/BorGullet.java
index a19260fa658..51d0b9a3dbd 100644
--- a/Mage.Sets/src/mage/cards/b/BorGullet.java
+++ b/Mage.Sets/src/mage/cards/b/BorGullet.java
@@ -25,7 +25,7 @@ public final class BorGullet extends CardImpl {
this.power = new MageInt(4);
this.toughness = new MageInt(4);
- // When Bor Gullet enters the battlefield, target opponent reveals his or her hand. You choose a card from it. That player discards that card.
+ // When Bor Gullet enters the battlefield, target opponent reveals their hand. You choose a card from it. That player discards that card.
Ability ability = new EntersBattlefieldTriggeredAbility(new DiscardCardYouChooseTargetEffect());
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/b/BorealElemental.java b/Mage.Sets/src/mage/cards/b/BorealElemental.java
index e496ba4261b..bd0f8fcadaf 100644
--- a/Mage.Sets/src/mage/cards/b/BorealElemental.java
+++ b/Mage.Sets/src/mage/cards/b/BorealElemental.java
@@ -2,6 +2,7 @@ package mage.cards.b;
import mage.MageInt;
import mage.abilities.Ability;
+import mage.abilities.Mode;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
@@ -10,8 +11,10 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
+import mage.target.Target;
import mage.util.CardUtil;
+import java.util.Collection;
import java.util.UUID;
/**
@@ -72,15 +75,11 @@ class BorealElementalCostIncreaseEffect extends CostModificationEffectImpl {
.getSelectedModes()
.stream()
.map(uuid -> abilityToModify.getModes().get(uuid))
- .anyMatch(mode -> mode
- .getTargets()
- .stream()
- .anyMatch(target -> target
- .getTargets()
- .stream()
- .anyMatch(uuid -> uuid.equals(source.getSourceId()))
- )
- );
+ .map(Mode::getTargets)
+ .flatMap(Collection::stream)
+ .map(Target::getTargets)
+ .flatMap(Collection::stream)
+ .anyMatch(uuid -> uuid.equals(source.getSourceId()));
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/BorosFuryShield.java b/Mage.Sets/src/mage/cards/b/BorosFuryShield.java
index 509e6fd4e68..4b744fbe539 100644
--- a/Mage.Sets/src/mage/cards/b/BorosFuryShield.java
+++ b/Mage.Sets/src/mage/cards/b/BorosFuryShield.java
@@ -37,7 +37,7 @@ public final class BorosFuryShield extends CardImpl {
// If {R} was spent to cast Boros Fury-Shield, it deals damage to that creature's controller equal to the creature's power.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new BorosFuryShieldDamageEffect(),
- new ManaWasSpentCondition(ColoredManaSymbol.R), "If {R} was spent to cast {this}, it deals damage to that creature's controller equal to the creature's power"));
+ new ManaWasSpentCondition(ColoredManaSymbol.R), "If {R} was spent to cast this spell, it deals damage to that creature's controller equal to the creature's power"));
}
public BorosFuryShield(final BorosFuryShield card) {
diff --git a/Mage.Sets/src/mage/cards/b/BraceForImpact.java b/Mage.Sets/src/mage/cards/b/BraceForImpact.java
index 6b5a458592c..507b658c5a7 100644
--- a/Mage.Sets/src/mage/cards/b/BraceForImpact.java
+++ b/Mage.Sets/src/mage/cards/b/BraceForImpact.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.PreventionEffectImpl;
import mage.cards.CardImpl;
@@ -12,12 +10,15 @@ 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.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author TheElk801
*/
public final class BraceForImpact extends CardImpl {
@@ -69,7 +70,7 @@ class BraceForImpactPreventDamageTargetEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int prevented = 0;
int damage = event.getAmount();
@@ -93,9 +94,7 @@ class BraceForImpactPreventDamageTargetEffect extends PreventionEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!this.used && super.applies(event, source, game)) {
- if (source.getTargets().getFirstTarget().equals(event.getTargetId())) {
- return true;
- }
+ return source.getTargets().getFirstTarget().equals(event.getTargetId());
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/b/BragoKingEternal.java b/Mage.Sets/src/mage/cards/b/BragoKingEternal.java
index f1445fd1ee5..ce1353d4d0e 100644
--- a/Mage.Sets/src/mage/cards/b/BragoKingEternal.java
+++ b/Mage.Sets/src/mage/cards/b/BragoKingEternal.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
@@ -20,8 +18,9 @@ import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.target.common.TargetControlledPermanent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class BragoKingEternal extends CardImpl {
@@ -29,7 +28,7 @@ public final class BragoKingEternal extends CardImpl {
public BragoKingEternal(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{U}");
addSuperType(SuperType.LEGENDARY);
- this.subtype.add(SubType.SPIRIT);
+ this.subtype.add(SubType.SPIRIT, SubType.NOBLE);
this.power = new MageInt(2);
this.toughness = new MageInt(4);
diff --git a/Mage.Sets/src/mage/cards/b/BrainInAJar.java b/Mage.Sets/src/mage/cards/b/BrainInAJar.java
index 78969941889..35f30d72c7e 100644
--- a/Mage.Sets/src/mage/cards/b/BrainInAJar.java
+++ b/Mage.Sets/src/mage/cards/b/BrainInAJar.java
@@ -1,4 +1,3 @@
-
package mage.cards.b;
import java.util.UUID;
@@ -36,16 +35,24 @@ public final class BrainInAJar extends CardImpl {
public BrainInAJar(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
- // {1}, {T}: Put a charge counter on Brain in a Jar, then you may cast an instant or sorcery card with converted mana costs equal to the number of charge counters on Brain in a Jar from your hand without paying its mana cost.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.CHARGE.createInstance()), new GenericManaCost(1));
+ // {1}, {T}: Put a charge counter on Brain in a Jar, then you may
+ // cast an instant or sorcery card with converted mana costs equal
+ // to the number of charge counters on Brain in a Jar from your
+ // hand without paying its mana cost.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
+ new AddCountersSourceEffect(CounterType.CHARGE.createInstance()),
+ new GenericManaCost(1));
ability.addEffect(new BrainInAJarCastEffect());
ability.addCost(new TapSourceCost());
this.addAbility(ability);
// {3}, {T}, Remove X charge counters from Brain in a Jar: Scry X.
- ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BrainInAJarScryEffect(), new GenericManaCost(3));
+ ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
+ new BrainInAJarScryEffect(),
+ new GenericManaCost(3));
ability.addCost(new TapSourceCost());
- ability.addCost(new RemoveVariableCountersSourceCost(CounterType.CHARGE.createInstance()));
+ ability.addCost(new RemoveVariableCountersSourceCost(
+ CounterType.CHARGE.createInstance()));
this.addAbility(ability);
}
@@ -62,8 +69,10 @@ public final class BrainInAJar extends CardImpl {
class BrainInAJarCastEffect extends OneShotEffect {
public BrainInAJarCastEffect() {
- super(Outcome.Benefit);
- this.staticText = ", then you may cast an instant or sorcery card with converted mana costs equal to the number of charge counters on {this} from your hand without paying its mana cost";
+ super(Outcome.PlayForFree);
+ this.staticText = ", then you may cast an instant or sorcery card "
+ + "with converted mana costs equal to the number of charge "
+ + "counters on {this} from your hand without paying its mana cost";
}
public BrainInAJarCastEffect(final BrainInAJarCastEffect effect) {
@@ -79,17 +88,26 @@ class BrainInAJarCastEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourceObject = game.getPermanentOrLKIBattlefield(source.getSourceId());
- if (controller != null && sourceObject != null) {
+ if (controller != null
+ && sourceObject != null) {
int counters = sourceObject.getCounters(game).getCount(CounterType.CHARGE);
FilterCard filter = new FilterInstantOrSorceryCard();
filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, counters));
- int cardsToCast = controller.getHand().count(filter, source.getControllerId(), source.getSourceId(), game);
- if (cardsToCast > 0 && controller.chooseUse(outcome, "Cast an instant or sorcery card with converted mana costs of " + counters + " from your hand without paying its mana cost?", source, game)) {
+ int cardsToCast = controller.getHand().count(filter, source.getControllerId(),
+ source.getSourceId(), game);
+ if (cardsToCast > 0
+ && controller.chooseUse(Outcome.PlayForFree,
+ "Cast an instant or sorcery card with converted mana costs of "
+ + counters + " from your hand without paying its mana cost?",
+ source, game)) {
TargetCardInHand target = new TargetCardInHand(filter);
controller.chooseTarget(outcome, target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
return true;
diff --git a/Mage.Sets/src/mage/cards/b/BrainPry.java b/Mage.Sets/src/mage/cards/b/BrainPry.java
index 4628af7111f..2e75ebc8321 100644
--- a/Mage.Sets/src/mage/cards/b/BrainPry.java
+++ b/Mage.Sets/src/mage/cards/b/BrainPry.java
@@ -24,7 +24,7 @@ public final class BrainPry extends CardImpl {
public BrainPry(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}");
- //Name a nonland card. Target player reveals their hand. That player discards a card with that name. If he or she can't, you draw a card.
+ //Name a nonland card. Target player reveals their hand. That player discards a card with that name. If they can't, you draw a card.
this.getSpellAbility().addEffect((new ChooseACardNameEffect(ChooseACardNameEffect.TypeOfName.NON_LAND_NAME)));
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new BrainPryEffect());
@@ -44,7 +44,7 @@ class BrainPryEffect extends OneShotEffect {
public BrainPryEffect() {
super(Outcome.Discard);
- staticText = "Target player reveals their hand. That player discards a card with that name. If he or she can't, you draw a card";
+ staticText = "Target player reveals their hand. That player discards a card with that name. If they can't, you draw a card";
}
public BrainPryEffect(final BrainPryEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/b/BramblefortFink.java b/Mage.Sets/src/mage/cards/b/BramblefortFink.java
new file mode 100644
index 00000000000..8356669ee09
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BramblefortFink.java
@@ -0,0 +1,47 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.common.ActivateIfConditionActivatedAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPlaneswalkerPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BramblefortFink extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterControlledPlaneswalkerPermanent(SubType.OKO, "you control an Oko planeswalker");
+ private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter);
+
+ public BramblefortFink(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
+
+ this.subtype.add(SubType.OUPHE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // {8}: Bramblefort Fink has base power and toughness 10/10 until end of turn. Activate this ability only if you control an Oko planeswalker.
+ this.addAbility(new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, new SetPowerToughnessSourceEffect(
+ 10, 10, Duration.EndOfTurn, SubLayer.SetPT_7b
+ ).setText("{this} has base power and toughness 10/10 until end of turn"), new GenericManaCost(8), condition));
+ }
+
+ private BramblefortFink(final BramblefortFink card) {
+ super(card);
+ }
+
+ @Override
+ public BramblefortFink copy() {
+ return new BramblefortFink(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BrazenBorrower.java b/Mage.Sets/src/mage/cards/b/BrazenBorrower.java
new file mode 100644
index 00000000000..9a7d91a18c7
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BrazenBorrower.java
@@ -0,0 +1,63 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.common.CanBlockOnlyFlyingAbility;
+import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.keyword.FlashAbility;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterNonlandPermanent;
+import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BrazenBorrower extends AdventureCard {
+
+ private static final FilterPermanent filter
+ = new FilterNonlandPermanent("nonland permanent an opponent controls");
+
+ static {
+ filter.add(new ControllerPredicate(TargetController.OPPONENT));
+ }
+
+ public BrazenBorrower(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.INSTANT}, "{1}{U}{U}", "Petty Theft", "{1}{U}");
+
+ this.subtype.add(SubType.FAERIE);
+ this.subtype.add(SubType.ROGUE);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(1);
+
+ // Flash
+ this.addAbility(FlashAbility.getInstance());
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Bazen Borrower can block only creatures with flying.
+ this.addAbility(new CanBlockOnlyFlyingAbility());
+
+ // Petty Theft
+ // Return target nonland permanent an opponent controls to its owner's hand.
+ this.getSpellCard().getSpellAbility().addEffect(new ReturnToHandTargetEffect());
+ this.getSpellCard().getSpellAbility().addTarget(new TargetPermanent(filter));
+ }
+
+ private BrazenBorrower(final BrazenBorrower card) {
+ super(card);
+ }
+
+ @Override
+ public BrazenBorrower copy() {
+ return new BrazenBorrower(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BreakingEntering.java b/Mage.Sets/src/mage/cards/b/BreakingEntering.java
index eb51034f634..4c96f12ae48 100644
--- a/Mage.Sets/src/mage/cards/b/BreakingEntering.java
+++ b/Mage.Sets/src/mage/cards/b/BreakingEntering.java
@@ -1,4 +1,3 @@
-
package mage.cards.b;
import java.util.UUID;
@@ -16,7 +15,7 @@ import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SpellAbilityType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.Target;
@@ -70,7 +69,7 @@ class EnteringReturnFromGraveyardToBattlefieldEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- Target target = new TargetCardInGraveyard(new FilterCreatureCard());
+ Target target = new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE);
target.setNotTarget(true);
if (target.canChoose(source.getSourceId(), source.getControllerId(), game)
&& controller.chooseTarget(outcome, target, source, game)) {
diff --git a/Mage.Sets/src/mage/cards/b/BreakingPoint.java b/Mage.Sets/src/mage/cards/b/BreakingPoint.java
index 3ed755f00e3..d9696d9ecd8 100644
--- a/Mage.Sets/src/mage/cards/b/BreakingPoint.java
+++ b/Mage.Sets/src/mage/cards/b/BreakingPoint.java
@@ -24,7 +24,7 @@ public final class BreakingPoint extends CardImpl {
public BreakingPoint(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}{R}");
- // Any player may have Breaking Point deal 6 damage to him or her. If no one does, destroy all creatures. Creatures destroyed this way can't be regenerated.
+ // Any player may have Breaking Point deal 6 damage to them. If no one does, destroy all creatures. Creatures destroyed this way can't be regenerated.
this.getSpellAbility().addEffect(new BreakingPointDestroyEffect());
}
@@ -42,7 +42,7 @@ class BreakingPointDestroyEffect extends OneShotEffect {
public BreakingPointDestroyEffect() {
super(Outcome.Benefit);
- this.staticText = "Any player may have {this} deal 6 damage to him or her. If no one does, destroy all creatures. Creatures destroyed this way can't be regenerated.";
+ this.staticText = "Any player may have {this} deal 6 damage to them. If no one does, destroy all creatures. Creatures destroyed this way can't be regenerated.";
}
public BreakingPointDestroyEffect(final BreakingPointDestroyEffect effect) {
@@ -74,7 +74,7 @@ class BreakingPointDestroyEffect extends OneShotEffect {
if (player != null && player.chooseUse(Outcome.Detriment, "Have " + spell.getLogName() + " deal 6 damage to you?", source, game)) {
destroyCreatures = false;
player.damage(6, source.getSourceId(), game, false, true);
- game.informPlayers(player.getLogName() + " has " + spell.getName() + " deal 6 to him or her");
+ game.informPlayers(player.getLogName() + " has " + spell.getName() + " deal 6 to them");
}
}
if (destroyCreatures) {
diff --git a/Mage.Sets/src/mage/cards/b/Breakthrough.java b/Mage.Sets/src/mage/cards/b/Breakthrough.java
index d6fcdc241f2..15f6a890e9d 100644
--- a/Mage.Sets/src/mage/cards/b/Breakthrough.java
+++ b/Mage.Sets/src/mage/cards/b/Breakthrough.java
@@ -65,7 +65,7 @@ class BreakthroughEffect extends OneShotEffect {
if (player != null) {
int amountToKeep = source.getManaCostsToPay().getX();
if (amountToKeep == 0) {
- player.discard(player.getHand().size(), source, game);
+ player.discard(player.getHand().size(), false, source, game);
}
else if (amountToKeep < player.getHand().size()) {
TargetCardInHand target = new TargetCardInHand(amountToKeep, new FilterCard());
diff --git a/Mage.Sets/src/mage/cards/b/BreathstealersCrypt.java b/Mage.Sets/src/mage/cards/b/BreathstealersCrypt.java
index aaeb5b471e2..520cd01f91e 100644
--- a/Mage.Sets/src/mage/cards/b/BreathstealersCrypt.java
+++ b/Mage.Sets/src/mage/cards/b/BreathstealersCrypt.java
@@ -27,7 +27,7 @@ public final class BreathstealersCrypt extends CardImpl {
public BreathstealersCrypt(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{B}");
- // If a player would draw a card, instead he or she draws a card and reveals it. If it's a creature card, that player discards it unless he or she pays 3 life.
+ // If a player would draw a card, instead they draw a card and reveals it. If it's a creature card, that player discards it unless they pay 3 life.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BreathstealersCryptEffect()));
}
diff --git a/Mage.Sets/src/mage/cards/b/BrimstoneTrebuchet.java b/Mage.Sets/src/mage/cards/b/BrimstoneTrebuchet.java
new file mode 100644
index 00000000000..e36f61c9570
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BrimstoneTrebuchet.java
@@ -0,0 +1,57 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.common.DamagePlayersEffect;
+import mage.abilities.effects.common.UntapSourceEffect;
+import mage.abilities.keyword.DefenderAbility;
+import mage.abilities.keyword.ReachAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+import mage.filter.FilterPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BrimstoneTrebuchet extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterPermanent(SubType.KNIGHT, "a Knight");
+
+ public BrimstoneTrebuchet(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{R}");
+
+ this.subtype.add(SubType.WALL);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(3);
+
+ // Defender
+ this.addAbility(DefenderAbility.getInstance());
+
+ // Reach
+ this.addAbility(ReachAbility.getInstance());
+
+ // {T}: Brimstone Trebuchet deals 1 damage to each opponent.
+ this.addAbility(new SimpleActivatedAbility(
+ new DamagePlayersEffect(1, TargetController.OPPONENT), new TapSourceCost()
+ ));
+
+ // Whenever a Knight enters the battlefield under your control, untap Brimstone Trebuchet.
+ this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new UntapSourceEffect(), filter));
+ }
+
+ private BrimstoneTrebuchet(final BrimstoneTrebuchet card) {
+ super(card);
+ }
+
+ @Override
+ public BrimstoneTrebuchet copy() {
+ return new BrimstoneTrebuchet(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/BrimstoneVolley.java b/Mage.Sets/src/mage/cards/b/BrimstoneVolley.java
index d0fca035254..dfc42e7bc6f 100644
--- a/Mage.Sets/src/mage/cards/b/BrimstoneVolley.java
+++ b/Mage.Sets/src/mage/cards/b/BrimstoneVolley.java
@@ -1,19 +1,14 @@
-
package mage.cards.b;
-import java.util.UUID;
-import mage.abilities.Ability;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.condition.common.MorbidCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
-import mage.players.Player;
import mage.target.common.TargetAnyTarget;
-import mage.watchers.Watcher;
import mage.watchers.common.MorbidWatcher;
+import java.util.UUID;
/**
* @author nantuko
@@ -25,8 +20,13 @@ public final class BrimstoneVolley extends CardImpl {
// Brimstone Volley deals 3 damage to any target.
// Morbid — Brimstone Volley deals 5 damage to that creature or player instead if a creature died this turn.
- this.getSpellAbility().addEffect(new BrimstoneVolleyEffect());
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new DamageTargetEffect(5), new DamageTargetEffect(3), MorbidCondition.instance,
+ "{this} deals 3 damage to any target." +
+ "
Morbid — {this} deals 5 damage instead if a creature died this turn."
+ ));
this.getSpellAbility().addTarget(new TargetAnyTarget());
+ this.getSpellAbility().addWatcher(new MorbidWatcher());
}
public BrimstoneVolley(final BrimstoneVolley card) {
@@ -38,41 +38,3 @@ public final class BrimstoneVolley extends CardImpl {
return new BrimstoneVolley(this);
}
}
-
-class BrimstoneVolleyEffect extends OneShotEffect {
-
- public BrimstoneVolleyEffect() {
- super(Outcome.Damage);
- staticText = "{this} deals 3 damage to any target.\n Morbid — {this} deals 5 damage to that permanent or player instead if a creature died this turn";
- }
-
- public BrimstoneVolleyEffect(final BrimstoneVolleyEffect effect) {
- super(effect);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- int damage = 3;
- MorbidWatcher watcher = game.getState().getWatcher(MorbidWatcher.class);
- if (watcher != null && watcher.conditionMet()) {
- damage = 5;
- }
- Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
- if (permanent != null) {
- permanent.damage(damage, source.getSourceId(), game, false, true);
- return true;
- }
- Player player = game.getPlayer(targetPointer.getFirst(game, source));
- if (player != null) {
- player.damage(damage, source.getSourceId(), game, false, true);
- return true;
- }
- return false;
- }
-
- @Override
- public BrimstoneVolleyEffect copy() {
- return new BrimstoneVolleyEffect(this);
- }
-
-}
diff --git a/Mage.Sets/src/mage/cards/b/BrineGiant.java b/Mage.Sets/src/mage/cards/b/BrineGiant.java
new file mode 100644
index 00000000000..3d646c17994
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BrineGiant.java
@@ -0,0 +1,86 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.effects.common.cost.CostModificationEffectImpl;
+import mage.abilities.hint.ValueHint;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.game.Game;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BrineGiant extends CardImpl {
+
+ private static final DynamicValue xValue
+ = new PermanentsOnBattlefieldCount(BrineGiantCostReductionEffect.filter);
+
+ public BrineGiant(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{U}");
+
+ this.subtype.add(SubType.GIANT);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(6);
+
+ // This spell costs {1} less to cast for each enchantment you control.
+ this.addAbility(new SimpleStaticAbility(
+ Zone.ALL, new BrineGiantCostReductionEffect()
+ ).addHint(new ValueHint("Enchantments you control", xValue)));
+ }
+
+ private BrineGiant(final BrineGiant card) {
+ super(card);
+ }
+
+ @Override
+ public BrineGiant copy() {
+ return new BrineGiant(this);
+ }
+}
+
+class BrineGiantCostReductionEffect extends CostModificationEffectImpl {
+
+ static final FilterControlledPermanent filter = new FilterControlledPermanent();
+
+ static {
+ filter.add(new CardTypePredicate(CardType.ENCHANTMENT));
+ }
+
+ BrineGiantCostReductionEffect() {
+ super(Duration.WhileOnStack, Outcome.Benefit, CostModificationType.REDUCE_COST);
+ staticText = "This spell costs {1} less to cast for each artifact you control";
+ }
+
+ private BrineGiantCostReductionEffect(final BrineGiantCostReductionEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source, Ability abilityToModify) {
+ int count = game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game).size();
+ if (count > 0) {
+ CardUtil.reduceCost(abilityToModify, count);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean applies(Ability abilityToModify, Ability source, Game game) {
+ return abilityToModify.getSourceId().equals(source.getSourceId());
+ }
+
+ @Override
+ public BrineGiantCostReductionEffect copy() {
+ return new BrineGiantCostReductionEffect(this);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/b/BringToLight.java b/Mage.Sets/src/mage/cards/b/BringToLight.java
index 1f10c21b5c7..de4435c5e68 100644
--- a/Mage.Sets/src/mage/cards/b/BringToLight.java
+++ b/Mage.Sets/src/mage/cards/b/BringToLight.java
@@ -1,4 +1,3 @@
-
package mage.cards.b;
import java.util.UUID;
@@ -71,7 +70,8 @@ class BringToLightEffect extends OneShotEffect {
if (controller != null) {
int numberColors = ColorsOfManaSpentToCastCount.getInstance().calculate(game, source, this);
FilterCard filter = new FilterCard();
- filter.add(Predicates.or(new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.SORCERY)));
+ filter.add(Predicates.or(new CardTypePredicate(CardType.CREATURE),
+ new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.SORCERY)));
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, numberColors + 1));
TargetCardInLibrary target = new TargetCardInLibrary(filter);
controller.searchLibrary(target, source, game);
@@ -81,9 +81,13 @@ class BringToLightEffect extends OneShotEffect {
}
controller.shuffleLibrary(source, game);
if (card != null) {
- if (controller.chooseUse(outcome, "Cast " + card.getName() + " without paying its mana cost?", source, game)) {
- if (card.getSpellAbility() != null) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ if (controller.chooseUse(Outcome.PlayForFree, "Cast " + card.getName()
+ + " without paying its mana cost?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (cardWasCast) {
} else {
Logger.getLogger(BringToLightEffect.class).error("Bring to Light: spellAbility == null " + card.getName());
}
diff --git a/Mage.Sets/src/mage/cards/b/BronzeBombshell.java b/Mage.Sets/src/mage/cards/b/BronzeBombshell.java
index da5bda513d5..297659b689b 100644
--- a/Mage.Sets/src/mage/cards/b/BronzeBombshell.java
+++ b/Mage.Sets/src/mage/cards/b/BronzeBombshell.java
@@ -31,7 +31,7 @@ public final class BronzeBombshell extends CardImpl {
this.power = new MageInt(4);
this.toughness = new MageInt(1);
- // When a player other than Bronze Bombshell's owner controls it, that player sacrifices it. If the player does, Bronze Bombshell deals 7 damage to him or her.
+ // When a player other than Bronze Bombshell's owner controls it, that player sacrifices it. If the player does, Bronze Bombshell deals 7 damage to the player.
this.addAbility(new LoseControlTriggeredAbility(new BronzeBombshellEffect(), false));
}
@@ -88,7 +88,7 @@ class BronzeBombshellEffect extends OneShotEffect {
public BronzeBombshellEffect() {
super(Outcome.Damage);
- this.staticText = "that player sacrifices it. If the player does, {this} deals 7 damage to him or her.";
+ this.staticText = "that player sacrifices it. If the player does, {this} deals 7 damage to the player.";
}
public BronzeBombshellEffect(final BronzeBombshellEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/b/BroodingSaurian.java b/Mage.Sets/src/mage/cards/b/BroodingSaurian.java
index 221feab710f..982c95c617f 100644
--- a/Mage.Sets/src/mage/cards/b/BroodingSaurian.java
+++ b/Mage.Sets/src/mage/cards/b/BroodingSaurian.java
@@ -31,7 +31,7 @@ public final class BroodingSaurian extends CardImpl {
this.power = new MageInt(4);
this.toughness = new MageInt(4);
- // At the beginning of each end step, each player gains control of all nontoken permanents he or she owns.
+ // At the beginning of each end step, each player gains control of all nontoken permanents they own.
this.addAbility(new BeginningOfEndStepTriggeredAbility(new BroodingSaurianControlEffect(), TargetController.ANY, false));
}
diff --git a/Mage.Sets/src/mage/cards/b/Browbeat.java b/Mage.Sets/src/mage/cards/b/Browbeat.java
index 4bc1a4a7e57..7c06058b9b7 100644
--- a/Mage.Sets/src/mage/cards/b/Browbeat.java
+++ b/Mage.Sets/src/mage/cards/b/Browbeat.java
@@ -23,7 +23,7 @@ public final class Browbeat extends CardImpl {
public Browbeat(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}");
- // Any player may have Browbeat deal 5 damage to him or her. If no one does, target player draws three cards.
+ // Any player may have Browbeat deal 5 damage to them. If no one does, target player draws three cards.
this.getSpellAbility().addEffect(new BrowbeatDrawEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
}
@@ -42,7 +42,7 @@ class BrowbeatDrawEffect extends OneShotEffect {
public BrowbeatDrawEffect() {
super(Outcome.DrawCard);
- staticText = "Any player may have {source} deal 5 damage to him or her. If no one does, target player draws three cards.";
+ staticText = "Any player may have {source} deal 5 damage to them. If no one does, target player draws three cards.";
}
public BrowbeatDrawEffect(final BrowbeatDrawEffect effect) {
@@ -73,7 +73,7 @@ class BrowbeatDrawEffect extends OneShotEffect {
if (player != null && player.chooseUse(Outcome.Detriment, "Have " + spell.getLogName() + " deal 5 damage to you?", source, game)) {
drawCards = false;
player.damage(5, source.getSourceId(), game, false, true);
- game.informPlayers(player.getLogName() + " has " + spell.getLogName() + " deal 5 to him or her");
+ game.informPlayers(player.getLogName() + " has " + spell.getLogName() + " deal 5 to them");
}
}
if (drawCards) {
diff --git a/Mage.Sets/src/mage/cards/b/BubbleMatrix.java b/Mage.Sets/src/mage/cards/b/BubbleMatrix.java
index 625af565777..3fe59d7157c 100644
--- a/Mage.Sets/src/mage/cards/b/BubbleMatrix.java
+++ b/Mage.Sets/src/mage/cards/b/BubbleMatrix.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.PreventAllDamageToAllEffect;
import mage.cards.CardImpl;
@@ -9,10 +7,11 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
-import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES;
+import mage.filter.StaticFilters;
+
+import java.util.UUID;
/**
- *
* @author LoneFox
*/
public final class BubbleMatrix extends CardImpl {
@@ -21,7 +20,7 @@ public final class BubbleMatrix extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
// Prevent all damage that would be dealt to creatures.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventAllDamageToAllEffect(Duration.WhileOnBattlefield, FILTER_PERMANENT_CREATURES)));
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventAllDamageToAllEffect(Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES)));
}
public BubbleMatrix(final BubbleMatrix card) {
diff --git a/Mage.Sets/src/mage/cards/b/BuildersBane.java b/Mage.Sets/src/mage/cards/b/BuildersBane.java
index 7ee8821d2e8..37e26184218 100644
--- a/Mage.Sets/src/mage/cards/b/BuildersBane.java
+++ b/Mage.Sets/src/mage/cards/b/BuildersBane.java
@@ -26,7 +26,7 @@ public final class BuildersBane extends CardImpl {
public BuildersBane(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{X}{R}");
- // Destroy X target artifacts. Builder's Bane deals damage to each player equal to the number of artifacts he or she controlled put into a graveyard this way.
+ // Destroy X target artifacts. Builder's Bane deals damage to each player equal to the number of artifacts they controlled put into a graveyard this way.
this.getSpellAbility().addTarget(new TargetArtifactPermanent());
this.getSpellAbility().addEffect(new BuildersBaneEffect());
this.getSpellAbility().setTargetAdjuster(BuildersBaneAdjuster.instance);
@@ -89,7 +89,7 @@ class BuildersBaneEffect extends OneShotEffect {
}
}
- // Builder's Bane deals damage to each player equal to the number of artifacts he or she controlled put into a graveyard this way.
+ // Builder's Bane deals damage to each player equal to the number of artifacts they controlled put into a graveyard this way.
for (Map.Entry entry : destroyedArtifactPerPlayer.entrySet()) {
Player player = game.getPlayer(entry.getKey());
if (player != null) {
diff --git a/Mage.Sets/src/mage/cards/b/BurdenOfGreed.java b/Mage.Sets/src/mage/cards/b/BurdenOfGreed.java
index 2f8ad795d0c..f9d161522e0 100644
--- a/Mage.Sets/src/mage/cards/b/BurdenOfGreed.java
+++ b/Mage.Sets/src/mage/cards/b/BurdenOfGreed.java
@@ -24,7 +24,7 @@ public final class BurdenOfGreed extends CardImpl {
public BurdenOfGreed(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{B}");
- // Target player loses 1 life for each tapped artifact he or she controls.
+ // Target player loses 1 life for each tapped artifact they control.
getSpellAbility().addTarget(new TargetPlayer());
getSpellAbility().addEffect(new LoseLifeTargetEffect(new BurdenOfGreedCount()));
@@ -65,7 +65,7 @@ class BurdenOfGreedCount implements DynamicValue {
@Override
public String getMessage() {
- return "tapped artifact he or she controls";
+ return "tapped artifact they control";
}
}
diff --git a/Mage.Sets/src/mage/cards/b/Burgeoning.java b/Mage.Sets/src/mage/cards/b/Burgeoning.java
index e273d6e3623..c907a81828e 100644
--- a/Mage.Sets/src/mage/cards/b/Burgeoning.java
+++ b/Mage.Sets/src/mage/cards/b/Burgeoning.java
@@ -1,7 +1,5 @@
-
package mage.cards.b;
-import java.util.UUID;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect;
import mage.cards.CardImpl;
@@ -14,6 +12,8 @@ import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
+import java.util.UUID;
+
/**
* @author duncant
*/
@@ -54,7 +54,7 @@ class BurgeoningTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent land = game.getPermanent(event.getTargetId());
- return game.getOpponents(controllerId).contains(land.getControllerId());
+ return land != null && game.getOpponents(controllerId).contains(land.getControllerId());
}
@Override
diff --git a/Mage.Sets/src/mage/cards/b/BuriedAlive.java b/Mage.Sets/src/mage/cards/b/BuriedAlive.java
index ca43d181920..7b8e350a627 100644
--- a/Mage.Sets/src/mage/cards/b/BuriedAlive.java
+++ b/Mage.Sets/src/mage/cards/b/BuriedAlive.java
@@ -1,4 +1,3 @@
-
package mage.cards.b;
import java.util.UUID;
@@ -10,7 +9,7 @@ import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
@@ -21,14 +20,12 @@ import mage.target.common.TargetCardInLibrary;
*/
public final class BuriedAlive extends CardImpl {
-
public BuriedAlive(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}");
// Search your library for up to three creature cards and put them into your graveyard. Then shuffle your library.
- this.getSpellAbility().addEffect(new BuriedAliveEffect());
-
+ this.getSpellAbility().addEffect(new BuriedAliveEffect());
+
}
public BuriedAlive(final BuriedAlive card) {
@@ -43,8 +40,8 @@ public final class BuriedAlive extends CardImpl {
class BuriedAliveEffect extends SearchEffect {
- public BuriedAliveEffect() {
- super(new TargetCardInLibrary(0, 3, new FilterCreatureCard()), Outcome.Detriment);
+ public BuriedAliveEffect() {
+ super(new TargetCardInLibrary(0, 3, StaticFilters.FILTER_CARD_CREATURE), Outcome.Detriment);
staticText = "Search your library for up to three creature cards and put them into your graveyard. Then shuffle your library";
}
@@ -69,5 +66,5 @@ class BuriedAliveEffect extends SearchEffect {
}
return false;
}
-
+
}
diff --git a/Mage.Sets/src/mage/cards/b/BurningOfXinye.java b/Mage.Sets/src/mage/cards/b/BurningOfXinye.java
index 16a159d914d..de7ea301886 100644
--- a/Mage.Sets/src/mage/cards/b/BurningOfXinye.java
+++ b/Mage.Sets/src/mage/cards/b/BurningOfXinye.java
@@ -28,7 +28,7 @@ public final class BurningOfXinye extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{R}{R}");
- // You destroy four lands you control, then target opponent destroys four lands he or she controls. Then Burning of Xinye deals 4 damage to each creature.
+ // You destroy four lands you control, then target opponent destroys four lands they control. Then Burning of Xinye deals 4 damage to each creature.
this.getSpellAbility().addTarget(new TargetOpponent());
this.getSpellAbility().addEffect(new BurningOfXinyeEffect());
this.getSpellAbility().addEffect(new DamageAllEffect(4, new FilterCreaturePermanent()));
@@ -51,7 +51,7 @@ class BurningOfXinyeEffect extends OneShotEffect{
public BurningOfXinyeEffect() {
super(Outcome.DestroyPermanent);
- staticText = "You destroy four lands you control, then target opponent destroys four lands he or she controls";
+ staticText = "You destroy four lands you control, then target opponent destroys four lands they control";
}
public BurningOfXinyeEffect ( BurningOfXinyeEffect effect ) {
diff --git a/Mage.Sets/src/mage/cards/b/BurningYardTrainer.java b/Mage.Sets/src/mage/cards/b/BurningYardTrainer.java
new file mode 100644
index 00000000000..3d37d2b461d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BurningYardTrainer.java
@@ -0,0 +1,70 @@
+package mage.cards.b;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.keyword.HasteAbility;
+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.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class BurningYardTrainer extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledPermanent(SubType.KNIGHT);
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ }
+
+ public BurningYardTrainer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Trample
+ this.addAbility(TrampleAbility.getInstance());
+
+ // Haste
+ this.addAbility(HasteAbility.getInstance());
+
+ // When Burning-Yard Trainer enters the battlefield, another target Knight you control gets +2/+2 and gains trample and haste until end of turn.
+ Ability ability = new EntersBattlefieldTriggeredAbility(
+ new BoostTargetEffect(2, 2, Duration.EndOfTurn)
+ .setText("another target Knight you control gets +2/+2")
+ );
+ ability.addEffect(new GainAbilityTargetEffect(
+ TrampleAbility.getInstance(), Duration.EndOfTurn
+ ).setText("and gains trample"));
+ ability.addEffect(new GainAbilityTargetEffect(
+ HasteAbility.getInstance(), Duration.EndOfTurn
+ ).setText("and haste until end of turn"));
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(ability);
+ }
+
+ private BurningYardTrainer(final BurningYardTrainer card) {
+ super(card);
+ }
+
+ @Override
+ public BurningYardTrainer copy() {
+ return new BurningYardTrainer(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/b/ButcherOrgg.java b/Mage.Sets/src/mage/cards/b/ButcherOrgg.java
index ef3fffe5ccc..4dd837db151 100644
--- a/Mage.Sets/src/mage/cards/b/ButcherOrgg.java
+++ b/Mage.Sets/src/mage/cards/b/ButcherOrgg.java
@@ -22,7 +22,7 @@ public final class ButcherOrgg extends CardImpl {
this.power = new MageInt(6);
this.toughness = new MageInt(6);
- // You may assign Butcher Orgg's combat damage divided as you choose among defending player and/or any number of creatures he or she controls.
+ // You may assign Butcher Orgg's combat damage divided as you choose among defending player and/or any number of creatures they control.
this.addAbility(ControllerDivideCombatDamageAbility.getInstance());
}
diff --git a/Mage.Sets/src/mage/cards/c/CacklingFlames.java b/Mage.Sets/src/mage/cards/c/CacklingFlames.java
index 5c7ba05fa38..0bf4c194f62 100644
--- a/Mage.Sets/src/mage/cards/c/CacklingFlames.java
+++ b/Mage.Sets/src/mage/cards/c/CacklingFlames.java
@@ -1,8 +1,5 @@
-
package mage.cards.c;
-import java.util.UUID;
-import mage.abilities.condition.InvertCondition;
import mage.abilities.condition.common.HellbentCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
@@ -11,8 +8,9 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetAnyTarget;
+import java.util.UUID;
+
/**
- *
* @author JotaPeRL
*/
public final class CacklingFlames extends CardImpl {
@@ -21,16 +19,12 @@ public final class CacklingFlames extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R}");
// Cackling Flames deals 3 damage to any target.
- this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
- new DamageTargetEffect(3),
- new InvertCondition(HellbentCondition.instance),
- "{this} deals 3 damage to any target"));
// Hellbent - Cackling Flames deals 5 damage to that creature or player instead if you have no cards in hand.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
- new DamageTargetEffect(5),
- HellbentCondition.instance,
- "
Hellbent — {this} deals 5 damage to that permanent or player instead if you have no cards in hand."));
-
+ new DamageTargetEffect(5), new DamageTargetEffect(3), HellbentCondition.instance,
+ "{this} deals 3 damage to any target
Hellbent " +
+ "— {this} deals 5 damage instead if you have no cards in hand."
+ ));
this.getSpellAbility().addTarget(new TargetAnyTarget());
}
diff --git a/Mage.Sets/src/mage/cards/c/CalculatingLich.java b/Mage.Sets/src/mage/cards/c/CalculatingLich.java
new file mode 100644
index 00000000000..d003b57b959
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CalculatingLich.java
@@ -0,0 +1,85 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.effects.common.LoseLifeTargetEffect;
+import mage.abilities.keyword.MenaceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.players.Player;
+import mage.target.targetpointer.FixedTarget;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CalculatingLich extends CardImpl {
+
+ public CalculatingLich(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}");
+
+ this.subtype.add(SubType.ZOMBIE);
+ this.subtype.add(SubType.WIZARD);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(5);
+
+ // Menace
+ this.addAbility(new MenaceAbility());
+
+ // Whenever a creature attacks one of your opponents, that player loses 1 life.
+ this.addAbility(new CalculatingLichTriggeredAbility());
+ }
+
+ private CalculatingLich(final CalculatingLich card) {
+ super(card);
+ }
+
+ @Override
+ public CalculatingLich copy() {
+ return new CalculatingLich(this);
+ }
+}
+
+class CalculatingLichTriggeredAbility extends TriggeredAbilityImpl {
+
+ CalculatingLichTriggeredAbility() {
+ super(Zone.BATTLEFIELD, null, false);
+ }
+
+ private CalculatingLichTriggeredAbility(final CalculatingLichTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ Player player = game.getPlayer(getControllerId());
+ UUID defenderId = game.getCombat().getDefenderId(event.getSourceId());
+ if (player == null || !player.hasOpponent(defenderId, game)) {
+ return false;
+ }
+ getEffects().clear();
+ addEffect(new LoseLifeTargetEffect(1).setTargetPointer(new FixedTarget(defenderId, game)));
+ return true;
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever a creature attacks one of your opponents, that player loses 1 life.";
+ }
+
+ @Override
+ public CalculatingLichTriggeredAbility copy() {
+ return new CalculatingLichTriggeredAbility(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java b/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java
index b95405da59a..02dacbe4611 100644
--- a/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java
+++ b/Mage.Sets/src/mage/cards/c/CallerOfTheHunt.java
@@ -1,28 +1,27 @@
-
package mage.cards.c;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.CostAdjuster;
-import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
-import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.InfoEffect;
-import mage.abilities.effects.common.continuous.SetPowerSourceEffect;
-import mage.abilities.effects.common.continuous.SetToughnessSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceCreatureType;
import mage.constants.*;
-import mage.filter.FilterPermanent;
-import mage.filter.predicate.mageobject.ChosenSubtypePredicate;
import mage.game.Game;
import mage.players.Player;
-
import java.util.UUID;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.target.targetpointer.FixedTarget;
/**
* @author jeffwadsworth
@@ -38,7 +37,9 @@ public final class CallerOfTheHunt extends CardImpl {
// Caller of the Hunt's power and toughness are each equal to the number of creatures of the chosen type on the battlefield.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("as an additional cost to cast this spell, choose a creature type. \r"
+ "{this}'s power and toughness are each equal to the number of creatures of the chosen type on the battlefield")));
+
this.getSpellAbility().setCostAdjuster(CallerOfTheHuntAdjuster.instance);
+
}
public CallerOfTheHunt(final CallerOfTheHunt card) {
@@ -58,19 +59,27 @@ enum CallerOfTheHuntAdjuster implements CostAdjuster {
public void adjustCosts(Ability ability, Game game) {
MageObject mageObject = game.getObject(ability.getSourceId());
Effect effect = new ChooseCreatureTypeEffect(Outcome.Benefit);
- if (mageObject != null
- && effect.apply(game, ability)) {
- FilterPermanent filter = new FilterPermanent();
- filter.add(ChosenSubtypePredicate.instance);
- ContinuousEffect effectPower = new SetPowerSourceEffect(new PermanentsOnBattlefieldCount(filter), Duration.Custom);
- ContinuousEffect effectToughness = new SetToughnessSourceEffect(new PermanentsOnBattlefieldCount(filter), Duration.Custom);
- game.addEffect(effectPower, ability);
- game.addEffect(effectToughness, ability);
+ if (mageObject != null) {
+ effect.apply(game, ability);
+ }
+ if (mageObject != null) {
+ SubType typeChoice = (SubType) game.getState().getValue(mageObject.getId() + "_type");
+ if (typeChoice != null) {
+ FilterCreaturePermanent filter = new FilterCreaturePermanent("chosen creature type");
+ filter.add(new SubtypePredicate(typeChoice));
+ ContinuousEffect effectPowerToughness = new SetPowerToughnessSourceEffect(
+ new PermanentsOnBattlefieldCount(filter), Duration.EndOfGame);
+ effectPowerToughness.setText("");
+ SimpleStaticAbility setPT = new SimpleStaticAbility(Zone.ALL, effectPowerToughness);
+ GainAbilityTargetEffect gainAbility = new GainAbilityTargetEffect(setPT, Duration.EndOfGame);
+ gainAbility.setTargetPointer(new FixedTarget(ability.getSourceId()));
+ game.getState().addEffect(gainAbility, ability);
+ }
}
}
}
-class ChooseCreatureTypeEffect extends OneShotEffect { // code by LevelX2, but that other version is not compatible with this card
+class ChooseCreatureTypeEffect extends OneShotEffect {
public ChooseCreatureTypeEffect(Outcome outcome) {
super(outcome);
@@ -86,11 +95,15 @@ class ChooseCreatureTypeEffect extends OneShotEffect { // code by LevelX2, but t
Player controller = game.getPlayer(source.getControllerId());
MageObject mageObject = game.getObject(source.getSourceId());
Choice typeChoice = new ChoiceCreatureType(mageObject);
- if (controller != null && mageObject != null && controller.choose(outcome, typeChoice, game)) {
+ if (controller != null
+ && mageObject != null
+ && controller.choose(outcome, typeChoice, game)) {
if (!game.isSimulation()) {
- game.informPlayers(mageObject.getName() + ": " + controller.getLogName() + " has chosen " + typeChoice.getChoice());
+ game.informPlayers(mageObject.getName() + ": "
+ + controller.getLogName() + " has chosen " + typeChoice.getChoice());
}
- game.getState().setValue(mageObject.getId() + "_type", SubType.byDescription(typeChoice.getChoice()));
+ game.getState().setValue(mageObject.getId()
+ + "_type", SubType.byDescription(typeChoice.getChoice()));
return true;
}
return false;
diff --git a/Mage.Sets/src/mage/cards/c/CallerOfThePack.java b/Mage.Sets/src/mage/cards/c/CallerOfThePack.java
index 4d6c7acf853..8dd07e62f03 100644
--- a/Mage.Sets/src/mage/cards/c/CallerOfThePack.java
+++ b/Mage.Sets/src/mage/cards/c/CallerOfThePack.java
@@ -25,7 +25,7 @@ public final class CallerOfThePack extends CardImpl {
// Trample
this.addAbility(TrampleAbility.getInstance());
- // Myriad (Whenever this creature attacks, for each opponent other than the defending player, create a token that's a copy of this creature tapped and attacking that player or a planeswalker he or she controls. Exile those tokens at the end of combat.)
+ // Myriad (Whenever this creature attacks, for each opponent other than the defending player, create a token that's a copy of this creature tapped and attacking that player or a planeswalker they control. Exile those tokens at the end of combat.)
this.addAbility(new MyriadAbility());
}
diff --git a/Mage.Sets/src/mage/cards/c/Camouflage.java b/Mage.Sets/src/mage/cards/c/Camouflage.java
index ed8719b8c2f..4ece48153b2 100644
--- a/Mage.Sets/src/mage/cards/c/Camouflage.java
+++ b/Mage.Sets/src/mage/cards/c/Camouflage.java
@@ -41,7 +41,7 @@ public final class Camouflage extends CardImpl {
// Cast Camouflage only during your declare attackers step.
this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(null, PhaseStep.DECLARE_ATTACKERS, MyTurnCondition.instance, "Cast this spell only during your declare attackers step"));
- // This turn, instead of declaring blockers, each defending player chooses any number of creatures he or she controls and divides them into a number of piles equal to the number of attacking creatures for whom that player is the defending player. Creatures he or she controls that can block additional creatures may likewise be put into additional piles. Assign each pile to a different one of those attacking creatures at random. Each creature in a pile that can block the creature that pile is assigned to does so. (Piles can be empty.)
+ // This turn, instead of declaring blockers, each defending player chooses any number of creatures they control and divides them into a number of piles equal to the number of attacking creatures for whom that player is the defending player. Creatures they control that can block additional creatures may likewise be put into additional piles. Assign each pile to a different one of those attacking creatures at random. Each creature in a pile that can block the creature that pile is assigned to does so. (Piles can be empty.)
this.getSpellAbility().addEffect(new CamouflageEffect());
}
@@ -59,7 +59,7 @@ class CamouflageEffect extends ContinuousRuleModifyingEffectImpl {
public CamouflageEffect() {
super(Duration.EndOfTurn, Outcome.Benefit, false, false);
- staticText = "This turn, instead of declaring blockers, each defending player chooses any number of creatures he or she controls and divides them into a number of piles equal to the number of attacking creatures for whom that player is the defending player. Creatures he or she controls that can block additional creatures may likewise be put into additional piles. Assign each pile to a different one of those attacking creatures at random. Each creature in a pile that can block the creature that pile is assigned to does so";
+ staticText = "This turn, instead of declaring blockers, each defending player chooses any number of creatures they control and divides them into a number of piles equal to the number of attacking creatures for whom that player is the defending player. Creatures they control that can block additional creatures may likewise be put into additional piles. Assign each pile to a different one of those attacking creatures at random. Each creature in a pile that can block the creature that pile is assigned to does so";
}
public CamouflageEffect(final CamouflageEffect effect) {
@@ -81,7 +81,7 @@ class CamouflageEffect extends ContinuousRuleModifyingEffectImpl {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Map>> masterMap = new HashMap<>();
- // Each defending player chooses any number of creatures he or she controls
+ // Each defending player chooses any number of creatures they control
// and divides them into a number of piles equal to the number of attacking creatures for whom that player is the defending player (piles can be empty)
for (UUID defenderId : game.getCombat().getPlayerDefenders(game)) {
Player defender = game.getPlayer(defenderId);
@@ -104,7 +104,7 @@ class CamouflageEffect extends ContinuousRuleModifyingEffectImpl {
if (!declinedChoice) {
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creatures you control not yet assigned to a pile");
for (List list : masterList) {
- // Creatures he or she controls that can block additional creatures may likewise be put into additional piles.
+ // Creatures they control that can block additional creatures may likewise be put into additional piles.
// (This temporarily manipulates Blocking values to "test" how many blockers the creature has still left to assign)
List spentBlockers = new ArrayList<>();
for (Permanent possibleBlocker : list) {
diff --git a/Mage.Sets/src/mage/cards/c/CandlesGlow.java b/Mage.Sets/src/mage/cards/c/CandlesGlow.java
index 7bf8e711e24..8c9d5388e70 100644
--- a/Mage.Sets/src/mage/cards/c/CandlesGlow.java
+++ b/Mage.Sets/src/mage/cards/c/CandlesGlow.java
@@ -1,4 +1,3 @@
-
package mage.cards.c;
import mage.abilities.Ability;
@@ -10,20 +9,21 @@ 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.players.Player;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class CandlesGlow extends CardImpl {
public CandlesGlow(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");
this.subtype.add(SubType.ARCANE);
@@ -70,7 +70,7 @@ class CandlesGlowPreventDamageTargetEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int prevented;
if (event.getAmount() >= this.amount) {
@@ -103,9 +103,7 @@ class CandlesGlowPreventDamageTargetEffect extends PreventionEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!this.used && super.applies(event, source, game)) {
- if (source.getTargets().getFirstTarget().equals(event.getTargetId())) {
- return true;
- }
+ return source.getTargets().getFirstTarget().equals(event.getTargetId());
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/c/CankerousThirst.java b/Mage.Sets/src/mage/cards/c/CankerousThirst.java
index 724a37456d5..05315140512 100644
--- a/Mage.Sets/src/mage/cards/c/CankerousThirst.java
+++ b/Mage.Sets/src/mage/cards/c/CankerousThirst.java
@@ -54,7 +54,7 @@ class CankerousThirstEffect extends OneShotEffect {
public CankerousThirstEffect() {
super(Outcome.Benefit);
- this.staticText = "If {B} was spent to cast {this}, you may have target creature get -3/-3 until end of turn. If {G} was spent to cast {this}, you may have target creature get +3/+3 until end of turn";
+ this.staticText = "If {B} was spent to cast {this}, you may have target creature get -3/-3 until end of turn. If {G} was spent to cast this spell, you may have target creature get +3/+3 until end of turn";
}
public CankerousThirstEffect(final CankerousThirstEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/CastleArdenvale.java b/Mage.Sets/src/mage/cards/c/CastleArdenvale.java
new file mode 100644
index 00000000000..6e15956b763
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CastleArdenvale.java
@@ -0,0 +1,61 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.TapSourceEffect;
+import mage.abilities.mana.WhiteManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.game.permanent.token.HumanToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CastleArdenvale extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledPermanent(SubType.PLAINS);
+ private static final Condition condition
+ = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.EQUAL_TO, 0);
+
+ public CastleArdenvale(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ // Castle Ardenvale enters the battlefield tapped unless you control a Plains.
+ this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(
+ new TapSourceEffect(), condition
+ ), "tapped unless you control a Plains"));
+
+ // {T}: Add {W}.
+ this.addAbility(new WhiteManaAbility());
+
+ // {2}{W}{W}, {T}: Create a 1/1 white Human creature token.
+ Ability ability = new SimpleActivatedAbility(
+ new CreateTokenEffect(new HumanToken()), new ManaCostsImpl("{2}{W}{W}")
+ );
+ ability.addCost(new TapSourceCost());
+ this.addAbility(ability);
+ }
+
+ private CastleArdenvale(final CastleArdenvale card) {
+ super(card);
+ }
+
+ @Override
+ public CastleArdenvale copy() {
+ return new CastleArdenvale(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CastleEmbereth.java b/Mage.Sets/src/mage/cards/c/CastleEmbereth.java
new file mode 100644
index 00000000000..2b4f10aea81
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CastleEmbereth.java
@@ -0,0 +1,61 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.TapSourceEffect;
+import mage.abilities.effects.common.continuous.BoostControlledEffect;
+import mage.abilities.mana.RedManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CastleEmbereth extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledPermanent(SubType.MOUNTAIN);
+ private static final Condition condition
+ = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.EQUAL_TO, 0);
+
+ public CastleEmbereth(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ // Castle Embereth enters the battlefield tapped unless you control a Mountain.
+ this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(
+ new TapSourceEffect(), condition
+ ), "tapped unless you control a Mountain"));
+
+ // {T}: Add {R}.
+ this.addAbility(new RedManaAbility());
+
+ // {1}{R}{R}, {T}: Creatures you control get +1/+0 until end of turn.
+ Ability ability = new SimpleActivatedAbility(
+ new BoostControlledEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl("{1}{R}{R}")
+ );
+ ability.addCost(new TapSourceCost());
+ this.addAbility(ability);
+ }
+
+ private CastleEmbereth(final CastleEmbereth card) {
+ super(card);
+ }
+
+ @Override
+ public CastleEmbereth copy() {
+ return new CastleEmbereth(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CastleGarenbrig.java b/Mage.Sets/src/mage/cards/c/CastleGarenbrig.java
new file mode 100644
index 00000000000..4e79fc9239b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CastleGarenbrig.java
@@ -0,0 +1,99 @@
+package mage.cards.c;
+
+import mage.ConditionalMana;
+import mage.MageObject;
+import mage.Mana;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.TapSourceEffect;
+import mage.abilities.mana.ConditionalColoredManaAbility;
+import mage.abilities.mana.GreenManaAbility;
+import mage.abilities.mana.builder.ConditionalManaBuilder;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.game.Game;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CastleGarenbrig extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledPermanent(SubType.FOREST);
+ private static final Condition condition
+ = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.EQUAL_TO, 0);
+
+ public CastleGarenbrig(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ // Castle Garenbrig enters the battlefield tapped unless you control a Forest.
+ this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(
+ new TapSourceEffect(), condition
+ ), "tapped unless you control a Forest"));
+
+ // {T}: Add {G}.
+ this.addAbility(new GreenManaAbility());
+
+ // {2}{G}{G}, {T}: Add six {G}. Spend this mana only to cast creature spells or activate abilities of creatures.
+ Ability ability = new ConditionalColoredManaAbility(
+ new ManaCostsImpl("{2}{G}{G}"), Mana.GreenMana(6), new CastleGarenbrigManaBuilder()
+ );
+ ability.addCost(new TapSourceCost());
+ this.addAbility(ability);
+ }
+
+ private CastleGarenbrig(final CastleGarenbrig card) {
+ super(card);
+ }
+
+ @Override
+ public CastleGarenbrig copy() {
+ return new CastleGarenbrig(this);
+ }
+}
+
+class CastleGarenbrigManaBuilder extends ConditionalManaBuilder {
+
+ @Override
+ public ConditionalMana build(Object... options) {
+ return new CastleGarenbrigConditionalMana(this.mana);
+ }
+
+ @Override
+ public String getRule() {
+ return "Spend this mana only to cast creature spells or activate abilities of creatures";
+ }
+}
+
+class CastleGarenbrigConditionalMana extends ConditionalMana {
+
+ CastleGarenbrigConditionalMana(Mana mana) {
+ super(mana);
+ this.staticText = "Spend this mana only to cast creature spells or activate abilities of creatures";
+ addCondition(CastleGarenbrigManaCondition.instance);
+ }
+}
+
+enum CastleGarenbrigManaCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ MageObject object = game.getObject(source.getSourceId());
+ if (object != null && object.isCreature()) {
+ return true;
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/c/CastleLocthwain.java b/Mage.Sets/src/mage/cards/c/CastleLocthwain.java
new file mode 100644
index 00000000000..06aa17106c1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CastleLocthwain.java
@@ -0,0 +1,64 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.dynamicvalue.common.CardsInControllerHandCount;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
+import mage.abilities.effects.common.TapSourceEffect;
+import mage.abilities.mana.BlackManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CastleLocthwain extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledPermanent(SubType.SWAMP);
+ private static final Condition condition
+ = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.EQUAL_TO, 0);
+
+ public CastleLocthwain(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ // Castle Locthwain enters the battlefield tapped unless you control a Swamp.
+ this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(
+ new TapSourceEffect(), condition
+ ), "tapped unless you control a Swamp"));
+
+ // {T}: Add {B}.
+ this.addAbility(new BlackManaAbility());
+
+ // {1}{B}{B}, {T}: Draw a card, then you lose life equal to the number of cards in your hand.
+ Ability ability = new SimpleActivatedAbility(
+ new DrawCardSourceControllerEffect(1).setText("draw a card,"), new ManaCostsImpl("{1}{B}{B}")
+ );
+ ability.addEffect(new LoseLifeSourceControllerEffect(CardsInControllerHandCount.instance)
+ .setText("then you lose life equal to the number of cards in your hand"));
+ ability.addCost(new TapSourceCost());
+ this.addAbility(ability);
+ }
+
+ private CastleLocthwain(final CastleLocthwain card) {
+ super(card);
+ }
+
+ @Override
+ public CastleLocthwain copy() {
+ return new CastleLocthwain(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CastleVantress.java b/Mage.Sets/src/mage/cards/c/CastleVantress.java
new file mode 100644
index 00000000000..9e73d7a217a
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CastleVantress.java
@@ -0,0 +1,58 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.TapSourceEffect;
+import mage.abilities.effects.keyword.ScryEffect;
+import mage.abilities.mana.BlueManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CastleVantress extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledPermanent(SubType.ISLAND);
+ private static final Condition condition
+ = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.EQUAL_TO, 0);
+
+ public CastleVantress(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ // Castle Vantress enters the battlefield tapped unless you control an Island.
+ this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(
+ new TapSourceEffect(), condition
+ ), "tapped unless you control an Island"));
+
+ // {T}: Add {U}.
+ this.addAbility(new BlueManaAbility());
+
+ // {2}{U}{U}, {T}: Scry 2.
+ Ability ability = new SimpleActivatedAbility(new ScryEffect(2), new ManaCostsImpl("{2}{U}{U}"));
+ ability.addCost(new TapSourceCost());
+ this.addAbility(ability);
+ }
+
+ private CastleVantress(final CastleVantress card) {
+ super(card);
+ }
+
+ @Override
+ public CastleVantress copy() {
+ return new CastleVantress(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/Cataclysm.java b/Mage.Sets/src/mage/cards/c/Cataclysm.java
index f4241f224ac..979b3055af8 100644
--- a/Mage.Sets/src/mage/cards/c/Cataclysm.java
+++ b/Mage.Sets/src/mage/cards/c/Cataclysm.java
@@ -30,7 +30,7 @@ public final class Cataclysm extends CardImpl {
public Cataclysm(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{W}{W}");
- // Each player chooses from the permanents he or she controls an artifact, a creature, an enchantment, and a land, then sacrifices the rest.
+ // Each player chooses from the permanents they control an artifact, a creature, an enchantment, and a land, then sacrifices the rest.
this.getSpellAbility().addEffect(new CataclysmEffect());
}
@@ -48,7 +48,7 @@ class CataclysmEffect extends OneShotEffect {
public CataclysmEffect() {
super(Outcome.DestroyPermanent);
- staticText = "Each player chooses from among the permanents he or she controls an artifact, a creature, an enchantment, and a land, then sacrifices the rest";
+ staticText = "Each player chooses from among the permanents they control an artifact, a creature, an enchantment, and a land, then sacrifices the rest";
}
public CataclysmEffect(CataclysmEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/CataclysmicGearhulk.java b/Mage.Sets/src/mage/cards/c/CataclysmicGearhulk.java
index e4bd95579a0..0a1669bf3d6 100644
--- a/Mage.Sets/src/mage/cards/c/CataclysmicGearhulk.java
+++ b/Mage.Sets/src/mage/cards/c/CataclysmicGearhulk.java
@@ -42,7 +42,7 @@ public final class CataclysmicGearhulk extends CardImpl {
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
- // When Cataclysmic Gearhulk enters the battlefield, each player chooses from among the non-land permanents he or she controls an artifact, a creature,
+ // When Cataclysmic Gearhulk enters the battlefield, each player chooses from among the non-land permanents they control an artifact, a creature,
// an enchantment, and a planeswalker, then sacrifices the rest.
this.addAbility(new EntersBattlefieldTriggeredAbility(new CataclysmicGearhulkEffect(), false));
}
@@ -81,7 +81,7 @@ class CataclysmicGearhulkEffect extends OneShotEffect {
public CataclysmicGearhulkEffect() {
super(Outcome.DestroyPermanent);
- staticText = "Each player chooses from among the non-land permanents he or she controls an artifact, a creature, an enchantment, and a planeswalker, "
+ staticText = "Each player chooses from among the non-land permanents they control an artifact, a creature, an enchantment, and a planeswalker, "
+ "then sacrifices the rest";
}
diff --git a/Mage.Sets/src/mage/cards/c/CauldronDance.java b/Mage.Sets/src/mage/cards/c/CauldronDance.java
index 3931ee4511a..5bf9e334e31 100644
--- a/Mage.Sets/src/mage/cards/c/CauldronDance.java
+++ b/Mage.Sets/src/mage/cards/c/CauldronDance.java
@@ -1,4 +1,3 @@
-
package mage.cards.c;
import java.util.UUID;
@@ -17,7 +16,6 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -120,7 +118,7 @@ class CauldronDancePutCreatureFromHandOntoBattlefieldEffect extends OneShotEffec
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
if (controller.chooseUse(Outcome.PutCreatureInPlay, CHOICE_TEXT, source, game)) {
- TargetCardInHand target = new TargetCardInHand(new FilterCreatureCard());
+ TargetCardInHand target = new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE);
if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
diff --git a/Mage.Sets/src/mage/cards/c/CauldronFamiliar.java b/Mage.Sets/src/mage/cards/c/CauldronFamiliar.java
new file mode 100644
index 00000000000..f9ba1ce582d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CauldronFamiliar.java
@@ -0,0 +1,55 @@
+package mage.cards.c;
+
+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.effects.common.GainLifeEffect;
+import mage.abilities.effects.common.LoseLifeOpponentsEffect;
+import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.common.FilterControlledPermanent;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CauldronFamiliar extends CardImpl {
+
+ private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.FOOD, "a Food");
+
+ public CauldronFamiliar(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}");
+
+ this.subtype.add(SubType.CAT);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // When Cauldron Familiar enters the battlefield, each opponent loses 1 life and you gain 1 life.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeOpponentsEffect(1));
+ ability.addEffect(new GainLifeEffect(1).concatBy("and"));
+ this.addAbility(ability);
+
+ // Sacrifice a Food: Return Cauldron Familiar from your graveyard to the battlefield.
+ this.addAbility(new SimpleActivatedAbility(
+ Zone.GRAVEYARD, new ReturnSourceFromGraveyardToBattlefieldEffect(),
+ new SacrificeTargetCost(new TargetControlledPermanent(filter))
+ ));
+ }
+
+ private CauldronFamiliar(final CauldronFamiliar card) {
+ super(card);
+ }
+
+ @Override
+ public CauldronFamiliar copy() {
+ return new CauldronFamiliar(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CauldronsGift.java b/Mage.Sets/src/mage/cards/c/CauldronsGift.java
new file mode 100644
index 00000000000..923e9568a8d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CauldronsGift.java
@@ -0,0 +1,92 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.condition.common.AdamantCondition;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.TargetCard;
+import mage.target.common.TargetCardInYourGraveyard;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CauldronsGift extends CardImpl {
+
+ public CauldronsGift(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}");
+
+ // Adamant — If at least three black mana was spent to cast this spell, put the top four cards of your library into your graveyard.
+ // You may choose a creature card in your graveyard. If you do, return it to the battlefield with an additional +1/+1 counter on it.
+ this.getSpellAbility().addEffect(new CauldronsGiftEffect());
+ }
+
+ private CauldronsGift(final CauldronsGift card) {
+ super(card);
+ }
+
+ @Override
+ public CauldronsGift copy() {
+ return new CauldronsGift(this);
+ }
+}
+
+class CauldronsGiftEffect extends OneShotEffect {
+
+ CauldronsGiftEffect() {
+ super(Outcome.Benefit);
+ staticText = "Adamant — If at least three black mana was spent to cast this spell, " +
+ "put the top four cards of your library into your graveyard." +
+ "
You may choose a creature card in your graveyard. " +
+ "If you do, return it to the battlefield with an additional +1/+1 counter on it.";
+ }
+
+ private CauldronsGiftEffect(final CauldronsGiftEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CauldronsGiftEffect copy() {
+ return new CauldronsGiftEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ if (AdamantCondition.BLACK.apply(game, source)) {
+ player.moveCards(player.getLibrary().getTopCards(game, 4), Zone.GRAVEYARD, source, game);
+ }
+ if (player.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game) == 0
+ || !player.chooseUse(outcome, "Choose a creature card in your graveyard to return to the battlefield?", source, game)) {
+ return true;
+ }
+ TargetCard target = new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD);
+ target.setNotTarget(true);
+ if (!player.choose(outcome, player.getGraveyard(), target, game)) {
+ return false;
+ }
+ Card card = game.getCard(target.getFirstTarget());
+ if (card == null || !player.moveCards(card, Zone.BATTLEFIELD, source, game)) {
+ return false;
+ }
+ Permanent permanent = game.getPermanent(card.getId());
+ if (permanent != null) {
+ permanent.addCounters(CounterType.P1P1.createInstance(), source, game);
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/c/CavalierOfFlame.java b/Mage.Sets/src/mage/cards/c/CavalierOfFlame.java
index d39443a8844..6021ff05049 100644
--- a/Mage.Sets/src/mage/cards/c/CavalierOfFlame.java
+++ b/Mage.Sets/src/mage/cards/c/CavalierOfFlame.java
@@ -103,7 +103,7 @@ class CavalierOfFlameEffect extends OneShotEffect {
return false;
}
TargetCardInHand target = new TargetCardInHand(0, player.getHand().size(), StaticFilters.FILTER_CARD);
- if (player.choose(outcome, player.getHand(), target, game)) {
+ if (player.choose(Outcome.Discard, player.getHand(), target, game)) {
int counter = target
.getTargets()
.stream()
diff --git a/Mage.Sets/src/mage/cards/c/CephalidAristocrat.java b/Mage.Sets/src/mage/cards/c/CephalidAristocrat.java
index 7cdf081dfc2..18f3ea581e2 100644
--- a/Mage.Sets/src/mage/cards/c/CephalidAristocrat.java
+++ b/Mage.Sets/src/mage/cards/c/CephalidAristocrat.java
@@ -1,7 +1,5 @@
-
package mage.cards.c;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.BecomesTargetTriggeredAbility;
import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveControllerEffect;
@@ -10,15 +8,16 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class CephalidAristocrat extends CardImpl {
public CephalidAristocrat(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{U}");
- this.subtype.add(SubType.CEPHALID);
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}");
+ this.subtype.add(SubType.CEPHALID, SubType.NOBLE);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
diff --git a/Mage.Sets/src/mage/cards/c/CerebralEruption.java b/Mage.Sets/src/mage/cards/c/CerebralEruption.java
index 56938bcf2a7..66a6ceba3c6 100644
--- a/Mage.Sets/src/mage/cards/c/CerebralEruption.java
+++ b/Mage.Sets/src/mage/cards/c/CerebralEruption.java
@@ -24,7 +24,7 @@ public final class CerebralEruption extends CardImpl {
public CerebralEruption(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}{R}");
- // Target opponent reveals the top card of their library. Cerebral Eruption deals damage equal to the revealed card's converted mana cost to that player and each creature he or she controls. If a land card is revealed this way, return Cerebral Eruption to its owner's hand.
+ // Target opponent reveals the top card of their library. Cerebral Eruption deals damage equal to the revealed card's converted mana cost to that player and each creature they control. If a land card is revealed this way, return Cerebral Eruption to its owner's hand.
this.getSpellAbility().addTarget(new TargetOpponent());
this.getSpellAbility().addEffect(new CerebralEruptionEffect());
}
@@ -44,7 +44,7 @@ class CerebralEruptionEffect extends OneShotEffect {
CerebralEruptionEffect() {
super(Outcome.Damage);
- staticText = "Target opponent reveals the top card of their library. {this} deals damage equal to the revealed card's converted mana cost to that player and each creature he or she controls. If a land card is revealed this way, return {this} to its owner's hand";
+ staticText = "Target opponent reveals the top card of their library. {this} deals damage equal to the revealed card's converted mana cost to that player and each creature they control. If a land card is revealed this way, return {this} to its owner's hand";
}
CerebralEruptionEffect(final CerebralEruptionEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/CerebralVortex.java b/Mage.Sets/src/mage/cards/c/CerebralVortex.java
index 1329470ef84..5960710391b 100644
--- a/Mage.Sets/src/mage/cards/c/CerebralVortex.java
+++ b/Mage.Sets/src/mage/cards/c/CerebralVortex.java
@@ -29,7 +29,7 @@ public final class CerebralVortex extends CardImpl {
public CerebralVortex(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}{R}");
- // Target player draws two cards, then Cerebral Vortex deals damage to that player equal to the number of cards he or she has drawn this turn.
+ // Target player draws two cards, then Cerebral Vortex deals damage to that player equal to the number of cards they have drawn this turn.
this.getSpellAbility().addEffect(new DrawCardTargetEffect(2));
this.getSpellAbility().addEffect(new CerebralVortexEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
@@ -50,7 +50,7 @@ class CerebralVortexEffect extends OneShotEffect {
CerebralVortexEffect() {
super(Outcome.Damage);
- this.staticText = ", then Cerebral Vortex deals damage to that player equal to the number of cards he or she has drawn this turn";
+ this.staticText = ", then Cerebral Vortex deals damage to that player equal to the number of cards they have drawn this turn";
}
CerebralVortexEffect(final CerebralVortexEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/ChainLightning.java b/Mage.Sets/src/mage/cards/c/ChainLightning.java
index 27492f792fb..123aa507a33 100644
--- a/Mage.Sets/src/mage/cards/c/ChainLightning.java
+++ b/Mage.Sets/src/mage/cards/c/ChainLightning.java
@@ -25,7 +25,7 @@ public final class ChainLightning extends CardImpl {
public ChainLightning(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{R}");
- // Chain Lightning deals 3 damage to any target. Then that player or that creature's controller may pay {R}{R}. If the player does, he or she may copy this spell and may choose a new target for that copy.
+ // Chain Lightning deals 3 damage to any target. Then that player or that creature's controller may pay {R}{R}. If the player does, they may copy this spell and may choose a new target for that copy.
this.getSpellAbility().addEffect(new ChainLightningEffect());
this.getSpellAbility().addTarget(new TargetAnyTarget());
}
diff --git a/Mage.Sets/src/mage/cards/c/ChainOfPlasma.java b/Mage.Sets/src/mage/cards/c/ChainOfPlasma.java
index eff15d7cf72..b9db7d2a255 100644
--- a/Mage.Sets/src/mage/cards/c/ChainOfPlasma.java
+++ b/Mage.Sets/src/mage/cards/c/ChainOfPlasma.java
@@ -25,7 +25,7 @@ public final class ChainOfPlasma extends CardImpl {
public ChainOfPlasma(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}");
- // Chain of Plasma deals 3 damage to any target. Then that player or that creature's controller may discard a card. If the player does, he or she may copy this spell and may choose a new target for that copy.
+ // Chain of Plasma deals 3 damage to any target. Then that player or that creature's controller may discard a card. If the player does, they may copy this spell and may choose a new target for that copy.
this.getSpellAbility().addEffect(new ChainOfPlasmaEffect());
this.getSpellAbility().addTarget(new TargetAnyTarget());
}
@@ -44,7 +44,7 @@ class ChainOfPlasmaEffect extends OneShotEffect {
ChainOfPlasmaEffect() {
super(Outcome.Damage);
- this.staticText = "{this} deals 3 damage to any target. Then that player or that creature's controller may discard a card. If the player does, he or she may copy this spell and may choose a new target for that copy.";
+ this.staticText = "{this} deals 3 damage to any target. Then that player or that creature's controller may discard a card. If the player does, they may copy this spell and may choose a new target for that copy.";
}
ChainOfPlasmaEffect(final ChainOfPlasmaEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/ChainOfSilence.java b/Mage.Sets/src/mage/cards/c/ChainOfSilence.java
index 68833dbeb17..379597d6bae 100644
--- a/Mage.Sets/src/mage/cards/c/ChainOfSilence.java
+++ b/Mage.Sets/src/mage/cards/c/ChainOfSilence.java
@@ -32,7 +32,7 @@ public final class ChainOfSilence extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");
- // Prevent all damage target creature would deal this turn. That creature's controller may sacrifice a land. If the player does, he or she may copy this spell and may choose a new target for that copy.
+ // Prevent all damage target creature would deal this turn. That creature's controller may sacrifice a land. If the player does, they may copy this spell and may choose a new target for that copy.
this.getSpellAbility().addEffect(new ChainOfSilenceEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
@@ -100,7 +100,7 @@ class ChainOfSilenceEffect extends OneShotEffect {
@Override
public String getText(Mode mode) {
- return "Prevent all damage target creature would deal this turn. That creature's controller may sacrifice a land. If the player does, he or she may copy this spell and may choose a new target for that copy";
+ return "Prevent all damage target creature would deal this turn. That creature's controller may sacrifice a land. If the player does, they may copy this spell and may choose a new target for that copy";
}
}
diff --git a/Mage.Sets/src/mage/cards/c/ChainOfVapor.java b/Mage.Sets/src/mage/cards/c/ChainOfVapor.java
index cfcb94afc32..4318ad28156 100644
--- a/Mage.Sets/src/mage/cards/c/ChainOfVapor.java
+++ b/Mage.Sets/src/mage/cards/c/ChainOfVapor.java
@@ -29,7 +29,7 @@ public final class ChainOfVapor extends CardImpl {
public ChainOfVapor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}");
- // Return target nonland permanent to its owner's hand. Then that permanent's controller may sacrifice a land. If the player does, he or she may copy this spell and may choose a new target for that copy.
+ // Return target nonland permanent to its owner's hand. Then that permanent's controller may sacrifice a land. If the player does, they may copy this spell and may choose a new target for that copy.
this.getSpellAbility().addEffect(new ChainOfVaporEffect());
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
}
@@ -97,7 +97,7 @@ class ChainOfVaporEffect extends OneShotEffect {
@Override
public String getText(Mode mode) {
- return "Return target nonland permanent to its owner's hand. Then that permanent's controller may sacrifice a land. If the player does, he or she may copy this spell and may choose a new target for that copy";
+ return "Return target nonland permanent to its owner's hand. Then that permanent's controller may sacrifice a land. If the player does, they may copy this spell and may choose a new target for that copy";
}
}
diff --git a/Mage.Sets/src/mage/cards/c/ChainStasis.java b/Mage.Sets/src/mage/cards/c/ChainStasis.java
index 4724a14be86..142f985c114 100644
--- a/Mage.Sets/src/mage/cards/c/ChainStasis.java
+++ b/Mage.Sets/src/mage/cards/c/ChainStasis.java
@@ -31,7 +31,7 @@ public final class ChainStasis extends CardImpl {
public ChainStasis(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}");
- // You may tap or untap target creature. Then that creature's controller may pay {2}{U}. If the player does, he or she may copy this spell and may choose a new target for that copy.
+ // You may tap or untap target creature. Then that creature's controller may pay {2}{U}. If the player does, they may copy this spell and may choose a new target for that copy.
this.getSpellAbility().addEffect(new ChainStasisEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
@@ -102,7 +102,7 @@ class ChainStasisEffect extends OneShotEffect {
@Override
public String getText(Mode mode
) {
- return "You may tap or untap target creature. Then that creature's controller may pay {2}{U}. If the player does, he or she may copy this spell and may choose a new target for that copy";
+ return "You may tap or untap target creature. Then that creature's controller may pay {2}{U}. If the player does, they may copy this spell and may choose a new target for that copy";
}
}
diff --git a/Mage.Sets/src/mage/cards/c/ChainedThroatseeker.java b/Mage.Sets/src/mage/cards/c/ChainedThroatseeker.java
index f9ac5ba3275..ded5fb991e6 100644
--- a/Mage.Sets/src/mage/cards/c/ChainedThroatseeker.java
+++ b/Mage.Sets/src/mage/cards/c/ChainedThroatseeker.java
@@ -10,7 +10,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
@@ -34,10 +33,10 @@ public final class ChainedThroatseeker extends CardImpl {
this.addAbility(InfectAbility.getInstance());
// Chained Throatseeker can't attack unless defending player is poisoned.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ChainedThroatseekerCantAttackEffect()));
+ this.addAbility(new SimpleStaticAbility(new ChainedThroatseekerCantAttackEffect()));
}
- public ChainedThroatseeker(final ChainedThroatseeker card) {
+ private ChainedThroatseeker(final ChainedThroatseeker card) {
super(card);
}
@@ -49,12 +48,12 @@ public final class ChainedThroatseeker extends CardImpl {
class ChainedThroatseekerCantAttackEffect extends RestrictionEffect {
- public ChainedThroatseekerCantAttackEffect() {
+ ChainedThroatseekerCantAttackEffect() {
super(Duration.WhileOnBattlefield);
staticText = "{this} can't attack unless defending player is poisoned";
}
- public ChainedThroatseekerCantAttackEffect(final ChainedThroatseekerCantAttackEffect effect) {
+ private ChainedThroatseekerCantAttackEffect(final ChainedThroatseekerCantAttackEffect effect) {
super(effect);
}
@@ -65,16 +64,12 @@ class ChainedThroatseekerCantAttackEffect extends RestrictionEffect {
@Override
public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game, boolean canUseChooseDialogs) {
- Player targetPlayer = game.getPlayer(defenderId);
- if (targetPlayer != null) {
- return targetPlayer.getCounters().containsKey(CounterType.POISON);
- }
- return false;
+ Player targetPlayer = game.getPlayerOrPlaneswalkerController(defenderId);
+ return targetPlayer != null && targetPlayer.getCounters().containsKey(CounterType.POISON);
}
@Override
public ChainedThroatseekerCantAttackEffect copy() {
return new ChainedThroatseekerCantAttackEffect(this);
}
-
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/c/ChainerNightmareAdept.java b/Mage.Sets/src/mage/cards/c/ChainerNightmareAdept.java
new file mode 100644
index 00000000000..c13928044bb
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/ChainerNightmareAdept.java
@@ -0,0 +1,200 @@
+package mage.cards.c;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
+import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
+import mage.abilities.costs.common.DiscardCardCost;
+import mage.abilities.effects.AsThoughEffectImpl;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.ContinuousEffectImpl;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.keyword.HasteAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.filter.predicate.permanent.TokenPredicate;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.stack.Spell;
+import mage.players.Player;
+import mage.target.targetpointer.FixedTarget;
+import mage.watchers.Watcher;
+import mage.watchers.common.CastFromHandWatcher;
+
+/**
+ * @author goesta
+ */
+public final class ChainerNightmareAdept extends CardImpl {
+
+ public ChainerNightmareAdept(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.MINION);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(2);
+
+ // Discard a card: You may cast a creature card from your graveyard this turn. Activate this ability only once each turn.
+ Ability ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new ChainerNightmareAdeptContinuousEffect(), new DiscardCardCost());
+ this.addAbility(ability, new ChainerNightmareAdeptWatcher());
+
+ // Whenever a nontoken creature enters the battlefield under your control, if you didn't cast it from your hand, it gains haste until your next turn.
+ this.addAbility(new ChainerNightmareAdeptTriggeredAbility(), new CastFromHandWatcher());
+ }
+
+ private ChainerNightmareAdept(final ChainerNightmareAdept card) {
+ super(card);
+ }
+
+ @Override
+ public ChainerNightmareAdept copy() {
+ return new ChainerNightmareAdept(this);
+ }
+}
+
+class ChainerNightmareAdeptContinuousEffect extends ContinuousEffectImpl {
+
+ ChainerNightmareAdeptContinuousEffect() {
+ super(Duration.EndOfTurn, Layer.PlayerEffects, SubLayer.NA, Outcome.Benefit);
+ staticText = "You may cast a creature card from your graveyard this turn.";
+ }
+
+ ChainerNightmareAdeptContinuousEffect(final ChainerNightmareAdeptContinuousEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ChainerNightmareAdeptContinuousEffect copy() {
+ return new ChainerNightmareAdeptContinuousEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+
+ if (player == null || game.getActivePlayerId() == null || !game.isActivePlayer(player.getId())) {
+ return false;
+ }
+
+ for (Card card : player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game)) {
+ ContinuousEffect effect = new ChainerNightmareAdeptCastFromGraveyardEffect();
+ effect.setTargetPointer(new FixedTarget(card.getId()));
+ game.addEffect(effect, source);
+ }
+ return true;
+ }
+}
+
+class ChainerNightmareAdeptCastFromGraveyardEffect extends AsThoughEffectImpl {
+
+ ChainerNightmareAdeptCastFromGraveyardEffect() {
+ super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
+ staticText = "You may cast one creature card from your graveyard";
+ }
+
+ ChainerNightmareAdeptCastFromGraveyardEffect(final ChainerNightmareAdeptCastFromGraveyardEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public ChainerNightmareAdeptCastFromGraveyardEffect copy() {
+ return new ChainerNightmareAdeptCastFromGraveyardEffect(this);
+ }
+
+ @Override
+ public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
+ Card card = game.getCard(objectId);
+ if (card != null
+ && card.getId().equals(getTargetPointer().getFirst(game, source))
+ && card.isCreature()
+ && card.getSpellAbility() != null
+ && affectedControllerId != null
+ && card.getSpellAbility().spellCanBeActivatedRegularlyNow(affectedControllerId, game)
+ && affectedControllerId.equals(source.getControllerId())) {
+ ChainerNightmareAdeptWatcher watcher = game.getState().getWatcher(ChainerNightmareAdeptWatcher.class, source.getSourceId());
+ return watcher != null && !watcher.isAbilityUsed();
+ }
+ return false;
+ }
+}
+
+class ChainerNightmareAdeptWatcher extends Watcher {
+
+ private boolean abilityUsed = false;
+
+ ChainerNightmareAdeptWatcher() {
+ super(WatcherScope.CARD);
+ }
+
+ ChainerNightmareAdeptWatcher(final ChainerNightmareAdeptWatcher watcher) {
+ super(watcher);
+ this.abilityUsed = watcher.abilityUsed;
+ }
+
+ @Override
+ public void watch(GameEvent event, Game game) {
+ if (event.getType() == GameEvent.EventType.SPELL_CAST && event.getZone() == Zone.GRAVEYARD) {
+ Spell spell = (Spell) game.getObject(event.getTargetId());
+ if (spell.isCreature()) {
+ abilityUsed = true;
+ }
+ }
+ }
+
+ @Override
+ public ChainerNightmareAdeptWatcher copy() {
+ return new ChainerNightmareAdeptWatcher(this);
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ abilityUsed = false;
+ }
+
+ public boolean isAbilityUsed() {
+ return abilityUsed;
+ }
+}
+
+class ChainerNightmareAdeptTriggeredAbility extends EntersBattlefieldAllTriggeredAbility {
+
+ private final static String abilityText = "Whenever a nontoken creature enters the battlefield under your control, "
+ + "if you didn't cast it from your hand, it gains haste until your next turn.";
+ private final static ContinuousEffect gainHasteUntilNextTurnEffect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.UntilYourNextTurn);
+ private final static FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another nontoken creature");
+
+ static {
+ filter.add(Predicates.not(TokenPredicate.instance));
+ filter.add(new ControllerPredicate(TargetController.YOU));
+ filter.add(AnotherPredicate.instance);
+ }
+
+ public ChainerNightmareAdeptTriggeredAbility() {
+ super(Zone.BATTLEFIELD, gainHasteUntilNextTurnEffect, filter, false, SetTargetPointer.PERMANENT, abilityText);
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ if (!super.checkTrigger(event, game)) {
+ return false;
+ }
+
+ CastFromHandWatcher watcher = game.getState().getWatcher(CastFromHandWatcher.class);
+ return watcher != null && !watcher.spellWasCastFromHand(event.getSourceId());
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/ChainsOfMephistopheles.java b/Mage.Sets/src/mage/cards/c/ChainsOfMephistopheles.java
index 4cba73bcdca..97210ba99b0 100644
--- a/Mage.Sets/src/mage/cards/c/ChainsOfMephistopheles.java
+++ b/Mage.Sets/src/mage/cards/c/ChainsOfMephistopheles.java
@@ -25,7 +25,7 @@ public final class ChainsOfMephistopheles extends CardImpl {
public ChainsOfMephistopheles(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{B}");
- // If a player would draw a card except the first one he or she draws in their draw step each turn, that player discards a card instead. If the player discards a card this way, he or she draws a card. If the player doesn't discard a card this way, he or she puts the top card of their library into their graveyard.
+ // If a player would draw a card except the first one they draw in their draw step each turn, that player discards a card instead. If the player discards a card this way, they draw a card. If the player doesn't discard a card this way, they put the top card of their library into their graveyard.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ChainsOfMephistophelesReplacementEffect()), new CardsDrawnDuringDrawStepWatcher());
}
@@ -43,7 +43,7 @@ class ChainsOfMephistophelesReplacementEffect extends ReplacementEffectImpl {
public ChainsOfMephistophelesReplacementEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit);
- staticText = "If a player would draw a card except the first one he or she draws in their draw step each turn, that player discards a card instead. If the player discards a card this way, he or she draws a card. If the player doesn't discard a card this way, he or she puts the top card of their library into their graveyard";
+ staticText = "If a player would draw a card except the first one they draw in their draw step each turn, that player discards a card instead. If the player discards a card this way, they draw a card. If the player doesn't discard a card this way, they put the top card of their library into their graveyard";
}
public ChainsOfMephistophelesReplacementEffect(final ChainsOfMephistophelesReplacementEffect effect) {
@@ -65,13 +65,13 @@ class ChainsOfMephistophelesReplacementEffect extends ReplacementEffectImpl {
Player player = game.getPlayer(event.getPlayerId());
if (player != null) {
if (player.getHand().isEmpty()) {
- // he or she puts the top card of their library into their graveyard
+ // they put the top card of their library into their graveyard
Effect effect = new PutTopCardOfLibraryIntoGraveTargetEffect(1);
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
effect.apply(game, source);
return true;
} else {
- // discards a card instead. If the player discards a card this way, he or she draws a card.
+ // discards a card instead. If the player discards a card this way, they draw a card.
player.discard(1, false, source, game);
return false; // because player draws a card, the draw event is kept
}
diff --git a/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java b/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java
index 7de1fc14326..be87c242afe 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java
@@ -1,8 +1,5 @@
-
package mage.cards.c;
-import java.util.Set;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
@@ -17,22 +14,24 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.token.ElementalToken;
import mage.players.Player;
+import java.util.Set;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class ChandraFlamecaller extends CardImpl {
public ChandraFlamecaller(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{4}{R}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{R}{R}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
@@ -78,7 +77,7 @@ class ChandraElementalEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- CreateTokenEffect effect = new CreateTokenEffect(new ElementalToken("OGW", 1, true), 2);
+ CreateTokenEffect effect = new CreateTokenEffect(new ElementalToken("OGW", 2, true), 2);
effect.apply(game, source);
effect.exileTokensCreatedAtNextEndStep(game, source);
return true;
diff --git a/Mage.Sets/src/mage/cards/c/ChandraPyrogenius.java b/Mage.Sets/src/mage/cards/c/ChandraPyrogenius.java
index f764e35a3fa..66a1e08ca23 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraPyrogenius.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraPyrogenius.java
@@ -41,7 +41,7 @@ public final class ChandraPyrogenius extends CardImpl {
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
- // -10: Chandra, Pyrogenius deals 6 damage to target player and each creature he or she controls.
+ // -10: Chandra, Pyrogenius deals 6 damage to target player and each creature they control.
Effects effects = new Effects();
effects.add(new DamageTargetEffect(6));
effects.add(new DamageAllControlledTargetEffect(6, new FilterCreaturePermanent())
diff --git a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java
index 57a53d31912..8c526836ac0 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java
@@ -38,7 +38,8 @@ public final class ChandraPyromaster extends CardImpl {
this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(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);
@@ -49,7 +50,9 @@ public final class ChandraPyromaster extends CardImpl {
LoyaltyAbility ability2 = new LoyaltyAbility(new ChandraPyromasterEffect2(), 0);
this.addAbility(ability2);
- // -7: Exile the top ten cards of your library. Choose an instant or sorcery card exiled this way and copy it three times. You may cast the copies without paying their mana costs.
+ // -7: Exile the top ten cards of your library. Choose an instant or sorcery
+ // card exiled this way and copy it three times. You may cast the copies
+ // without paying their mana costs.
LoyaltyAbility ability3 = new LoyaltyAbility(new ChandraPyromasterEffect3(), -7);
this.addAbility(ability3);
@@ -69,7 +72,9 @@ class ChandraPyromasterEffect1 extends OneShotEffect {
public 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 planeswalker's controller controls. That creature can't block this turn.";
+ staticText = "{this} deals 1 damage to target player or planeswalker "
+ + "and 1 damage to up to one target creature that player or that "
+ + "planeswalker's controller controls. That creature can't block this turn.";
}
public ChandraPyromasterEffect1(final ChandraPyromasterEffect1 effect) {
@@ -83,7 +88,8 @@ class ChandraPyromasterEffect1 extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- game.damagePlayerOrPlaneswalker(source.getTargets().get(0).getFirstTarget(), 1, source.getSourceId(), game, false, true);
+ game.damagePlayerOrPlaneswalker(source.getTargets().get(0).getFirstTarget(),
+ 1, source.getSourceId(), game, false, true);
Permanent creature = game.getPermanent(source.getTargets().get(1).getFirstTarget());
if (creature != null) {
creature.damage(1, source.getSourceId(), game, false, true);
@@ -98,7 +104,8 @@ class ChandraPyromasterEffect1 extends OneShotEffect {
class ChandraPyromasterTarget extends TargetPermanent {
public ChandraPyromasterTarget() {
- super(0, 1, new FilterCreaturePermanent("creature that the targeted player or planeswalker's controller controls"), false);
+ super(0, 1, new FilterCreaturePermanent("creature that the targeted player "
+ + "or planeswalker's controller controls"), false);
}
public ChandraPyromasterTarget(final ChandraPyromasterTarget target) {
@@ -179,7 +186,8 @@ class ChandraPyromasterEffect2 extends OneShotEffect {
Card card = controller.getLibrary().getFromTop(game);
if (card != null) {
controller.moveCards(card, Zone.EXILED, source, game);
- ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
+ ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(
+ Zone.EXILED, Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source);
}
@@ -192,8 +200,10 @@ class ChandraPyromasterEffect2 extends OneShotEffect {
class ChandraPyromasterEffect3 extends OneShotEffect {
public ChandraPyromasterEffect3() {
- super(Outcome.PutCardInPlay);
- this.staticText = "Exile the top ten cards of your library. Choose an instant or sorcery card exiled this way and copy it three times. You may cast the copies without paying their mana costs";
+ super(Outcome.PlayForFree);
+ this.staticText = "Exile the top ten cards of your library. Choose an instant "
+ + "or sorcery card exiled this way and copy it three times. "
+ + "You may cast the copies without paying their mana costs";
}
public ChandraPyromasterEffect3(final ChandraPyromasterEffect3 effect) {
@@ -223,15 +233,24 @@ class ChandraPyromasterEffect3 extends OneShotEffect {
MageObjectReference mor = new MageObjectReference(source.getSourceObject(game), game);
if (controller.chooseUse(outcome, "Do you wish to cast copy 1 of " + card.getName(), source, game)) {
Card copy1 = game.copyCard(card, source, source.getControllerId());
- controller.cast(copy1.getSpellAbility(), game, true, mor);
+ game.getState().setValue("PlayFromNotOwnHandZone" + copy1.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(copy1, game, true),
+ game, true, mor);
+ game.getState().setValue("PlayFromNotOwnHandZone" + copy1.getId(), null);
}
if (controller.chooseUse(outcome, "Do you wish to cast copy 2 of " + card.getName(), source, game)) {
Card copy2 = game.copyCard(card, source, source.getControllerId());
- controller.cast(copy2.getSpellAbility(), game, true, mor);
+ game.getState().setValue("PlayFromNotOwnHandZone" + copy2.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(copy2, game, true),
+ game, true, mor);
+ game.getState().setValue("PlayFromNotOwnHandZone" + copy2.getId(), null);
}
if (controller.chooseUse(outcome, "Do you wish to cast copy 3 of " + card.getName(), source, game)) {
Card copy3 = game.copyCard(card, source, source.getControllerId());
- controller.cast(copy3.getSpellAbility(), game, true, mor);
+ game.getState().setValue("PlayFromNotOwnHandZone" + copy3.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(copy3, game, true),
+ game, true, mor);
+ game.getState().setValue("PlayFromNotOwnHandZone" + copy3.getId(), null);
}
return true;
}
diff --git a/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java b/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java
index 95fd6740e5c..f0b547ad537 100644
--- a/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java
+++ b/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java
@@ -21,6 +21,7 @@ import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.TargetController;
+import mage.constants.Zone;
import mage.game.Game;
import mage.game.command.emblems.ChandraTorchOfDefianceEmblem;
import mage.players.Library;
@@ -89,17 +90,21 @@ class ChandraTorchOfDefianceEffect extends OneShotEffect {
Library library = controller.getLibrary();
Card card = library.getFromTop(game);
if (card != null) {
- boolean exiledCardWasCast = false;
+ boolean cardWasCast = false;
controller.moveCardsToExile(card, source, game, true, source.getSourceId(), sourceObject.getIdName());
- if (!card.getManaCost().isEmpty() && !card.isLand()) {
- if (controller.chooseUse(Outcome.Benefit, "Cast " + card.getName() + "? (You still pay the costs)", source, game)) {
- exiledCardWasCast = controller.cast(card.getSpellAbility(), game, false, new MageObjectReference(sourceObject, game));
+ if (!card.getManaCost().isEmpty()
+ || !card.isLand()) {
+ if (controller.chooseUse(Outcome.Benefit, "Cast " + card.getName() + "? (You still pay the costs)", source, game)
+ && (game.getState().getZone(card.getId()) == Zone.EXILED)) { // card must be in the exile zone
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE); // enable the card to be cast from the exile zone
+ cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, false),
+ game, false, new MageObjectReference(sourceObject, game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null); // reset to null
}
}
- if (!exiledCardWasCast) {
+ if (!cardWasCast) {
new DamagePlayersEffect(Outcome.Damage, new StaticValue(2), TargetController.OPPONENT).apply(game, source);
}
-
}
return true;
}
diff --git a/Mage.Sets/src/mage/cards/c/ChaosWand.java b/Mage.Sets/src/mage/cards/c/ChaosWand.java
index f5f790060aa..75ef1aa4da5 100644
--- a/Mage.Sets/src/mage/cards/c/ChaosWand.java
+++ b/Mage.Sets/src/mage/cards/c/ChaosWand.java
@@ -28,7 +28,10 @@ public final class ChaosWand extends CardImpl {
public ChaosWand(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
- // {4}, {T}: Target opponent exiles cards from the top of their library until they exile an instant or sorcery card. You may cast that card without paying its mana cost. Then put the exiled cards that weren't cast this way on the bottom of that library in a random order.
+ // {4}, {T}: Target opponent exiles cards from the top of their library
+ // until they exile an instant or sorcery card. You may cast that card
+ // without paying its mana cost. Then put the exiled cards that weren't
+ // cast this way on the bottom of that library in a random order.
Ability ability = new SimpleActivatedAbility(
new ChaosWandEffect(),
new GenericManaCost(4)
@@ -51,7 +54,7 @@ public final class ChaosWand extends CardImpl {
class ChaosWandEffect extends OneShotEffect {
public ChaosWandEffect() {
- super(Outcome.Benefit);
+ super(Outcome.PlayForFree);
this.staticText = "Target opponent exiles cards from the top of their library "
+ "until they exile an instant or sorcery card. "
+ "You may cast that card without paying its mana cost. "
@@ -84,9 +87,15 @@ class ChaosWandEffect extends OneShotEffect {
opponent.moveCards(card, Zone.EXILED, source, game);
controller.revealCards(source, new CardsImpl(card), game);
if (card.isInstant() || card.isSorcery()) {
- if (!controller.chooseUse(outcome, "Cast " + card.getName() + " without paying its mana cost?", source, game)
- || !controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
- cardsToShuffle.add(card);
+ if (!controller.chooseUse(Outcome.PlayForFree, "Cast " + card.getName()
+ + " without paying its mana cost?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (!cardWasCast) {
+ cardsToShuffle.add(card);
+ }
}
break;
} else {
diff --git a/Mage.Sets/src/mage/cards/c/ChaosWarp.java b/Mage.Sets/src/mage/cards/c/ChaosWarp.java
index 8121632b5f2..0a38d9eb5ef 100644
--- a/Mage.Sets/src/mage/cards/c/ChaosWarp.java
+++ b/Mage.Sets/src/mage/cards/c/ChaosWarp.java
@@ -29,7 +29,7 @@ public final class ChaosWarp extends CardImpl {
this.getSpellAbility().addEffect(new ChaosWarpShuffleIntoLibraryEffect());
this.getSpellAbility().addTarget(new TargetPermanent());
//then reveals the top card of their library.
- //If it's a permanent card, he or she puts it onto the battlefield.
+ //If it's a permanent card, they put it onto the battlefield.
this.getSpellAbility().addEffect(new ChaosWarpRevealEffect());
}
@@ -79,7 +79,7 @@ class ChaosWarpRevealEffect extends OneShotEffect {
public ChaosWarpRevealEffect() {
super(Outcome.PutCardInPlay);
- this.staticText = "then reveals the top card of their library. If it's a permanent card, he or she puts it onto the battlefield";
+ this.staticText = "then reveals the top card of their library. If it's a permanent card, they put it onto the battlefield";
}
public ChaosWarpRevealEffect(final ChaosWarpRevealEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/ChaoticBacklash.java b/Mage.Sets/src/mage/cards/c/ChaoticBacklash.java
index 23868ef7c94..91465927512 100644
--- a/Mage.Sets/src/mage/cards/c/ChaoticBacklash.java
+++ b/Mage.Sets/src/mage/cards/c/ChaoticBacklash.java
@@ -26,7 +26,7 @@ public final class ChaoticBacklash extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{4}{R}");
- // Chaotic Backlash deals damage to target player equal to twice the number of white and/or blue permanents he or she controls.
+ // Chaotic Backlash deals damage to target player equal to twice the number of white and/or blue permanents they control.
this.getSpellAbility().addEffect(new ChaoticBacklashEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
@@ -44,7 +44,7 @@ public final class ChaoticBacklash extends CardImpl {
class ChaoticBacklashEffect extends OneShotEffect {
- private static final FilterPermanent filter = new FilterPermanent("white and/or blue permanents he or she controls");
+ private static final FilterPermanent filter = new FilterPermanent("white and/or blue permanents they control");
static {
filter.add(Predicates.or(
@@ -54,7 +54,7 @@ class ChaoticBacklashEffect extends OneShotEffect {
public ChaoticBacklashEffect() {
super(Outcome.Detriment);
- this.staticText = "{this} deals damage to target player equal to twice the number of white and/or blue permanents he or she controls";
+ this.staticText = "{this} deals damage to target player equal to twice the number of white and/or blue permanents they control";
}
public ChaoticBacklashEffect(final ChaoticBacklashEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/CharmedSleep.java b/Mage.Sets/src/mage/cards/c/CharmedSleep.java
new file mode 100644
index 00000000000..41daf61253a
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CharmedSleep.java
@@ -0,0 +1,52 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect;
+import mage.abilities.effects.common.TapEnchantedEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+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 CharmedSleep extends CardImpl {
+
+ public CharmedSleep(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}{U}");
+
+ this.subtype.add(SubType.AURA);
+
+ // Enchant creature
+ TargetPermanent auraTarget = new TargetCreaturePermanent();
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // When Charmed Sleep enters the battlefield, tap enchanted creature.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new TapEnchantedEffect()));
+
+ // Enchanted creature doesn't untap during its controller's untap step.
+ this.addAbility(new SimpleStaticAbility(new DontUntapInControllersUntapStepEnchantedEffect()));
+ }
+
+ private CharmedSleep(final CharmedSleep card) {
+ super(card);
+ }
+
+ @Override
+ public CharmedSleep copy() {
+ return new CharmedSleep(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CharmingPrince.java b/Mage.Sets/src/mage/cards/c/CharmingPrince.java
new file mode 100644
index 00000000000..a1b24192575
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CharmingPrince.java
@@ -0,0 +1,113 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.Mode;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect;
+import mage.abilities.effects.keyword.ScryEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.other.OwnerPredicate;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.TargetPermanent;
+import mage.target.targetpointer.FixedTarget;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CharmingPrince extends CardImpl {
+
+
+ private static final FilterPermanent filter = new FilterCreaturePermanent("another creature you own");
+
+ static {
+ filter.add(new OwnerPredicate(TargetController.YOU));
+ filter.add(AnotherPredicate.instance);
+ }
+
+ public CharmingPrince(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.NOBLE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // When Charming Prince enters the battlefield, choose one —
+ // • Scry 2.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new ScryEffect(2));
+
+ // • You gain 3 life.
+ ability.addMode(new Mode(new GainLifeEffect(3)));
+
+ // • Exile another target creature you own. Return it to the battlefield under your control at the beginning of the next end step.
+ Mode mode = new Mode(new CharmingPrinceEffect());
+ mode.addTarget(new TargetPermanent(filter));
+ ability.addMode(mode);
+ this.addAbility(ability);
+ }
+
+ private CharmingPrince(final CharmingPrince card) {
+ super(card);
+ }
+
+ @Override
+ public CharmingPrince copy() {
+ return new CharmingPrince(this);
+ }
+}
+
+class CharmingPrinceEffect extends OneShotEffect {
+
+ CharmingPrinceEffect() {
+ super(Outcome.Benefit);
+ staticText = "Exile another target creature you own. " +
+ "Return it to the battlefield under your control at the beginning of the next end step.";
+ }
+
+ private CharmingPrinceEffect(final CharmingPrinceEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CharmingPrinceEffect copy() {
+ return new CharmingPrinceEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ MageObject sourceObject = game.getObject(source.getSourceId());
+ if (controller == null || sourceObject == null) {
+ return false;
+ }
+ Permanent permanent = game.getPermanent(source.getFirstTarget());
+ if (permanent == null) {
+ return false;
+ }
+ if (!controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true)) {
+ return false;
+ }
+ //create delayed triggered ability
+ Effect effect = new ReturnToBattlefieldUnderYourControlTargetEffect();
+ effect.setText("Return it to the battlefield under your control at the beginning of the next end step");
+ effect.setTargetPointer(new FixedTarget(permanent.getId(), game));
+ game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
+ return true;
+
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/c/ChitteringWitch.java b/Mage.Sets/src/mage/cards/c/ChitteringWitch.java
new file mode 100644
index 00000000000..645f8bf62f5
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/ChitteringWitch.java
@@ -0,0 +1,60 @@
+package mage.cards.c;
+
+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.common.OpponentsCount;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
+import mage.game.permanent.token.RatToken;
+import mage.target.common.TargetControlledCreaturePermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author jmharmon
+ */
+
+public final class ChitteringWitch extends CardImpl {
+
+ public ChitteringWitch(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.WARLOCK);
+
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // When Chittering Witch enters the battlefield, create a number of 1/1 black Rat creature tokens equal to the number of opponents you have.
+ Effect effect = new CreateTokenEffect(new RatToken(), OpponentsCount.instance);
+ effect.setText("create a number of 1/1 black Rat creature tokens equal to the number of opponents you have");
+ this.addAbility(new EntersBattlefieldTriggeredAbility(effect));
+
+ // {1}{B}, Sacrifice a creature: Target creature gets -2/-2 until end of turn.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(-2, -2, Duration.EndOfTurn), new ManaCostsImpl("{1}{B}"));
+ ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+ }
+
+ public ChitteringWitch(final ChitteringWitch card) {
+ super(card);
+ }
+
+ @Override
+ public ChitteringWitch copy() {
+ return new ChitteringWitch(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/ChordOfCalling.java b/Mage.Sets/src/mage/cards/c/ChordOfCalling.java
index 951c0a11b20..19ee96ddc85 100644
--- a/Mage.Sets/src/mage/cards/c/ChordOfCalling.java
+++ b/Mage.Sets/src/mage/cards/c/ChordOfCalling.java
@@ -1,4 +1,3 @@
-
package mage.cards.c;
import java.util.UUID;
@@ -7,7 +6,7 @@ import mage.abilities.keyword.ConvokeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -22,7 +21,7 @@ public final class ChordOfCalling extends CardImpl {
this.addAbility(new ConvokeAbility());
// Search your library for a creature card with converted mana cost X or less and put it onto the battlefield. Then shuffle your library.
- this.getSpellAbility().addEffect(new SearchLibraryWithLessCMCPutInPlayEffect(new FilterCreatureCard()));
+ this.getSpellAbility().addEffect(new SearchLibraryWithLessCMCPutInPlayEffect(StaticFilters.FILTER_CARD_CREATURE));
}
public ChordOfCalling(final ChordOfCalling card) {
diff --git a/Mage.Sets/src/mage/cards/c/CitadelOfPain.java b/Mage.Sets/src/mage/cards/c/CitadelOfPain.java
index 1cf2bbde90a..6443ee7c354 100644
--- a/Mage.Sets/src/mage/cards/c/CitadelOfPain.java
+++ b/Mage.Sets/src/mage/cards/c/CitadelOfPain.java
@@ -32,7 +32,7 @@ public final class CitadelOfPain extends CardImpl {
TriggeredAbility triggered = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE,
"beginning of the end step", true,
new CitadelOfPainEffect());
- // At the beginning of each player's end step, Citadel of Pain deals X damage to that player, where X is the number of untapped lands he or she controls.
+ // At the beginning of each player's end step, Citadel of Pain deals X damage to that player, where X is the number of untapped lands they control.
this.addAbility(triggered);
}
@@ -52,7 +52,7 @@ class CitadelOfPainEffect extends OneShotEffect {
@Override
public String getText(Mode mode) {
- return "{this} deals X damage to that player, where X is the number of untapped lands he or she controls.";
+ return "{this} deals X damage to that player, where X is the number of untapped lands they control.";
}
static {
diff --git a/Mage.Sets/src/mage/cards/c/CityOfTraitors.java b/Mage.Sets/src/mage/cards/c/CityOfTraitors.java
index aa507b2a60d..39b86b5b1a3 100644
--- a/Mage.Sets/src/mage/cards/c/CityOfTraitors.java
+++ b/Mage.Sets/src/mage/cards/c/CityOfTraitors.java
@@ -1,8 +1,5 @@
-
package mage.cards.c;
-import java.util.Objects;
-import java.util.UUID;
import mage.Mana;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.costs.common.TapSourceCost;
@@ -17,14 +14,16 @@ import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
+import java.util.Objects;
+import java.util.UUID;
+
/**
- *
* @author jeffwadsworth
*/
public final class CityOfTraitors extends CardImpl {
public CityOfTraitors(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
// When you play another land, sacrifice City of Traitors.
this.addAbility(new CityOfTraitorsTriggeredAbility());
@@ -61,7 +60,8 @@ class CityOfTraitorsTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent land = game.getPermanent(event.getTargetId());
- return land.isLand()
+ return land != null
+ && land.isLand()
&& land.isControlledBy(this.controllerId)
&& !Objects.equals(event.getTargetId(), this.getSourceId());
}
diff --git a/Mage.Sets/src/mage/cards/c/ClackbridgeTroll.java b/Mage.Sets/src/mage/cards/c/ClackbridgeTroll.java
new file mode 100644
index 00000000000..b8be5017bc6
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/ClackbridgeTroll.java
@@ -0,0 +1,123 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfCombatTriggeredAbility;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateTokenTargetEffect;
+import mage.abilities.keyword.HasteAbility;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.token.GoatToken;
+import mage.players.Player;
+import mage.target.common.TargetControlledPermanent;
+import mage.target.common.TargetOpponent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ClackbridgeTroll extends CardImpl {
+
+ public ClackbridgeTroll(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
+
+ this.subtype.add(SubType.TROLL);
+ this.power = new MageInt(8);
+ this.toughness = new MageInt(8);
+
+ // Trample
+ this.addAbility(TrampleAbility.getInstance());
+
+ // Haste
+ this.addAbility(HasteAbility.getInstance());
+
+ // When Clackbridge Troll enters the battlefield, target opponent creates three 0/1 white Goat creature tokens.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new CreateTokenTargetEffect(new GoatToken(), 3));
+ ability.addTarget(new TargetOpponent());
+ this.addAbility(ability);
+
+ // At the beginning of combat on your turn, any opponent may sacrifice a creature. If a player does, tap Clackbridge Troll, you gain 3 life, and you draw a card.
+ this.addAbility(new BeginningOfCombatTriggeredAbility(
+ new ClackbridgeTrollEffect(), TargetController.YOU, false)
+ );
+ }
+
+ private ClackbridgeTroll(final ClackbridgeTroll card) {
+ super(card);
+ }
+
+ @Override
+ public ClackbridgeTroll copy() {
+ return new ClackbridgeTroll(this);
+ }
+}
+
+class ClackbridgeTrollEffect extends OneShotEffect {
+
+ ClackbridgeTrollEffect() {
+ super(Outcome.Benefit);
+ staticText = "any opponent may sacrifice a creature. If a player does, " +
+ "tap {this}, you gain 3 life, and you draw a card.";
+ }
+
+ private ClackbridgeTrollEffect(final ClackbridgeTrollEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ClackbridgeTrollEffect copy() {
+ return new ClackbridgeTrollEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Permanent sourcePerm = game.getPermanent(source.getSourceId());
+ if (controller == null) {
+ return false;
+ }
+ boolean flag = false;
+ for (UUID opponentId : game.getOpponents(controller.getId())) {
+ Player opponent = game.getPlayer(opponentId);
+ if (opponent == null) {
+ continue;
+ }
+ FilterControlledPermanent filter = new FilterControlledPermanent("creature to sacrifice");
+ filter.add(new CardTypePredicate(CardType.CREATURE));
+ filter.add(new ControllerPredicate(TargetController.YOU));
+ TargetControlledPermanent target = new TargetControlledPermanent(filter);
+ target.setNotTarget(true);
+ if (!target.canChoose(opponent.getId(), game)
+ || !opponent.chooseUse(Outcome.AIDontUseIt, "Sacrifice a creature?", source, game)
+ || !opponent.choose(Outcome.Sacrifice, target, source.getSourceId(), game)) {
+ continue;
+ }
+ Permanent permanent = game.getPermanent(target.getFirstTarget());
+ if (permanent == null || !permanent.sacrifice(source.getSourceId(), game)) {
+ continue;
+ }
+ flag = true;
+ }
+ if (flag) {
+ if (sourcePerm != null) {
+ sourcePerm.tap(game);
+ }
+ controller.gainLife(3, game, source);
+ controller.drawCards(1, game);
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/c/ClaimTheFirstborn.java b/Mage.Sets/src/mage/cards/c/ClaimTheFirstborn.java
new file mode 100644
index 00000000000..8d328a64278
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/ClaimTheFirstborn.java
@@ -0,0 +1,51 @@
+package mage.cards.c;
+
+import mage.abilities.effects.common.UntapTargetEffect;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.effects.common.continuous.GainControlTargetEffect;
+import mage.abilities.keyword.HasteAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.Duration;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ClaimTheFirstborn extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterCreaturePermanent("creature with converted mana cost 3 or less");
+
+ static {
+ filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 4));
+ }
+
+ public ClaimTheFirstborn(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}");
+
+ // Gain control of target creature with converted mana cost 3 or less until end of turn. Untap that creature. It gains haste until end of turn.
+ this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new UntapTargetEffect()
+ .setText("Untap that creature"));
+ this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)
+ .setText("It gains haste until end of turn."));
+ this.getSpellAbility().addTarget(new TargetPermanent(filter));
+ }
+
+ private ClaimTheFirstborn(final ClaimTheFirstborn card) {
+ super(card);
+ }
+
+ @Override
+ public ClaimTheFirstborn copy() {
+ return new ClaimTheFirstborn(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/ClockworkServant.java b/Mage.Sets/src/mage/cards/c/ClockworkServant.java
new file mode 100644
index 00000000000..0e38967ad99
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/ClockworkServant.java
@@ -0,0 +1,44 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.condition.common.AdamantCondition;
+import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.watchers.common.ManaSpentToCastWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ClockworkServant extends CardImpl {
+
+ public ClockworkServant(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}");
+
+ this.subtype.add(SubType.GNOME);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // Adamant - When Clockwork Servant enters the battlefield, if at least three mana of the same color was spent to cast it, draw a card.
+ this.addAbility(new ConditionalInterveningIfTriggeredAbility(
+ new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)),
+ AdamantCondition.ANY, "
Adamant — When {this} enters the battlefield, " +
+ "if at least three mana of the same color was spent to cast it, draw a card."
+ ), new ManaSpentToCastWatcher());
+ }
+
+ private ClockworkServant(final ClockworkServant card) {
+ super(card);
+ }
+
+ @Override
+ public ClockworkServant copy() {
+ return new ClockworkServant(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/ColdSnap.java b/Mage.Sets/src/mage/cards/c/ColdSnap.java
index 5902042e266..8772ae0a60c 100644
--- a/Mage.Sets/src/mage/cards/c/ColdSnap.java
+++ b/Mage.Sets/src/mage/cards/c/ColdSnap.java
@@ -28,7 +28,7 @@ public final class ColdSnap extends CardImpl {
// Cumulative upkeep {2}
this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{2}")));
- // At the beginning of each player's upkeep, Cold Snap deals damage to that player equal to the number of snow lands he or she controls.
+ // At the beginning of each player's upkeep, Cold Snap deals damage to that player equal to the number of snow lands they control.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new ColdSnapDamageTargetEffect(), TargetController.ANY, false, true));
}
@@ -62,7 +62,7 @@ class ColdSnapDamageTargetEffect extends OneShotEffect{
@Override
public String getText(Mode mode) {
- return "{this} deals damage to that player equal to the number of snow lands he or she controls";
+ return "{this} deals damage to that player equal to the number of snow lands they control";
}
@Override
diff --git a/Mage.Sets/src/mage/cards/c/CollapsingBorders.java b/Mage.Sets/src/mage/cards/c/CollapsingBorders.java
index 2b4d21ca20f..1aa523897ae 100644
--- a/Mage.Sets/src/mage/cards/c/CollapsingBorders.java
+++ b/Mage.Sets/src/mage/cards/c/CollapsingBorders.java
@@ -24,12 +24,12 @@ public final class CollapsingBorders extends CardImpl {
public CollapsingBorders(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
- // Domain - At the beginning of each player's upkeep, that player gains 1 life for each basic land type among lands he or she controls. Then Collapsing Borders deals 3 damage to him or her.
+ // Domain - At the beginning of each player's upkeep, that player gains 1 life for each basic land type among lands they control. Then Collapsing Borders deals 3 damage to that player.
Effect effect = new GainLifeTargetEffect(new DomainValue(true));
- effect.setText("that player gains 1 life for each basic land type among lands he or she controls.");
+ effect.setText("that player gains 1 life for each basic land type among lands they control.");
Ability ability = new BeginningOfUpkeepTriggeredAbility(effect, TargetController.ANY, false);
effect = new DamageTargetEffect(3);
- effect.setText("Then {this} deals 3 damage to him or her.");
+ effect.setText("Then {this} deals 3 damage to that player.");
ability.addEffect(effect);
ability.setAbilityWord(AbilityWord.DOMAIN);
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/c/CollectedConjuring.java b/Mage.Sets/src/mage/cards/c/CollectedConjuring.java
index 22094e0f1bb..709d46dfa3d 100644
--- a/Mage.Sets/src/mage/cards/c/CollectedConjuring.java
+++ b/Mage.Sets/src/mage/cards/c/CollectedConjuring.java
@@ -26,7 +26,10 @@ public final class CollectedConjuring extends CardImpl {
public CollectedConjuring(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}{R}");
- // Exile the top six cards of your library. You may cast up to two sorcery cards with converted mana costs 3 or less from among them without paying their mana cost. Put the exiled cards not cast this way on the bottom of your library in a random order.
+ // Exile the top six cards of your library. You may cast up to two sorcery
+ // cards with converted mana costs 3 or less from among them without paying
+ // their mana cost. Put the exiled cards not cast this way on the bottom
+ // of your library in a random order.
this.getSpellAbility().addEffect(new CollectedConjuringEffect());
}
@@ -42,7 +45,8 @@ public final class CollectedConjuring extends CardImpl {
class CollectedConjuringEffect extends OneShotEffect {
- private static final FilterCard filter = new FilterCard("sorcery cards with converted mana cost 3 or less");
+ private static final FilterCard filter = new FilterCard(
+ "sorcery cards with converted mana cost 3 or less");
static {
filter.add(new CardTypePredicate(CardType.SORCERY));
@@ -56,11 +60,11 @@ class CollectedConjuringEffect extends OneShotEffect {
}
CollectedConjuringEffect() {
- super(Outcome.Benefit);
- this.staticText = "Exile the top six cards of your library. " +
- "You may cast up to two sorcery cards with converted mana costs 3 or less from among them " +
- "without paying their mana cost. Put the exiled cards not cast this way " +
- "on the bottom of your library in a random order.";
+ super(Outcome.PlayForFree);
+ this.staticText = "Exile the top six cards of your library. "
+ + "You may cast up to two sorcery cards with converted mana costs 3 or less from among them "
+ + "without paying their mana cost. Put the exiled cards not cast this way "
+ + "on the bottom of your library in a random order.";
}
private CollectedConjuringEffect(final CollectedConjuringEffect effect) {
@@ -76,14 +80,17 @@ class CollectedConjuringEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
- if (controller == null || sourceObject == null) {
+ if (controller == null
+ || sourceObject == null) {
return false;
}
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 6));
controller.moveCards(cards, Zone.EXILED, source, game);
int cardsCast = 0;
- while (!cards.getCards(filter, source.getSourceId(), source.getControllerId(), game).isEmpty() && cardsCast < 2) {
- if (!controller.chooseUse(Outcome.PlayForFree, "Cast a card exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
+ while (!cards.getCards(filter, source.getSourceId(), source.getControllerId(), game).isEmpty()
+ && cardsCast < 2) {
+ if (!controller.chooseUse(Outcome.PlayForFree, "Cast a card exiled with "
+ + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
break;
}
TargetCard targetCard = new TargetCard(1, Zone.EXILED, filter2);
@@ -94,11 +101,16 @@ class CollectedConjuringEffect extends OneShotEffect {
if (card == null) {
continue;
}
- if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (cardWasCast) {
cards.remove(card);
cardsCast++;
} else {
- game.informPlayer(controller, "You're not able to cast " + card.getIdName() + " or you canceled the casting.");
+ game.informPlayer(controller, "You're not able to cast "
+ + card.getIdName() + " or you canceled the casting.");
}
}
controller.putCardsOnBottomOfLibrary(cards, game, source, false);
diff --git a/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java b/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java
index 8d0acc19b1e..3cb3e18e169 100644
--- a/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java
+++ b/Mage.Sets/src/mage/cards/c/CollectiveRestraint.java
@@ -25,7 +25,7 @@ public final class CollectiveRestraint extends CardImpl {
public CollectiveRestraint(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}");
- // Domain - Creatures can't attack you unless their controller pays {X} for each creature he or she controls that's attacking you, where X is the number of basic land types you control.
+ // Domain - Creatures can't attack you unless their controller pays {X} for each creature they control that's attacking you, where X is the number of basic land types you control.
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new CollectiveRestraintPayManaToAttackAllEffect());
ability.setAbilityWord(AbilityWord.DOMAIN);
this.addAbility(ability);
@@ -46,7 +46,7 @@ class CollectiveRestraintPayManaToAttackAllEffect extends CantAttackYouUnlessPay
CollectiveRestraintPayManaToAttackAllEffect() {
super(null, false);
- staticText = "Creatures can't attack you unless their controller pays {X} for each creature he or she controls that's attacking you, where X is the number of basic land types you control.";
+ staticText = "Creatures can't attack you unless their controller pays {X} for each creature they control that's attacking you, where X is the number of basic land types you control.";
}
CollectiveRestraintPayManaToAttackAllEffect(CollectiveRestraintPayManaToAttackAllEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/CommandingPresence.java b/Mage.Sets/src/mage/cards/c/CommandingPresence.java
new file mode 100644
index 00000000000..c6443d3529e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CommandingPresence.java
@@ -0,0 +1,62 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
+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.FirstStrikeAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.permanent.token.HumanSoldierToken;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CommandingPresence extends CardImpl {
+
+ public CommandingPresence(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}");
+
+ this.subtype.add(SubType.AURA);
+
+ // Enchant creature
+ TargetPermanent auraTarget = new TargetCreaturePermanent();
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // Enchanted creature gets +2/+2 and has first strike and "Whenever this creature deals combat damage to a player, create a 1/1 white Human Soldier creature token."
+ ability = new SimpleStaticAbility(new BoostEnchantedEffect(2, 2));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ FirstStrikeAbility.getInstance(), AttachmentType.AURA,
+ Duration.WhileOnBattlefield, "and has first strike"
+ ));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ new DealsCombatDamageToAPlayerTriggeredAbility(
+ new CreateTokenEffect(new HumanSoldierToken()), false
+ ), AttachmentType.AURA, Duration.WhileOnBattlefield,
+ "and \"Whenever this creature deals combat damage to a player, " +
+ "create a 1/1 white Human Soldier creature token.\""
+ ));
+ this.addAbility(ability);
+ }
+
+ private CommandingPresence(final CommandingPresence card) {
+ super(card);
+ }
+
+ @Override
+ public CommandingPresence copy() {
+ return new CommandingPresence(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CompulsiveResearch.java b/Mage.Sets/src/mage/cards/c/CompulsiveResearch.java
index 5b8a76150d4..d132be25f8b 100644
--- a/Mage.Sets/src/mage/cards/c/CompulsiveResearch.java
+++ b/Mage.Sets/src/mage/cards/c/CompulsiveResearch.java
@@ -25,7 +25,7 @@ public final class CompulsiveResearch extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}");
- // Target player draws three cards. Then that player discards two cards unless he or she discards a land card.
+ // Target player draws three cards. Then that player discards two cards unless they discard a land card.
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new DrawCardTargetEffect(3));
this.getSpellAbility().addEffect(new CompulsiveResearchDiscardEffect());
@@ -44,7 +44,7 @@ class CompulsiveResearchDiscardEffect extends OneShotEffect {
public CompulsiveResearchDiscardEffect() {
super(Outcome.Discard);
- this.staticText = "Then that player discards two cards unless he or she discards a land card";
+ this.staticText = "Then that player discards two cards unless they discard a land card";
}
public CompulsiveResearchDiscardEffect(final CompulsiveResearchDiscardEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/ConstrictingSliver.java b/Mage.Sets/src/mage/cards/c/ConstrictingSliver.java
index 49ce3b59141..8d8d0687a90 100644
--- a/Mage.Sets/src/mage/cards/c/ConstrictingSliver.java
+++ b/Mage.Sets/src/mage/cards/c/ConstrictingSliver.java
@@ -1,4 +1,3 @@
-
package mage.cards.c;
import java.util.UUID;
@@ -10,7 +9,7 @@ import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect;
-import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
+import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
@@ -47,9 +46,10 @@ public final class ConstrictingSliver extends CardImpl {
ability.addTarget(new TargetCreaturePermanent(filterTarget));
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
- new GainAbilityAllEffect(ability,
- Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS,
- "Sliver creatures you control have \"When this creature enters the battlefield, you may exile target creature an opponent controls until this creature leaves the battlefield.\"")));
+ new GainAbilityControlledEffect(ability,
+ Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS)
+ .setText("Sliver creatures you control have \"When this creature enters the battlefield, "
+ + "you may exile target creature an opponent controls until this creature leaves the battlefield.\"")));
}
diff --git a/Mage.Sets/src/mage/cards/c/ConsumingAberration.java b/Mage.Sets/src/mage/cards/c/ConsumingAberration.java
index 69ade3c171d..6eb7c879898 100644
--- a/Mage.Sets/src/mage/cards/c/ConsumingAberration.java
+++ b/Mage.Sets/src/mage/cards/c/ConsumingAberration.java
@@ -35,7 +35,7 @@ public final class ConsumingAberration extends CardImpl {
//Consuming Aberration's power and toughness are each equal to the number of cards in your opponents' graveyards.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new CardsInOpponentsGraveyardsCount(), Duration.EndOfGame)));
- //Whenever you cast a spell, each opponent reveals cards from the top of their library until he or she reveals a land card, then puts those cards into their graveyard.
+ //Whenever you cast a spell, each opponent reveals cards from the top of their library until they reveal a land card, then puts those cards into their graveyard.
this.addAbility(new SpellCastControllerTriggeredAbility(new ConsumingAberrationEffect(), false));
}
@@ -53,7 +53,7 @@ class ConsumingAberrationEffect extends OneShotEffect {
public ConsumingAberrationEffect() {
super(Outcome.PutCardInPlay);
- this.staticText = "each opponent reveals cards from the top of their library until he or she reveals a land card, then puts those cards into their graveyard";
+ this.staticText = "each opponent reveals cards from the top of their library until they reveal a land card, then puts those cards into their graveyard";
}
public ConsumingAberrationEffect(final ConsumingAberrationEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/ConundrumSphinx.java b/Mage.Sets/src/mage/cards/c/ConundrumSphinx.java
index ae2ce4eaafc..6baed0ceb09 100644
--- a/Mage.Sets/src/mage/cards/c/ConundrumSphinx.java
+++ b/Mage.Sets/src/mage/cards/c/ConundrumSphinx.java
@@ -35,7 +35,7 @@ public final class ConundrumSphinx extends CardImpl {
//Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever Conundrum Sphinx attacks, each player names a card. Then each player reveals the top card of their library.
- // If the card a player revealed is the card he or she named, that player puts it into their hand.
+ // If the card a player revealed is the card they named, that player puts it into their hand.
// If it's not, that player puts it on the bottom of their library.
this.addAbility(new AttacksTriggeredAbility(new ConundrumSphinxEffect(), false));
}
@@ -55,7 +55,7 @@ class ConundrumSphinxEffect extends OneShotEffect {
public ConundrumSphinxEffect() {
super(Outcome.DrawCard);
- staticText = "each player names a card. Then each player reveals the top card of their library. If the card a player revealed is the card he or she named, that player puts it into their hand. If it's not, that player puts it on the bottom of their library";
+ staticText = "each player names a card. Then each player reveals the top card of their library. If the card a player revealed is the card they named, that player puts it into their hand. If it's not, that player puts it on the bottom of their library";
}
public ConundrumSphinxEffect(final ConundrumSphinxEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/CorpseConnoisseur.java b/Mage.Sets/src/mage/cards/c/CorpseConnoisseur.java
index d134fd60ac3..98ddf5d9a4a 100644
--- a/Mage.Sets/src/mage/cards/c/CorpseConnoisseur.java
+++ b/Mage.Sets/src/mage/cards/c/CorpseConnoisseur.java
@@ -1,4 +1,3 @@
-
package mage.cards.c;
import java.util.UUID;
@@ -12,10 +11,10 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
@@ -27,7 +26,7 @@ import mage.target.common.TargetCardInLibrary;
public final class CorpseConnoisseur extends CardImpl {
public CorpseConnoisseur(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
this.subtype.add(SubType.ZOMBIE);
this.subtype.add(SubType.WIZARD);
@@ -52,8 +51,8 @@ public final class CorpseConnoisseur extends CardImpl {
class SearchLibraryPutInGraveyard extends SearchEffect {
- public SearchLibraryPutInGraveyard() {
- super(new TargetCardInLibrary(new FilterCreatureCard()), Outcome.Neutral);
+ public SearchLibraryPutInGraveyard() {
+ super(new TargetCardInLibrary(StaticFilters.FILTER_CARD_CREATURE), Outcome.Neutral);
staticText = "search your library for a card and put that card into your graveyard. Then shuffle your library";
}
@@ -80,9 +79,8 @@ class SearchLibraryPutInGraveyard extends SearchEffect {
}
controller.shuffleLibrary(source, game);
return true;
- }
+ }
return false;
}
-
}
diff --git a/Mage.Sets/src/mage/cards/c/CorridorMonitor.java b/Mage.Sets/src/mage/cards/c/CorridorMonitor.java
new file mode 100644
index 00000000000..9a277adc542
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CorridorMonitor.java
@@ -0,0 +1,55 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.UntapTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CorridorMonitor extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterControlledPermanent("artifact or creature you control");
+
+ static {
+ filter.add(Predicates.or(
+ new CardTypePredicate(CardType.ARTIFACT),
+ new CardTypePredicate(CardType.CREATURE)
+ ));
+ }
+
+ public CorridorMonitor(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{U}");
+
+ this.subtype.add(SubType.CONSTRUCT);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(4);
+
+ // When Corridor Monitor enters the battlefield, untap target artifact or creature you control.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new UntapTargetEffect());
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(ability);
+ }
+
+ private CorridorMonitor(final CorridorMonitor card) {
+ super(card);
+ }
+
+ @Override
+ public CorridorMonitor copy() {
+ return new CorridorMonitor(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CouncilGuardian.java b/Mage.Sets/src/mage/cards/c/CouncilGuardian.java
index 0931fdd4662..631f174e09d 100644
--- a/Mage.Sets/src/mage/cards/c/CouncilGuardian.java
+++ b/Mage.Sets/src/mage/cards/c/CouncilGuardian.java
@@ -1,9 +1,5 @@
-
package mage.cards.c;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
@@ -15,14 +11,17 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceColor;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.game.Game;
import mage.players.Player;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
/**
- *
* @author Styxo
*/
public final class CouncilGuardian extends CardImpl {
@@ -53,7 +52,7 @@ public final class CouncilGuardian extends CardImpl {
class CouncilsGuardianEffect extends OneShotEffect {
public CouncilsGuardianEffect() {
- super(Outcome.Exile);
+ super(Outcome.Benefit);
this.staticText = "starting with you, each player votes for blue, black, red, or green. {this} gains protection from each color with the most votes or tied for most votes";
}
@@ -78,7 +77,7 @@ class CouncilsGuardianEffect extends OneShotEffect {
Player player = game.getPlayer(playerId);
if (player != null) {
choice.clearChoice();
- if (player.choose(outcome, choice, game)) {
+ if (player.choose(Outcome.Detriment, choice, game)) {
ObjectColor color = choice.getColor();
if (color != null) {
if (chosenColors.containsKey(color)) {
diff --git a/Mage.Sets/src/mage/cards/c/CovenantOfMinds.java b/Mage.Sets/src/mage/cards/c/CovenantOfMinds.java
index e20336fa981..9c4ed372d42 100644
--- a/Mage.Sets/src/mage/cards/c/CovenantOfMinds.java
+++ b/Mage.Sets/src/mage/cards/c/CovenantOfMinds.java
@@ -24,7 +24,7 @@ public final class CovenantOfMinds extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}");
// Reveal the top three cards of your library. Target opponent may choose to put those cards into your hand.
- // If he or she doesn't, put those cards into your graveyard and draw five cards.
+ // If they don't, put those cards into your graveyard and draw five cards.
this.getSpellAbility().addEffect(new CovenantOfMindsEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
}
@@ -43,7 +43,7 @@ class CovenantOfMindsEffect extends OneShotEffect {
public CovenantOfMindsEffect() {
super(Outcome.DrawCard);
- this.staticText = "Reveal the top three cards of your library. Target opponent may choose to put those cards into your hand. If he or she doesn't, put those cards into your graveyard and draw five cards";
+ this.staticText = "Reveal the top three cards of your library. Target opponent may choose to put those cards into your hand. If they don't, put those cards into your graveyard and draw five cards";
}
public CovenantOfMindsEffect(final CovenantOfMindsEffect effect) {
@@ -68,7 +68,7 @@ class CovenantOfMindsEffect extends OneShotEffect {
player.revealCards(source, cards, game);
StringBuilder sb = new StringBuilder();
sb.append("Put the revealed cards into ").append(player.getLogName()).append("'s hand?");
- sb.append(" If you don't, those cards are put into his graveyard and he will draw five cards.");
+ sb.append(" If you don't, those cards are put into their graveyard and they will draw five cards.");
if (opponent.chooseUse(Outcome.Neutral, sb.toString(), source, game)) {
player.moveCards(cards, Zone.HAND, source, game);
@@ -78,7 +78,7 @@ class CovenantOfMindsEffect extends OneShotEffect {
}
} else {
- if (!opponent.chooseUse(Outcome.Benefit, player.getLogName() + "'s library is empty? Do you want him to draw five cards?", source, game)) {
+ if (!opponent.chooseUse(Outcome.Benefit, player.getLogName() + "'s library is empty? Do you want them to draw five cards?", source, game)) {
player.drawCards(5, game);
}
}
diff --git a/Mage.Sets/src/mage/cards/c/CovetousUrge.java b/Mage.Sets/src/mage/cards/c/CovetousUrge.java
new file mode 100644
index 00000000000..051a0973d57
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CovetousUrge.java
@@ -0,0 +1,172 @@
+package mage.cards.c;
+
+import mage.MageObjectReference;
+import mage.abilities.Ability;
+import mage.abilities.effects.AsThoughEffectImpl;
+import mage.abilities.effects.AsThoughManaEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.players.ManaPoolItem;
+import mage.players.Player;
+import mage.target.TargetCard;
+import mage.target.common.TargetCardInGraveyard;
+import mage.target.common.TargetCardInHand;
+import mage.target.common.TargetOpponent;
+import mage.target.targetpointer.FixedTarget;
+import mage.util.CardUtil;
+
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CovetousUrge extends CardImpl {
+
+ public CovetousUrge(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U/B}{U/B}{U/B}{U/B}");
+
+ // Target opponent reveals their hand. You choose a nonland card from that player's graveyard or hand and exile it. You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell.
+ this.getSpellAbility().addEffect(new CovetousUrgeEffect());
+ this.getSpellAbility().addTarget(new TargetOpponent());
+ }
+
+ private CovetousUrge(final CovetousUrge card) {
+ super(card);
+ }
+
+ @Override
+ public CovetousUrge copy() {
+ return new CovetousUrge(this);
+ }
+}
+
+class CovetousUrgeEffect extends OneShotEffect {
+
+ CovetousUrgeEffect() {
+ super(Outcome.Benefit);
+ staticText = "Target opponent reveals their hand. You choose a nonland card from that player's graveyard " +
+ "or hand and exile it. You may cast that card for as long as it remains exiled," +
+ " and you may spend mana as though it were mana of any color to cast that spell.";
+ }
+
+ private CovetousUrgeEffect(final CovetousUrgeEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CovetousUrgeEffect copy() {
+ return new CovetousUrgeEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Player player = game.getPlayer(source.getFirstTarget());
+ if (controller == null || player == null) {
+ return false;
+ }
+ player.revealCards(source, player.getHand(), game);
+ if (!controller.chooseUse(outcome, "Choose a nonland card to exile?", source, game)) {
+ return false;
+ }
+ TargetCard target;
+ if (player.getGraveyard().isEmpty() || controller.chooseUse(outcome,
+ "Exile a nonland card from " + player.getName() + "'s hand or graveyard",
+ "", "Hand", "Graveyard", source, game)) {
+ if (player.getHand().isEmpty()) {
+ return true;
+ }
+ target = new TargetCardInHand(StaticFilters.FILTER_CARD_A_NON_LAND);
+ controller.choose(outcome, player.getHand(), target, game);
+ } else {
+ target = new TargetCardInGraveyard(StaticFilters.FILTER_CARD_A_NON_LAND);
+ controller.choose(outcome, player.getGraveyard(), target, game);
+ }
+ Card card = game.getCard(target.getFirstTarget());
+ if (card == null || !controller.moveCards(card, Zone.EXILED, source, game)) {
+ return false;
+ }
+ if (card.getSpellAbility() == null) {
+ return true;
+ }
+ game.addEffect(new CovetousUrgeCastFromExileEffect(new MageObjectReference(card, game)), source);
+ game.addEffect(new CovetousUrgeSpendAnyManaEffect().setTargetPointer(new FixedTarget(card, game)), source);
+ return true;
+ }
+}
+
+class CovetousUrgeCastFromExileEffect extends AsThoughEffectImpl {
+
+ private final MageObjectReference mor;
+
+ CovetousUrgeCastFromExileEffect(MageObjectReference mor) {
+ super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit);
+ this.mor = mor;
+ }
+
+ private CovetousUrgeCastFromExileEffect(final CovetousUrgeCastFromExileEffect effect) {
+ super(effect);
+ this.mor = effect.mor;
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public CovetousUrgeCastFromExileEffect copy() {
+ return new CovetousUrgeCastFromExileEffect(this);
+ }
+
+ @Override
+ public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
+ if (mor.getCard(game) == null) {
+ discard();
+ return false;
+ }
+ return mor.refersTo(sourceId, game) && source.isControlledBy(affectedControllerId);
+ }
+}
+
+class CovetousUrgeSpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect {
+
+ CovetousUrgeSpendAnyManaEffect() {
+ super(AsThoughEffectType.SPEND_OTHER_MANA, Duration.Custom, Outcome.Benefit);
+ }
+
+ private CovetousUrgeSpendAnyManaEffect(final CovetousUrgeSpendAnyManaEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public CovetousUrgeSpendAnyManaEffect copy() {
+ return new CovetousUrgeSpendAnyManaEffect(this);
+ }
+
+ @Override
+ public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
+ FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
+ return source.isControlledBy(affectedControllerId)
+ && Objects.equals(objectId, fixedTarget.getTarget())
+ && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
+ && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
+ }
+
+ @Override
+ public ManaType getAsThoughManaType(ManaType manaType, ManaPoolItem mana, UUID affectedControllerId, Ability source, Game game) {
+ return mana.getFirstAvailable();
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CracklingDoom.java b/Mage.Sets/src/mage/cards/c/CracklingDoom.java
index 36a5bbc0471..701630c23f1 100644
--- a/Mage.Sets/src/mage/cards/c/CracklingDoom.java
+++ b/Mage.Sets/src/mage/cards/c/CracklingDoom.java
@@ -32,7 +32,7 @@ public final class CracklingDoom extends CardImpl {
public CracklingDoom(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}{W}{B}");
- // Crackling Doom deals 2 damage to each opponent. Each opponent sacrifices a creature with the greatest power among creatures he or she controls.
+ // Crackling Doom deals 2 damage to each opponent. Each opponent sacrifices a creature with the greatest power among creatures they control.
this.getSpellAbility().addEffect(new DamagePlayersEffect(2, TargetController.OPPONENT));
this.getSpellAbility().addEffect(new CracklingDoomEffect());
@@ -52,7 +52,7 @@ class CracklingDoomEffect extends OneShotEffect {
public CracklingDoomEffect() {
super(Outcome.Sacrifice);
- this.staticText = "Each opponent sacrifices a creature with the greatest power among creatures he or she controls";
+ this.staticText = "Each opponent sacrifices a creature with the greatest power among creatures they control";
}
public CracklingDoomEffect(final CracklingDoomEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/CrashingBoars.java b/Mage.Sets/src/mage/cards/c/CrashingBoars.java
index 26678b713cb..b856a04ae54 100644
--- a/Mage.Sets/src/mage/cards/c/CrashingBoars.java
+++ b/Mage.Sets/src/mage/cards/c/CrashingBoars.java
@@ -35,7 +35,7 @@ public final class CrashingBoars extends CardImpl {
this.power = new MageInt(4);
this.toughness = new MageInt(4);
- // Whenever Crashing Boars attacks, defending player chooses an untapped creature he or she controls. That creature block Crashing Boars this turn if able.
+ // Whenever Crashing Boars attacks, defending player chooses an untapped creature they control. That creature block Crashing Boars this turn if able.
this.addAbility(new AttacksTriggeredAbility(new CrashingBoarsEffect(), false, "", SetTargetPointer.PLAYER));
}
@@ -58,7 +58,7 @@ class CrashingBoarsEffect extends OneShotEffect {
CrashingBoarsEffect() {
super(Outcome.Benefit);
- this.staticText = "defending player chooses an untapped creature he or she controls. That creature blocks {this} this turn if able";
+ this.staticText = "defending player chooses an untapped creature they control. That creature blocks {this} this turn if able";
}
CrashingBoarsEffect(final CrashingBoarsEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/CrashingDrawbridge.java b/Mage.Sets/src/mage/cards/c/CrashingDrawbridge.java
new file mode 100644
index 00000000000..fedc7671158
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CrashingDrawbridge.java
@@ -0,0 +1,47 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
+import mage.abilities.keyword.DefenderAbility;
+import mage.abilities.keyword.HasteAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CrashingDrawbridge extends CardImpl {
+
+ public CrashingDrawbridge(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}");
+
+ this.subtype.add(SubType.WALL);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(4);
+
+ // Defender
+ this.addAbility(DefenderAbility.getInstance());
+
+ // {T}: Creatures you control gain haste until end of turn.
+ this.addAbility(new SimpleActivatedAbility(new GainAbilityControlledEffect(
+ HasteAbility.getInstance(), Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURES
+ ), new TapSourceCost()));
+ }
+
+ private CrashingDrawbridge(final CrashingDrawbridge card) {
+ super(card);
+ }
+
+ @Override
+ public CrashingDrawbridge copy() {
+ return new CrashingDrawbridge(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CratersClaws.java b/Mage.Sets/src/mage/cards/c/CratersClaws.java
index a4b2b4dbfb2..a0b6a3d12d6 100644
--- a/Mage.Sets/src/mage/cards/c/CratersClaws.java
+++ b/Mage.Sets/src/mage/cards/c/CratersClaws.java
@@ -28,7 +28,7 @@ public final class CratersClaws extends CardImpl {
new DamageTargetEffect(ManacostVariableValue.instance),
FerociousCondition.instance,
"{this} deals X damage to any target."
- + "
Ferocious — {this} deals X plus 2 damage to that permanent or player instead if you control a creature with power 4 or greater"));
+ + "
Ferocious — {this} deals X plus 2 damage instead if you control a creature with power 4 or greater"));
this.getSpellAbility().addTarget(new TargetAnyTarget());
this.getSpellAbility().addHint(FerociousHint.instance);
}
diff --git a/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java b/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java
index 4d8f96c8abd..d60d4622dbb 100644
--- a/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java
+++ b/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java
@@ -37,7 +37,7 @@ public final class CrimsonHonorGuard extends CardImpl {
// Trample
this.addAbility(TrampleAbility.getInstance());
- // At the beginning of each player's end step, Crimson Honor Guard deals 4 damage to that player unless he or she controls a commander.
+ // At the beginning of each player's end step, Crimson Honor Guard deals 4 damage to that player unless they control a commander.
this.addAbility(new BeginningOfEndStepTriggeredAbility(new CrimsonHonorGuardEffect(), TargetController.ANY, false));
}
@@ -83,6 +83,6 @@ class CrimsonHonorGuardEffect extends OneShotEffect {
@Override
public String getText(Mode mode) {
- return "{this} deals 4 damage to that player unless he or she controls a commander";
+ return "{this} deals 4 damage to that player unless they control a commander";
}
}
diff --git a/Mage.Sets/src/mage/cards/c/CrimsonRoc.java b/Mage.Sets/src/mage/cards/c/CrimsonRoc.java
new file mode 100644
index 00000000000..6b7d68697cd
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CrimsonRoc.java
@@ -0,0 +1,87 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.FirstStrikeAbility;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class CrimsonRoc extends CardImpl {
+
+ public CrimsonRoc(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}");
+
+ this.subtype.add(SubType.BIRD);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Whenever Crimson Roc blocks a creature without flying, Crimson Roc gets +1/+0 and gains first strike until end of turn.
+ this.addAbility(new CrimsonRocTriggeredAbility());
+ }
+
+ private CrimsonRoc(final CrimsonRoc card) {
+ super(card);
+ }
+
+ @Override
+ public CrimsonRoc copy() {
+ return new CrimsonRoc(this);
+ }
+}
+
+class CrimsonRocTriggeredAbility extends TriggeredAbilityImpl {
+
+ CrimsonRocTriggeredAbility() {
+ super(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn), false);
+ this.addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn));
+ }
+
+ private CrimsonRocTriggeredAbility(final CrimsonRocTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.BLOCKER_DECLARED;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ if (!event.getSourceId().equals(this.getSourceId())) {
+ return false;
+ }
+ Permanent permanent = game.getPermanent(event.getTargetId());
+ return permanent != null
+ && permanent.isCreature()
+ && !permanent.getAbilities(game).contains(FlyingAbility.getInstance());
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever {this} blocks a creature without flying, " +
+ "{this} gets +1/+0 and gains first strike until end of turn.";
+ }
+
+ @Override
+ public CrimsonRocTriggeredAbility copy() {
+ return new CrimsonRocTriggeredAbility(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CrownOfFury.java b/Mage.Sets/src/mage/cards/c/CrownOfFury.java
new file mode 100644
index 00000000000..3c3a5e57b09
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CrownOfFury.java
@@ -0,0 +1,104 @@
+
+package mage.cards.c;
+
+import java.util.UUID;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.SacrificeSourceCost;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.continuous.BoostAllEffect;
+import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.abilities.keyword.FirstStrikeAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.common.FilterOtherCreatureSharingCreatureSubtype;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author t-schroeder
+ */
+public final class CrownOfFury extends CardImpl {
+
+ public CrownOfFury(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}");
+ this.subtype.add(SubType.AURA);
+
+ TargetPermanent auraTarget = new TargetCreaturePermanent();
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // Enchanted creature gets +1/+0 and has first strike.
+ Effect effect = new BoostEnchantedEffect(1, 0, Duration.WhileOnBattlefield);
+ effect.setText("enchanted creature gets +1/+0");
+ ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
+ effect = new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.AURA);
+ effect.setText("and has first strike");
+ ability.addEffect(effect);
+ this.addAbility(ability);
+
+ // Sacrifice Crown of Fury: Enchanted creature and other creatures that share a creature type with it get +1/+0 and gain first strike until end of turn.
+ ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CrownOfFuryEffect(), new SacrificeSourceCost());
+ this.addAbility(ability);
+ }
+
+ public CrownOfFury(final CrownOfFury card) {
+ super(card);
+ }
+
+ @Override
+ public CrownOfFury copy() {
+ return new CrownOfFury(this);
+ }
+}
+
+class CrownOfFuryEffect extends OneShotEffect {
+
+ public CrownOfFuryEffect() {
+ super(Outcome.Benefit);
+ this.staticText = "Enchanted creature and other creatures that share a creature type with it get +1/+0 and gain first strike until end of turn.";
+ }
+
+ public CrownOfFuryEffect(final CrownOfFuryEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CrownOfFuryEffect copy() {
+ return new CrownOfFuryEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+
+ // Enchanted creature ...
+ ContinuousEffect effect = new BoostEnchantedEffect(1, 0, Duration.EndOfTurn);
+ game.addEffect(effect, source);
+ effect = new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.AURA, Duration.EndOfTurn);
+ game.addEffect(effect, source);
+
+ // ... and other creatures that share a creature type with it ...
+ Permanent enchantedCreature = game.getPermanent(source.getSourcePermanentOrLKI(game).getAttachedTo());
+ FilterCreaturePermanent filter = new FilterOtherCreatureSharingCreatureSubtype(enchantedCreature, game);
+ game.addEffect(new BoostAllEffect(1, 0, Duration.EndOfTurn, filter, false), source);
+ game.addEffect(new GainAbilityAllEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn, filter), source);
+
+ // ... get +1/+0 and gain first strike until end of turn.
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CruelReality.java b/Mage.Sets/src/mage/cards/c/CruelReality.java
index ed9a9e29046..c4c1d62e3c9 100644
--- a/Mage.Sets/src/mage/cards/c/CruelReality.java
+++ b/Mage.Sets/src/mage/cards/c/CruelReality.java
@@ -43,7 +43,7 @@ public final class CruelReality extends CardImpl {
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Damage));
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
- //At the beginning of enchanted player's upkeep, that player sacrifices a creature or planeswalker. If the player can't, he or she loses 5 life.
+ //At the beginning of enchanted player's upkeep, that player sacrifices a creature or planeswalker. If the player can't, they lose 5 life.
this.addAbility(new CruelRealityTriggeredAbiilty());
}
@@ -103,7 +103,7 @@ class CruelRealityEffect extends OneShotEffect {
public CruelRealityEffect() {
super(Outcome.LoseLife);
- staticText = "that player sacrifices a creature or planeswalker. If the player can't, he or she loses 5 life";
+ staticText = "that player sacrifices a creature or planeswalker. If the player can't, they lose 5 life";
}
public CruelRealityEffect(final CruelRealityEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/CryptIncursion.java b/Mage.Sets/src/mage/cards/c/CryptIncursion.java
index b9ea02c5621..81a8ce6eecc 100644
--- a/Mage.Sets/src/mage/cards/c/CryptIncursion.java
+++ b/Mage.Sets/src/mage/cards/c/CryptIncursion.java
@@ -1,5 +1,3 @@
-
-
package mage.cards.c;
import java.util.UUID;
@@ -10,7 +8,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
@@ -19,19 +17,15 @@ import mage.target.TargetPlayer;
*
* @author LevelX2
*/
-
-
public final class CryptIncursion extends CardImpl {
public CryptIncursion(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{B}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}");
// Exile all creature cards from target player's graveyard. You gain 3 life for each card exiled this way.
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new CryptIncursionEffect());
-
}
public CryptIncursion(final CryptIncursion card) {
@@ -47,8 +41,6 @@ public final class CryptIncursion extends CardImpl {
class CryptIncursionEffect extends OneShotEffect {
- private static final FilterCreatureCard filter = new FilterCreatureCard();
-
public CryptIncursionEffect() {
super(Outcome.Detriment);
staticText = "Exile all creature cards from target player's graveyard. You gain 3 life for each card exiled this way";
@@ -64,8 +56,8 @@ class CryptIncursionEffect extends OneShotEffect {
Player targetPlayer = game.getPlayer(source.getFirstTarget());
if (player != null && targetPlayer != null) {
int exiledCards = 0;
- for (Card card: targetPlayer.getGraveyard().getCards(game)) {
- if (filter.match(card, game)) {
+ for (Card card : targetPlayer.getGraveyard().getCards(game)) {
+ if (StaticFilters.FILTER_CARD_CREATURE.match(card, game)) {
if (card.moveToExile(null, "", source.getSourceId(), game)) {
exiledCards++;
}
diff --git a/Mage.Sets/src/mage/cards/c/CrystalSlipper.java b/Mage.Sets/src/mage/cards/c/CrystalSlipper.java
new file mode 100644
index 00000000000..c17e1b2753e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CrystalSlipper.java
@@ -0,0 +1,48 @@
+package mage.cards.c;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.continuous.BoostEquippedEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.abilities.keyword.EquipAbility;
+import mage.abilities.keyword.HasteAbility;
+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 java.util.UUID;
+
+/**
+ * @author jmharmon
+ */
+
+public final class CrystalSlipper extends CardImpl {
+
+ public CrystalSlipper(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{R}");
+ this.subtype.add(SubType.EQUIPMENT);
+
+ // Equipped creature gets +1/+0 and has haste.
+ Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(1, 0));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ HasteAbility.getInstance(), AttachmentType.EQUIPMENT).setText("and has haste")
+ );
+ this.addAbility(ability);
+
+ // Equip {1}
+ this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(1)));
+ }
+
+ public CrystalSlipper(final CrystalSlipper card) {
+ super(card);
+ }
+
+ @Override
+ public CrystalSlipper copy() {
+ return new CrystalSlipper(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CunningAbduction.java b/Mage.Sets/src/mage/cards/c/CunningAbduction.java
index 48553cd2ea5..e070eaf1aaa 100644
--- a/Mage.Sets/src/mage/cards/c/CunningAbduction.java
+++ b/Mage.Sets/src/mage/cards/c/CunningAbduction.java
@@ -1,6 +1,5 @@
package mage.cards.c;
-import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.AsThoughEffectImpl;
@@ -21,8 +20,9 @@ import mage.target.common.TargetOpponent;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
+import java.util.UUID;
+
/**
- *
* @author Styxo
*/
public final class CunningAbduction extends CardImpl {
@@ -122,15 +122,11 @@ class CunningAbductionSpendAnyManaEffect extends AsThoughEffectImpl implements A
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
- objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget())
&& game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
- if (affectedControllerId.equals(source.getControllerId())) {
- // if the card moved from exile to spell the zone change counter is increased by 1
- if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
- return true;
- }
- }
+ // if the card moved from exile to spell the zone change counter is increased by 1 (effect must applies before and on stack, use isCheckPlayableMode?)
+ return affectedControllerId.equals(source.getControllerId());
} else if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
// object has moved zone so effect can be discarted
this.discard();
diff --git a/Mage.Sets/src/mage/cards/c/Curfew.java b/Mage.Sets/src/mage/cards/c/Curfew.java
index 2db339d536a..5e93b5103e8 100644
--- a/Mage.Sets/src/mage/cards/c/Curfew.java
+++ b/Mage.Sets/src/mage/cards/c/Curfew.java
@@ -25,7 +25,7 @@ public final class Curfew extends CardImpl {
public Curfew(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}");
- // Each player returns a creature he or she controls to its owner's hand.
+ // Each player returns a creature they control to its owner's hand.
this.getSpellAbility().addEffect(new CurfewEffect());
}
@@ -43,12 +43,12 @@ class CurfewEffect extends OneShotEffect {
public CurfewEffect() {
super(Outcome.ReturnToHand);
- staticText = "Each player returns a creature he or she controls to its owner's hand";
+ staticText = "Each player returns a creature they control to its owner's hand";
}
@Override
public boolean apply(Game game, Ability source) {
- game.informPlayers("Each player returns a creature he or she controls to its owner's hand");
+ game.informPlayers("Each player returns a creature they control to its owner's hand");
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null && game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, playerId, game) > 0) {
diff --git a/Mage.Sets/src/mage/cards/c/CuriousPair.java b/Mage.Sets/src/mage/cards/c/CuriousPair.java
new file mode 100644
index 00000000000..febc9db70ed
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/CuriousPair.java
@@ -0,0 +1,39 @@
+package mage.cards.c;
+
+import mage.MageInt;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.cards.AdventureCard;
+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 CuriousPair extends AdventureCard {
+
+ public CuriousPair(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{1}{G}", "Treats to Share", "{G}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.PEASANT);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(3);
+
+ // Treats to Share
+ // Create a Food token.
+ this.getSpellCard().getSpellAbility().addEffect(new CreateTokenEffect(new FoodToken()));
+ }
+
+ private CuriousPair(final CuriousPair card) {
+ super(card);
+ }
+
+ @Override
+ public CuriousPair copy() {
+ return new CuriousPair(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CurseArtifact.java b/Mage.Sets/src/mage/cards/c/CurseArtifact.java
index 812a9167018..039ad782061 100644
--- a/Mage.Sets/src/mage/cards/c/CurseArtifact.java
+++ b/Mage.Sets/src/mage/cards/c/CurseArtifact.java
@@ -36,11 +36,11 @@ public final class CurseArtifact extends CardImpl {
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
- // At the beginning of the upkeep of enchanted artifact's controller, Curse Artifact deals 2 damage to that player unless he or she sacrifices that artifact.
+ // At the beginning of the upkeep of enchanted artifact's controller, Curse Artifact deals 2 damage to that player unless they sacrifice that artifact.
Cost cost = new SacrificeAttachedCost();
cost.setText("sacrifice attached artifact");
Effect effect = new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new DamageTargetEffect(2), cost, "Sacrifice enchanted artifact? (otherwise {this} deals 2 damage to you)");
- effect.setText("{this} deals 2 damage to that player unless he or she sacrifices that artifact");
+ effect.setText("{this} deals 2 damage to that player unless they sacrifice that artifact");
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.CONTROLLER_ATTACHED_TO, false, true, "At the beginning of the upkeep of enchanted artifact's controller, "));
}
diff --git a/Mage.Sets/src/mage/cards/c/CurseOfBounty.java b/Mage.Sets/src/mage/cards/c/CurseOfBounty.java
index 4c853ed2818..292f0e91ca1 100644
--- a/Mage.Sets/src/mage/cards/c/CurseOfBounty.java
+++ b/Mage.Sets/src/mage/cards/c/CurseOfBounty.java
@@ -39,7 +39,7 @@ public final class CurseOfBounty extends CardImpl {
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
// Whenever enchanted player is attacked, untap all nonland permanents you control.
- // Each opponent attacking that player untaps all nonland permanents he or she controls.
+ // Each opponent attacking that player untaps all nonland permanents they control.
this.addAbility(new EnchantedPlayerAttackedTriggeredAbility(new CurseOfBountyEffect()));
}
diff --git a/Mage.Sets/src/mage/cards/c/CurseOfChaos.java b/Mage.Sets/src/mage/cards/c/CurseOfChaos.java
index 53b0c265ac9..d4892429397 100644
--- a/Mage.Sets/src/mage/cards/c/CurseOfChaos.java
+++ b/Mage.Sets/src/mage/cards/c/CurseOfChaos.java
@@ -38,7 +38,7 @@ public final class CurseOfChaos extends CardImpl {
this.getSpellAbility().addEffect(new AttachEffect(Outcome.DrawCard));
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
- // Whenever a player attacks enchanted player with one or more creatures, that attacking player may discard a card. If the player does, he or she draws a card.
+ // Whenever a player attacks enchanted player with one or more creatures, that attacking player may discard a card. If the player does, they draw a card.
this.addAbility(new CurseOfChaosTriggeredAbility());
}
@@ -97,7 +97,7 @@ class CurseOfChaosEffect extends OneShotEffect {
public CurseOfChaosEffect() {
super(Outcome.Benefit);
- this.staticText = "that attacking player may discard a card. If the player does, he or she draws a card";
+ this.staticText = "that attacking player may discard a card. If the player does, they draw a card";
}
public CurseOfChaosEffect(final CurseOfChaosEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/CurseOfEchoes.java b/Mage.Sets/src/mage/cards/c/CurseOfEchoes.java
index ff670fab1a4..dac64b90fa9 100644
--- a/Mage.Sets/src/mage/cards/c/CurseOfEchoes.java
+++ b/Mage.Sets/src/mage/cards/c/CurseOfEchoes.java
@@ -41,7 +41,7 @@ public final class CurseOfEchoes extends CardImpl {
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Damage));
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
- // Whenever enchanted player casts an instant or sorcery spell, each other player may copy that spell and may choose new targets for the copy he or she controls.
+ // Whenever enchanted player casts an instant or sorcery spell, each other player may copy that spell and may choose new targets for the copy they control.
this.addAbility(new CurseOfEchoesCopyTriggeredAbility());
}
@@ -101,7 +101,7 @@ class CurseOfEchoesCopyTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
- return "Whenever enchanted player casts an instant or sorcery spell, each other player may copy that spell and may choose new targets for the copy he or she controls.";
+ return "Whenever enchanted player casts an instant or sorcery spell, each other player may copy that spell and may choose new targets for the copy they control.";
}
}
diff --git a/Mage.Sets/src/mage/cards/c/CurseOfTheCabal.java b/Mage.Sets/src/mage/cards/c/CurseOfTheCabal.java
index c1751ec8077..7cf0bfda698 100644
--- a/Mage.Sets/src/mage/cards/c/CurseOfTheCabal.java
+++ b/Mage.Sets/src/mage/cards/c/CurseOfTheCabal.java
@@ -38,14 +38,14 @@ public final class CurseOfTheCabal extends CardImpl {
public CurseOfTheCabal(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{9}{B}");
- // Target player sacrifices half the permanents he or she controls, rounded down.
+ // Target player sacrifices half the permanents they control, rounded down.
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new CurseOfTheCabalSacrificeEffect());
// Suspend 2-{2}{B}{B}
this.addAbility(new SuspendAbility(2, new ManaCostsImpl("{2}{B}{B}"), this));
- // At the beginning of each player's upkeep, if Curse of the Cabal is suspended, that player may sacrifice a permanent. If he or she does, put two time counters on Curse of the Cabal.
+ // At the beginning of each player's upkeep, if Curse of the Cabal is suspended, that player may sacrifice a permanent. If they do, put two time counters on Curse of the Cabal.
this.addAbility(new CurseOfTheCabalInterveningIfTriggeredAbility());
}
@@ -64,7 +64,7 @@ class CurseOfTheCabalSacrificeEffect extends OneShotEffect {
public CurseOfTheCabalSacrificeEffect() {
super(Outcome.Sacrifice);
- this.staticText = "Target player sacrifices half the permanents he or she controls, rounded down.";
+ this.staticText = "Target player sacrifices half the permanents they control, rounded down.";
}
public CurseOfTheCabalSacrificeEffect(final CurseOfTheCabalSacrificeEffect effect) {
@@ -111,7 +111,7 @@ class CurseOfTheCabalInterveningIfTriggeredAbility extends ConditionalIntervenin
),
SuspendedCondition.instance,
"At the beginning of each player's upkeep, if {this} is suspended, "
- + "that player may sacrifice a permanent. If he or she does, "
+ + "that player may sacrifice a permanent. If they do, "
+ "put two time counters on {this}."
);
// controller has to sac a permanent
diff --git a/Mage.Sets/src/mage/cards/c/CurseOfThirst.java b/Mage.Sets/src/mage/cards/c/CurseOfThirst.java
index 05e564079e5..9864782728f 100644
--- a/Mage.Sets/src/mage/cards/c/CurseOfThirst.java
+++ b/Mage.Sets/src/mage/cards/c/CurseOfThirst.java
@@ -39,7 +39,7 @@ public final class CurseOfThirst extends CardImpl {
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
- // At the beginning of enchanted player's upkeep, Curse of Thirst deals damage to that player equal to the number of Curses attached to him or her.
+ // At the beginning of enchanted player's upkeep, Curse of Thirst deals damage to that player equal to the number of Curses attached to them.
this.addAbility(new CurseOfThirstAbility());
}
@@ -90,7 +90,7 @@ class CurseOfThirstAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
return "At the beginning of enchanted player's upkeep, Curse of Thirst "
- + "deals damage to that player equal to the number of Curses attached to him or her.";
+ + "deals damage to that player equal to the number of Curses attached to them.";
}
}
@@ -130,6 +130,6 @@ class CursesAttachedCount implements DynamicValue {
@Override
public String getMessage() {
- return "number of Curses attached to him or her";
+ return "number of Curses attached to them";
}
}
diff --git a/Mage.Sets/src/mage/cards/d/DanceOfTheDead.java b/Mage.Sets/src/mage/cards/d/DanceOfTheDead.java
index 01eccf78337..e5c70512b6b 100644
--- a/Mage.Sets/src/mage/cards/d/DanceOfTheDead.java
+++ b/Mage.Sets/src/mage/cards/d/DanceOfTheDead.java
@@ -70,7 +70,7 @@ public final class DanceOfTheDead extends CardImpl {
ability.addEffect(effect);
this.addAbility(ability);
- // At the beginning of the upkeep of enchanted creature's controller, that player may pay {1}{B}. If he or she does, untap that creature.
+ // At the beginning of the upkeep of enchanted creature's controller, that player may pay {1}{B}. If they do, untap that creature.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DanceOfTheDeadDoIfCostPaidEffect(), TargetController.CONTROLLER_ATTACHED_TO, false));
}
@@ -279,6 +279,6 @@ class DanceOfTheDeadDoIfCostPaidEffect extends DoIfCostPaid {
@Override
public String getText(Mode mode) {
- return "that player may " + getCostText() + ". If he or she does, " + executingEffects.getText(mode);
+ return "that player may " + getCostText() + ". If they do, " + executingEffects.getText(mode);
}
}
diff --git a/Mage.Sets/src/mage/cards/d/DanceOfTheManse.java b/Mage.Sets/src/mage/cards/d/DanceOfTheManse.java
new file mode 100644
index 00000000000..b46a38d00ce
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/d/DanceOfTheManse.java
@@ -0,0 +1,122 @@
+package mage.cards.d;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.AddCardTypeTargetEffect;
+import mage.abilities.effects.common.continuous.SetPowerToughnessTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.cards.Cards;
+import mage.cards.CardsImpl;
+import mage.constants.*;
+import mage.filter.FilterCard;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.Target;
+import mage.target.common.TargetCardInYourGraveyard;
+import mage.target.targetadjustment.TargetAdjuster;
+import mage.target.targetpointer.FixedTarget;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * @author TheElk801
+ */
+public final class DanceOfTheManse extends CardImpl {
+
+ public DanceOfTheManse(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{W}{U}");
+
+ // Return up to X target artifact and/or non-Aura enchantment cards each with converted mana cost X or less from your graveyard to the battlefield. If X is 6 or more, those permanents are 4/4 creatures in addition to their other types.
+ this.getSpellAbility().addEffect(new DanceOfTheManseEffect());
+ this.getSpellAbility().setTargetAdjuster(DanceOfTheManseAdjuster.instance);
+ }
+
+ private DanceOfTheManse(final DanceOfTheManse card) {
+ super(card);
+ }
+
+ @Override
+ public DanceOfTheManse copy() {
+ return new DanceOfTheManse(this);
+ }
+}
+
+enum DanceOfTheManseAdjuster implements TargetAdjuster {
+ instance;
+
+ @Override
+ public void adjustTargets(Ability ability, Game game) {
+ int xValue = ability.getManaCostsToPay().getX();
+ FilterCard filter = new FilterCard("artifact and/or non-Aura enchantment cards " +
+ "each with converted mana cost " + xValue + " or less from your graveyard");
+ filter.add(Predicates.or(
+ new CardTypePredicate(CardType.ARTIFACT),
+ Predicates.and(
+ new CardTypePredicate(CardType.ENCHANTMENT),
+ Predicates.not(new SubtypePredicate(SubType.AURA))
+ )
+ ));
+ filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xValue + 1));
+ ability.getTargets().clear();
+ ability.addTarget(new TargetCardInYourGraveyard(0, xValue, filter));
+ }
+}
+
+class DanceOfTheManseEffect extends OneShotEffect {
+
+ DanceOfTheManseEffect() {
+ super(Outcome.Benefit);
+ staticText = "Return up to X target artifact and/or non-Aura enchantment cards " +
+ "each with converted mana cost X or less from your graveyard to the battlefield. " +
+ "If X is 6 or more, those permanents are 4/4 creatures in addition to their other types.";
+ }
+
+ private DanceOfTheManseEffect(final DanceOfTheManseEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public DanceOfTheManseEffect copy() {
+ return new DanceOfTheManseEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ Cards cards = new CardsImpl(source
+ .getTargets()
+ .stream()
+ .map(Target::getTargets)
+ .flatMap(Collection::stream)
+ .map(game::getCard)
+ .collect(Collectors.toSet()));
+ player.moveCards(cards, Zone.BATTLEFIELD, source, game);
+ if (source.getManaCostsToPay().getX() < 6) {
+ return true;
+ }
+ cards.stream()
+ .map(game::getPermanent)
+ .filter(Objects::nonNull)
+ .forEach(permanent -> {
+ ContinuousEffect effect = new AddCardTypeTargetEffect(Duration.EndOfGame, CardType.CREATURE);
+ effect.setTargetPointer(new FixedTarget(permanent, game));
+ game.addEffect(effect, source);
+ effect = new SetPowerToughnessTargetEffect(4, 4, Duration.EndOfGame);
+ effect.setTargetPointer(new FixedTarget(permanent, game));
+ game.addEffect(effect, source);
+ });
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java b/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java
index 713cded9566..761505e9d42 100644
--- a/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java
+++ b/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java
@@ -1,4 +1,3 @@
-
package mage.cards.d;
import mage.abilities.Ability;
@@ -14,10 +13,8 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
-import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterArtifactCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.permanent.token.DarettiConstructToken;
@@ -34,8 +31,6 @@ public final class DarettiIngeniousIconoclast extends CardImpl {
private static final FilterPermanent filter
= new FilterPermanent("artifact or creature (to destroy)");
- private static final FilterCard filter2
- = new FilterArtifactCard("artifact card in a graveyard or artifact on the battlefield");
static {
filter.add(Predicates.or(
@@ -72,7 +67,8 @@ public final class DarettiIngeniousIconoclast extends CardImpl {
.setText("Choose target artifact card in a graveyard or artifact on the battlefield. " +
"Create three tokens that are copies of it"), -6
);
- ability.addTarget(new TargetCardInGraveyardOrBattlefield(filter2));
+ ability.addTarget(new TargetCardInGraveyardOrBattlefield(1, 1,
+ StaticFilters.FILTER_CARD_ARTIFACT, StaticFilters.FILTER_PERMANENT_ARTIFACT));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/d/DarigaazsCharm.java b/Mage.Sets/src/mage/cards/d/DarigaazsCharm.java
index 68bc7456288..3524db97de4 100644
--- a/Mage.Sets/src/mage/cards/d/DarigaazsCharm.java
+++ b/Mage.Sets/src/mage/cards/d/DarigaazsCharm.java
@@ -1,4 +1,3 @@
-
package mage.cards.d;
import java.util.UUID;
@@ -11,9 +10,9 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
-import mage.filter.common.FilterCreatureCard;
-import mage.target.common.TargetCardInYourGraveyard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetAnyTarget;
+import mage.target.common.TargetCardInYourGraveyard;
import mage.target.common.TargetCreaturePermanent;
/**
@@ -23,13 +22,13 @@ import mage.target.common.TargetCreaturePermanent;
public final class DarigaazsCharm extends CardImpl {
public DarigaazsCharm(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}{R}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}{R}{G}");
// Choose one - Return target creature card from your graveyard to your hand;
Effect effect = new ReturnToHandTargetEffect();
effect.setText("Return target creature card from your graveyard to your hand");
this.getSpellAbility().addEffect(effect);
- this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard()));
+ this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE));
// or Darigaaz's Charm deals 3 damage to any target;
Mode mode = new Mode();
diff --git a/Mage.Sets/src/mage/cards/d/DawnglowInfusion.java b/Mage.Sets/src/mage/cards/d/DawnglowInfusion.java
index 7faec30b05a..bf930dca29e 100644
--- a/Mage.Sets/src/mage/cards/d/DawnglowInfusion.java
+++ b/Mage.Sets/src/mage/cards/d/DawnglowInfusion.java
@@ -28,7 +28,7 @@ public final class DawnglowInfusion extends CardImpl {
DynamicValue xValue = ManacostVariableValue.instance;
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new GainLifeEffect(xValue),
- new ManaWasSpentCondition(ColoredManaSymbol.G), "You gain X life if {G} was spent to cast {this}"));
+ new ManaWasSpentCondition(ColoredManaSymbol.G), "You gain X life if {G} was spent to cast this spell"));
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new GainLifeEffect(xValue),
new ManaWasSpentCondition(ColoredManaSymbol.W), " And X life if {W} was spent to cast it"));
diff --git a/Mage.Sets/src/mage/cards/d/DaxosBlessedByTheSun.java b/Mage.Sets/src/mage/cards/d/DaxosBlessedByTheSun.java
new file mode 100644
index 00000000000..d03488133f3
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/d/DaxosBlessedByTheSun.java
@@ -0,0 +1,88 @@
+package mage.cards.d;
+
+import mage.MageInt;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.common.DevotionCount;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.effects.common.continuous.SetToughnessSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.events.ZoneChangeEvent;
+import mage.game.permanent.Permanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class DaxosBlessedByTheSun extends CardImpl {
+
+ public DaxosBlessedByTheSun(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{W}{W}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.DEMIGOD);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(0);
+
+ // Daxos's toughness is equal to your devotion to white.
+ this.addAbility(new SimpleStaticAbility(
+ Zone.ALL,
+ new SetToughnessSourceEffect(DevotionCount.W, Duration.EndOfGame)
+ .setText("{this}'s toughness is equal to your devotion to white")
+ ).addHint(DevotionCount.W.getHint()));
+
+ // Whenever another creature you control enters the battlefield or dies, you gain 1 life.
+ this.addAbility(new DaxosBlessedByTheSunAbility());
+ }
+
+ private DaxosBlessedByTheSun(final DaxosBlessedByTheSun card) {
+ super(card);
+ }
+
+ @Override
+ public DaxosBlessedByTheSun copy() {
+ return new DaxosBlessedByTheSun(this);
+ }
+}
+
+class DaxosBlessedByTheSunAbility extends TriggeredAbilityImpl {
+
+ DaxosBlessedByTheSunAbility() {
+ super(Zone.BATTLEFIELD, new GainLifeEffect(1));
+ }
+
+ private DaxosBlessedByTheSunAbility(DaxosBlessedByTheSunAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD)
+ || (event.getType() == GameEvent.EventType.ZONE_CHANGE
+ && ((ZoneChangeEvent) event).isDiesEvent());
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ if (event.getTargetId().equals(this.getSourceId())) {
+ return false;
+ }
+ Permanent creature = game.getPermanentOrLKIBattlefield(event.getTargetId());
+ return creature != null && creature.isControlledBy(this.getControllerId());
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever another creature you control enters the battlefield or dies, you gain 1 life.";
+ }
+
+ @Override
+ public DaxosBlessedByTheSunAbility copy() {
+ return new DaxosBlessedByTheSunAbility(this);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java b/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java
index e9cc5916243..2611031369b 100644
--- a/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java
+++ b/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java
@@ -1,7 +1,5 @@
package mage.cards.d;
-import java.util.Objects;
-import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
@@ -26,8 +24,10 @@ import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
+import java.util.Objects;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class DaxosOfMeletis extends CardImpl {
@@ -177,12 +177,12 @@ class DaxosOfMeletisSpendAnyManaEffect extends AsThoughEffectImpl implements AsT
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
- objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
+ FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
return source.isControlledBy(affectedControllerId)
- && Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget())
- && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)
- && (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId))
- && game.getState().getZone(objectId) == Zone.STACK;
+ && Objects.equals(objectId, fixedTarget.getTarget())
+ && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
+ && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/d/DeadMansChest.java b/Mage.Sets/src/mage/cards/d/DeadMansChest.java
index 284ec871fbb..1a20378b824 100644
--- a/Mage.Sets/src/mage/cards/d/DeadMansChest.java
+++ b/Mage.Sets/src/mage/cards/d/DeadMansChest.java
@@ -1,7 +1,5 @@
package mage.cards.d;
-import java.util.Set;
-import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.DiesAttachedTriggeredAbility;
@@ -15,14 +13,7 @@ import mage.abilities.keyword.EnchantAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.AsThoughEffectType;
-import mage.constants.CardType;
-import mage.constants.Duration;
-import mage.constants.ManaType;
-import mage.constants.Outcome;
-import mage.constants.SubType;
-import mage.constants.TargetController;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
@@ -31,9 +22,12 @@ import mage.players.ManaPoolItem;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTarget;
+import mage.util.CardUtil;
+
+import java.util.Set;
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class DeadMansChest extends CardImpl {
@@ -142,9 +136,7 @@ class DeadMansChestCastFromExileEffect extends AsThoughEffectImpl {
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (objectId.equals(getTargetPointer().getFirst(game, source))) {
- if (affectedControllerId.equals(source.getControllerId())) {
- return true;
- }
+ return affectedControllerId.equals(source.getControllerId());
} else {
if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
// object has moved zone so effect can be discarted
@@ -178,15 +170,11 @@ class DeadMansChestSpendManaEffect extends AsThoughEffectImpl implements AsThoug
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
- objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget())
&& game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
- if (affectedControllerId.equals(source.getControllerId())) {
- // if the card moved from exile to spell the zone change counter is increased by 1
- if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
- return true;
- }
- }
+ // if the card moved from exile to spell the zone change counter is increased by 1 (effect must applies before and on stack, use isCheckPlayableMode?)
+ return affectedControllerId.equals(source.getControllerId());
} else {
if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
// object has moved zone so effect can be discarted
diff --git a/Mage.Sets/src/mage/cards/d/DeadRingers.java b/Mage.Sets/src/mage/cards/d/DeadRingers.java
index 476e4578cb5..e07ca86f513 100644
--- a/Mage.Sets/src/mage/cards/d/DeadRingers.java
+++ b/Mage.Sets/src/mage/cards/d/DeadRingers.java
@@ -1,4 +1,3 @@
-
package mage.cards.d;
import java.util.UUID;
@@ -29,7 +28,7 @@ public final class DeadRingers extends CardImpl {
}
public DeadRingers(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}");
// Destroy two target nonblack creatures unless either one is a color the other isn't. They can't be regenerated.
this.getSpellAbility().addEffect(new DeadRingersEffect());
@@ -65,10 +64,15 @@ class DeadRingersEffect extends DestroyTargetEffect {
@Override
public boolean apply(Game game, Ability source) {
Target target = source.getTargets().get(0);
- Permanent first = game.getPermanentOrLKIBattlefield(target.getTargets().get(0));
- Permanent second = game.getPermanentOrLKIBattlefield(target.getTargets().get(1));
- if(first != null && second != null && first.getColor(game).equals(second.getColor(game))) {
- return super.apply(game, source);
+ if (target != null
+ && target.getTargets().size() > 1) {
+ Permanent first = game.getPermanentOrLKIBattlefield(target.getTargets().get(0));
+ Permanent second = game.getPermanentOrLKIBattlefield(target.getTargets().get(1));
+ if (first != null
+ && second != null
+ && first.getColor(game).equals(second.getColor(game))) {
+ return super.apply(game, source);
+ }
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/d/DeadlyAllure.java b/Mage.Sets/src/mage/cards/d/DeadlyAllure.java
index 0191d316bc2..bfe8ce12aae 100644
--- a/Mage.Sets/src/mage/cards/d/DeadlyAllure.java
+++ b/Mage.Sets/src/mage/cards/d/DeadlyAllure.java
@@ -3,6 +3,7 @@ package mage.cards.d;
import java.util.UUID;
import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.Effect;
import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.DeathtouchAbility;
@@ -26,7 +27,9 @@ public final class DeadlyAllure extends CardImpl {
// Target creature gains deathtouch until end of turn and must be blocked this turn if able.
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn));
- this.getSpellAbility().addEffect(new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn));
+ Effect effect = new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn);
+ effect.setText("and must be blocked this turn if able");
+ this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Flashback {G}
diff --git a/Mage.Sets/src/mage/cards/d/DeadlyTempest.java b/Mage.Sets/src/mage/cards/d/DeadlyTempest.java
index 954e2de63fb..e09fbd1f653 100644
--- a/Mage.Sets/src/mage/cards/d/DeadlyTempest.java
+++ b/Mage.Sets/src/mage/cards/d/DeadlyTempest.java
@@ -25,7 +25,7 @@ public final class DeadlyTempest extends CardImpl {
public DeadlyTempest(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}{B}");
- // Destroy all creatures. Each player loses life equal to the number of creatures he or she controlled that were destroyed this way.
+ // Destroy all creatures. Each player loses life equal to the number of creatures they controlled that were destroyed this way.
getSpellAbility().addEffect(new DeadlyTempestEffect());
}
@@ -43,7 +43,7 @@ class DeadlyTempestEffect extends OneShotEffect {
public DeadlyTempestEffect() {
super(Outcome.DestroyPermanent);
- this.staticText = "Destroy all creatures. Each player loses life equal to the number of creatures he or she controlled that were destroyed this way";
+ this.staticText = "Destroy all creatures. Each player loses life equal to the number of creatures they controlled that were destroyed this way";
}
public DeadlyTempestEffect(final DeadlyTempestEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/d/DeafeningSilence.java b/Mage.Sets/src/mage/cards/d/DeafeningSilence.java
new file mode 100644
index 00000000000..247b09f06ea
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/d/DeafeningSilence.java
@@ -0,0 +1,133 @@
+package mage.cards.d;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
+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.WatcherScope;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.stack.Spell;
+import mage.watchers.Watcher;
+
+/**
+ * @author TheElk801
+ */
+public final class DeafeningSilence extends CardImpl {
+
+ public DeafeningSilence(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}");
+
+ // Each player can't cast more than one noncreature spell each turn.
+ this.addAbility(new SimpleStaticAbility(new DeafeningSilenceEffect()), new DeafeningSilenceWatcher());
+ }
+
+ private DeafeningSilence(final DeafeningSilence card) {
+ super(card);
+ }
+
+ @Override
+ public DeafeningSilence copy() {
+ return new DeafeningSilence(this);
+ }
+}
+
+class DeafeningSilenceEffect extends ContinuousRuleModifyingEffectImpl {
+
+ DeafeningSilenceEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.Detriment);
+ staticText = "Each player can't cast more than one noncreature spell each turn";
+ }
+
+ private DeafeningSilenceEffect(final DeafeningSilenceEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public String getInfoMessage(Ability source, GameEvent event, Game game) {
+ return "Each player can't cast more than one noncreature spell each turn";
+ }
+
+ @Override
+ public DeafeningSilenceEffect copy() {
+ return new DeafeningSilenceEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @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) {
+ Card card = game.getCard(event.getSourceId());
+ if (card == null
+ || card.isCreature()) {
+ return false;
+ }
+ DeafeningSilenceWatcher watcher = game.getState().getWatcher(DeafeningSilenceWatcher.class);
+ return watcher != null
+ && watcher.spellsCastByPlayerThisTurnNonCreature(event.getPlayerId()) > 0;
+ }
+}
+
+class DeafeningSilenceWatcher extends Watcher {
+
+ private final Map spellsCastByPlayerThisTurnNonCreature = new HashMap<>();
+
+ DeafeningSilenceWatcher() {
+ super(WatcherScope.GAME);
+ }
+
+ private DeafeningSilenceWatcher(final DeafeningSilenceWatcher watcher) {
+ super(watcher);
+ for (Map.Entry entry : watcher.spellsCastByPlayerThisTurnNonCreature.entrySet()) {
+ spellsCastByPlayerThisTurnNonCreature.put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ @Override
+ public void watch(GameEvent event, Game game) {
+ if (event.getType() != GameEvent.EventType.SPELL_CAST) {
+ return;
+ }
+ Spell spell = game.getSpell(event.getTargetId());
+ if (spell == null
+ || spell.isCreature()) {
+ return;
+ }
+ UUID playerId = event.getPlayerId();
+ if (playerId != null) {
+ spellsCastByPlayerThisTurnNonCreature.putIfAbsent(playerId, 0);
+ spellsCastByPlayerThisTurnNonCreature.compute(playerId, (k, v) -> v + 1);
+ }
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ spellsCastByPlayerThisTurnNonCreature.clear();
+ }
+
+ public int spellsCastByPlayerThisTurnNonCreature(UUID playerId) {
+ return spellsCastByPlayerThisTurnNonCreature.getOrDefault(playerId, 0);
+ }
+
+ @Override
+ public DeafeningSilenceWatcher copy() {
+ return new DeafeningSilenceWatcher(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/d/DeathCharmer.java b/Mage.Sets/src/mage/cards/d/DeathCharmer.java
index db7ac183d67..943c0059ff3 100644
--- a/Mage.Sets/src/mage/cards/d/DeathCharmer.java
+++ b/Mage.Sets/src/mage/cards/d/DeathCharmer.java
@@ -25,7 +25,7 @@ public final class DeathCharmer extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- // Whenever Death Charmer deals combat damage to a creature, that creature's controller loses 2 life unless he or she pays {2}.
+ // Whenever Death Charmer deals combat damage to a creature, that creature's controller loses 2 life unless they pay {2}.
this.addAbility(new DealsCombatDamageToACreatureTriggeredAbility(new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new LoseLifeTargetControllerEffect(2), new ManaCostsImpl("{2}")), false, true));
}
diff --git a/Mage.Sets/src/mage/cards/d/DeathOrGlory.java b/Mage.Sets/src/mage/cards/d/DeathOrGlory.java
index 85efe75cd08..47ef739d616 100644
--- a/Mage.Sets/src/mage/cards/d/DeathOrGlory.java
+++ b/Mage.Sets/src/mage/cards/d/DeathOrGlory.java
@@ -1,4 +1,3 @@
-
package mage.cards.d;
import java.util.ArrayList;
@@ -18,7 +17,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.Target;
@@ -68,7 +67,7 @@ class DeathOrGloryEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- Cards cards = new CardsImpl(controller.getGraveyard().getCards(new FilterCreatureCard(), game));
+ Cards cards = new CardsImpl(controller.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game));
if (!cards.isEmpty()) {
TargetCard targetCards = new TargetCard(0, cards.size(), Zone.EXILED, new FilterCard("cards to put in the first pile"));
List pile1 = new ArrayList<>();
@@ -88,7 +87,7 @@ class DeathOrGloryEffect extends OneShotEffect {
StringBuilder sb = new StringBuilder("First pile of ").append(controller.getLogName()).append(": ");
sb.append(pile1.stream().map(Card::getLogName).collect(Collectors.joining(", ")));
game.informPlayers(sb.toString());
-
+
sb = new StringBuilder("Second pile of ").append(controller.getLogName()).append(": ");
sb.append(pile2.stream().map(Card::getLogName).collect(Collectors.joining(", ")));
game.informPlayers(sb.toString());
@@ -100,7 +99,7 @@ class DeathOrGloryEffect extends OneShotEffect {
Target targetOpponent = new TargetOpponent(true);
if (controller.chooseTarget(Outcome.Neutral, targetOpponent, source, game)) {
opponent = game.getPlayer(targetOpponent.getFirstTarget());
- game.informPlayers(controller.getLogName() + " chose " + opponent.getLogName() + " to choose his pile");
+ game.informPlayers(controller.getLogName() + " chose " + opponent.getLogName() + " to choose their pile");
}
}
if (opponent != null) {
diff --git a/Mage.Sets/src/mage/cards/d/DeathbellowWarCry.java b/Mage.Sets/src/mage/cards/d/DeathbellowWarCry.java
new file mode 100644
index 00000000000..fddedf90f3b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/d/DeathbellowWarCry.java
@@ -0,0 +1,75 @@
+package mage.cards.d;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.cards.Cards;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterCard;
+import mage.filter.common.FilterCreatureCard;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.game.Game;
+import mage.target.common.TargetCardInLibrary;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class DeathbellowWarCry extends CardImpl {
+
+ public DeathbellowWarCry(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{R}{R}{R}");
+
+ // Search your library for up to four Minotaur creature cards with different names, put them onto the battlefield, then shuffle your library.
+ this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new DeathbellowWarCryTarget()));
+ }
+
+ private DeathbellowWarCry(final DeathbellowWarCry card) {
+ super(card);
+ }
+
+ @Override
+ public DeathbellowWarCry copy() {
+ return new DeathbellowWarCry(this);
+ }
+}
+
+class DeathbellowWarCryTarget extends TargetCardInLibrary {
+
+ private static final FilterCard minotaurFilter
+ = new FilterCreatureCard("Minotaur creature cards with different names");
+
+ static {
+ minotaurFilter.add(new SubtypePredicate(SubType.MINOTAUR));
+ }
+
+ DeathbellowWarCryTarget() {
+ super(0, 4, minotaurFilter);
+ }
+
+ private DeathbellowWarCryTarget(final DeathbellowWarCryTarget target) {
+ super(target);
+ }
+
+ @Override
+ public DeathbellowWarCryTarget copy() {
+ return new DeathbellowWarCryTarget(this);
+ }
+
+ @Override
+ public boolean canTarget(UUID playerId, UUID id, Ability source, Cards cards, Game game) {
+ Card card = cards.get(id, game);
+ return card != null
+ && filter.match(card, playerId, game)
+ && this
+ .getTargets()
+ .stream()
+ .map(game::getCard)
+ .map(Card::getName)
+ .noneMatch(card.getName()::equals);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/d/DeathlessKnight.java b/Mage.Sets/src/mage/cards/d/DeathlessKnight.java
new file mode 100644
index 00000000000..decc33595d1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/d/DeathlessKnight.java
@@ -0,0 +1,91 @@
+package mage.cards.d;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect;
+import mage.abilities.keyword.HasteAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+
+/**
+ * @author TheElk801
+ */
+public final class DeathlessKnight extends CardImpl {
+
+ public DeathlessKnight(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B/G}{B/G}{B/G}{B/G}");
+
+ this.subtype.add(SubType.SKELETON);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(2);
+
+ // Haste
+ this.addAbility(HasteAbility.getInstance());
+
+ // When you gain life for the first time each turn, return Deathless Knight from your graveyard to your hand.
+ this.addAbility(new DeathlessKnightTriggeredAbility());
+ }
+
+ private DeathlessKnight(final DeathlessKnight card) {
+ super(card);
+ }
+
+ @Override
+ public DeathlessKnight copy() {
+ return new DeathlessKnight(this);
+ }
+}
+
+class DeathlessKnightTriggeredAbility extends TriggeredAbilityImpl {
+
+ private boolean triggeredOnce = false;
+
+ DeathlessKnightTriggeredAbility() {
+ super(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), false);
+ }
+
+ private DeathlessKnightTriggeredAbility(final DeathlessKnightTriggeredAbility ability) {
+ super(ability);
+ this.triggeredOnce = ability.triggeredOnce;
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.GAINED_LIFE
+ || event.getType() == GameEvent.EventType.END_PHASE_POST;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ if (event.getType() == GameEvent.EventType.END_PHASE_POST) {
+ triggeredOnce = false;
+ return false;
+ }
+ if (event.getType() != GameEvent.EventType.GAINED_LIFE
+ || !event.getPlayerId().equals(getControllerId())) {
+ return false;
+ }
+ if (triggeredOnce) {
+ return false;
+ }
+ triggeredOnce = true;
+ return true;
+ }
+
+ @Override
+ public String getRule() {
+ return "When you gain life for the first time each turn, return {this} from your graveyard to your hand.";
+ }
+
+ @Override
+ public DeathlessKnightTriggeredAbility copy() {
+ return new DeathlessKnightTriggeredAbility(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/d/Deathrender.java b/Mage.Sets/src/mage/cards/d/Deathrender.java
index 66c57afbc86..dec0fe1678d 100644
--- a/Mage.Sets/src/mage/cards/d/Deathrender.java
+++ b/Mage.Sets/src/mage/cards/d/Deathrender.java
@@ -1,4 +1,3 @@
-
package mage.cards.d;
import java.util.UUID;
@@ -16,8 +15,7 @@ import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.FilterCard;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -30,7 +28,7 @@ import mage.target.common.TargetCardInHand;
public final class Deathrender extends CardImpl {
public Deathrender(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +2/+2.
@@ -72,8 +70,7 @@ class DeathrenderEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (controller != null && sourcePermanent != null) {
- FilterCard filter = new FilterCreatureCard();
- TargetCardInHand target = new TargetCardInHand(0, 1, filter);
+ TargetCardInHand target = new TargetCardInHand(0, 1, StaticFilters.FILTER_CARD_CREATURE);
if (controller.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) {
Card creatureInHand = game.getCard(target.getFirstTarget());
if (creatureInHand != null) {
diff --git a/Mage.Sets/src/mage/cards/d/DefenseOfTheHeart.java b/Mage.Sets/src/mage/cards/d/DefenseOfTheHeart.java
index f703fa21696..eb7a12f629f 100644
--- a/Mage.Sets/src/mage/cards/d/DefenseOfTheHeart.java
+++ b/Mage.Sets/src/mage/cards/d/DefenseOfTheHeart.java
@@ -1,4 +1,3 @@
-
package mage.cards.d;
import java.util.Set;
@@ -17,7 +16,6 @@ import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.target.common.TargetCardInLibrary;
@@ -32,7 +30,7 @@ public final class DefenseOfTheHeart extends CardImpl {
// At the beginning of your upkeep, if an opponent controls three or more creatures, sacrifice Defense of the Heart, search your library for up to two creature cards, and put those cards onto the battlefield. Then shuffle your library.
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SacrificeSourceEffect(), TargetController.YOU, false);
- ability.addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 2, new FilterCreatureCard()), false, Outcome.PutLandInPlay));
+ ability.addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_CREATURE), false, Outcome.PutLandInPlay));
DefenseOfTheHeartCondition contition = new DefenseOfTheHeartCondition();
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, contition, "At the beginning of your upkeep, if an opponent controls three or more creatures, sacrifice {this}, search your library for up to two creature cards, and put those cards onto the battlefield. Then shuffle your library"));
diff --git a/Mage.Sets/src/mage/cards/d/DefensiveManeuvers.java b/Mage.Sets/src/mage/cards/d/DefensiveManeuvers.java
index afdce81b29e..755fe982905 100644
--- a/Mage.Sets/src/mage/cards/d/DefensiveManeuvers.java
+++ b/Mage.Sets/src/mage/cards/d/DefensiveManeuvers.java
@@ -1,7 +1,5 @@
-
package mage.cards.d;
-import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
@@ -19,8 +17,9 @@ import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.players.Player;
+import java.util.UUID;
+
/**
- *
* @author TheElk801
*/
public final class DefensiveManeuvers extends CardImpl {
@@ -45,7 +44,7 @@ public final class DefensiveManeuvers extends CardImpl {
class DefensiveManeuversEffect extends OneShotEffect {
DefensiveManeuversEffect() {
- super(Outcome.Benefit);
+ super(Outcome.BoostCreature);
this.staticText = "Creatures of the creature type of your choice get +0/+4 until end of turn.";
}
diff --git a/Mage.Sets/src/mage/cards/d/DemonOfLoathing.java b/Mage.Sets/src/mage/cards/d/DemonOfLoathing.java
new file mode 100644
index 00000000000..2f9b21f61ec
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/d/DemonOfLoathing.java
@@ -0,0 +1,48 @@
+package mage.cards.d;
+
+import mage.MageInt;
+import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
+import mage.abilities.effects.common.SacrificeEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class DemonOfLoathing extends CardImpl {
+
+ public DemonOfLoathing(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}");
+
+ this.subtype.add(SubType.DEMON);
+ this.power = new MageInt(7);
+ this.toughness = new MageInt(7);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Trample
+ this.addAbility(TrampleAbility.getInstance());
+
+ // Whenever Demon of Loathing deals combat damage to a player, that player sacrifices a creature.
+ this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new SacrificeEffect(
+ StaticFilters.FILTER_PERMANENT_A_CREATURE, 1, "that player"
+ ), false, true));
+ }
+
+ private DemonOfLoathing(final DemonOfLoathing card) {
+ super(card);
+ }
+
+ @Override
+ public DemonOfLoathing copy() {
+ return new DemonOfLoathing(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/d/DescendantsPath.java b/Mage.Sets/src/mage/cards/d/DescendantsPath.java
index 4fbe772f8fe..9f66411ff2a 100644
--- a/Mage.Sets/src/mage/cards/d/DescendantsPath.java
+++ b/Mage.Sets/src/mage/cards/d/DescendantsPath.java
@@ -1,4 +1,3 @@
-
package mage.cards.d;
import java.util.UUID;
@@ -29,7 +28,9 @@ public final class DescendantsPath extends CardImpl {
public DescendantsPath(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}");
- // At the beginning of your upkeep, reveal the top card of your library. If it's a creature card that shares a creature type with a creature you control, you may cast that card without paying its mana cost. Otherwise, put that card on the bottom of your library.
+ // At the beginning of your upkeep, reveal the top card of your library.
+ // If it's a creature card that shares a creature type with a creature you control,
+ // you may cast that card without paying its mana cost. Otherwise, put that card on the bottom of your library.
Ability ability = new BeginningOfUpkeepTriggeredAbility(new DescendantsPathEffect(), TargetController.YOU, false);
this.addAbility(ability);
}
@@ -48,7 +49,10 @@ class DescendantsPathEffect extends OneShotEffect {
public DescendantsPathEffect() {
super(Outcome.Discard);
- this.staticText = "reveal the top card of your library. If it's a creature card that shares a creature type with a creature you control, you may cast that card without paying its mana cost. Otherwise, put that card on the bottom of your library";
+ this.staticText = "reveal the top card of your library. If it's a creature "
+ + "card that shares a creature type with a creature you control, "
+ + "you may cast that card without paying its mana cost. Otherwise, "
+ + "put that card on the bottom of your library";
}
public DescendantsPathEffect(final DescendantsPathEffect effect) {
@@ -83,7 +87,10 @@ class DescendantsPathEffect extends OneShotEffect {
if (found) {
game.informPlayers(sourceObject.getLogName() + ": Found a creature that shares a creature type with the revealed card.");
if (controller.chooseUse(Outcome.Benefit, "Cast the card?", source, game)) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
} else {
game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " canceled casting the card.");
controller.getLibrary().putOnBottom(card, game);
diff --git a/Mage.Sets/src/mage/cards/d/DescentIntoMadness.java b/Mage.Sets/src/mage/cards/d/DescentIntoMadness.java
index 028feb1b2fc..da95405944b 100644
--- a/Mage.Sets/src/mage/cards/d/DescentIntoMadness.java
+++ b/Mage.Sets/src/mage/cards/d/DescentIntoMadness.java
@@ -1,10 +1,5 @@
-
package mage.cards.d;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@@ -24,13 +19,17 @@ import mage.filter.predicate.permanent.PermanentIdPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
-import mage.players.PlayerList;
import mage.target.Target;
import mage.target.TargetCard;
import mage.target.common.TargetControlledPermanent;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+
/**
- * 5/1/2012 For each despair counter on Descent into Madness, you'll exile a permanent
+ * 5/1/2012 For each despair counter on Descent into Madness, you'll exile a permanent
* you control or exile a card from your hand, not both.
* 5/1/2012 First you choose the permanents and/or cards from your hand that will be
* exiled. Then each other player in turn order does the same. Then all the chosen permanents
@@ -43,16 +42,16 @@ import mage.target.common.TargetControlledPermanent;
* 5/1/2012 If Descent into Madness isn't on the battlefield when its ability resolves,
* use the number of counters on it when it left the battlefield to determine how many permanents
* and/or cards from hands to exile.
- *
+ *
* @author noxx
*/
public final class DescentIntoMadness extends CardImpl {
public DescentIntoMadness(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{B}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}");
- // At the beginning of your upkeep, put a despair counter on Descent into Madness, then each player exiles X permanents he or she controls and/or cards from their hand, where X is the number of despair counters on Descent into Madness.
+ // At the beginning of your upkeep, put a despair counter on Descent into Madness, then each player exiles X permanents they control and/or cards from their hand, where X is the number of despair counters on Descent into Madness.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DescentIntoMadnessEffect(), TargetController.YOU, false));
}
@@ -70,7 +69,7 @@ class DescentIntoMadnessEffect extends OneShotEffect {
public DescentIntoMadnessEffect() {
super(Outcome.Sacrifice);
- this.staticText = "put a despair counter on {this}, then each player exiles X permanents he or she controls and/or cards from their hand, where X is the number of despair counters on {this}";
+ this.staticText = "put a despair counter on {this}, then each player exiles X permanents they control and/or cards from their hand, where X is the number of despair counters on {this}";
}
public DescentIntoMadnessEffect(final DescentIntoMadnessEffect effect) {
@@ -83,7 +82,7 @@ class DescentIntoMadnessEffect extends OneShotEffect {
}
@Override
- public boolean apply(Game game, Ability source) {
+ public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent != null && controller != null) {
@@ -92,18 +91,20 @@ class DescentIntoMadnessEffect extends OneShotEffect {
if (sourcePermanent == null) {
sourcePermanent = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
}
- if (sourcePermanent != null && controller != null) {
+ if (sourcePermanent != null && controller != null) {
int count = sourcePermanent.getCounters(game).getCount(CounterType.DESPAIR);
if (count > 0) {
// select the permanents and hand cards in turn order
LinkedList selectedObjects = new LinkedList<>();
- PlayerList playerList = game.getState().getPlayerList(controller.getId());
- Player currentPlayer = controller;
- do {
- selectCards(currentPlayer, selectedObjects, count, source, game);
- currentPlayer = playerList.getNextInRange(controller, game);
- } while (!currentPlayer.equals(controller) && controller.canRespond());
-
+
+ // ask all players
+ for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
+ Player currentPlayer = game.getPlayer(playerId);
+ if (currentPlayer != null && currentPlayer.canRespond()) {
+ selectCards(currentPlayer, selectedObjects, count, source, game);
+ }
+ }
+
// move permanents and hand cards to exile
for (UUID objectId : selectedObjects) {
if (game.getState().getZone(objectId) == Zone.BATTLEFIELD) {
@@ -121,10 +122,10 @@ class DescentIntoMadnessEffect extends OneShotEffect {
if (player != null) {
player.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.HAND, true);
}
- }
+ }
}
}
-
+
}
return true;
}
@@ -134,22 +135,22 @@ class DescentIntoMadnessEffect extends OneShotEffect {
private void selectCards(Player player, List selectedObjects, int count, Ability source, Game game) {
int amount = Math.min(count, player.getHand().size() + game.getBattlefield().getAllActivePermanents(player.getId()).size());
int cardsFromHand = 0;
-
+
while (player.canRespond() && amount > 0) {
-
+
Target target;
do {
FilterControlledPermanent filter = new FilterControlledPermanent();
- filter.setMessage("permanent you control (" + amount + " left in total)" );
+ filter.setMessage("permanent you control (" + amount + " left in total)");
List uuidPredicates = new ArrayList<>();
- for (UUID uuid :selectedObjects) {
+ for (UUID uuid : selectedObjects) {
uuidPredicates.add(new PermanentIdPredicate(uuid));
}
- filter.add(Predicates.not(Predicates.or(uuidPredicates)));
-
+ filter.add(Predicates.not(Predicates.or(uuidPredicates)));
+
target = new TargetControlledPermanent(0, 1, filter, true);
if (target.canChoose(player.getId(), game)
- && player.choose(Outcome.Exile, target, source.getSourceId(), game)) {
+ && player.choose(Outcome.Exile, target, source.getSourceId(), game)) {
for (UUID targetId : target.getTargets()) {
if (!selectedObjects.contains(targetId)) {
Permanent chosen = game.getPermanent(targetId);
@@ -162,17 +163,17 @@ class DescentIntoMadnessEffect extends OneShotEffect {
}
}
} while (amount > 0 && !target.getTargets().isEmpty() && player.canRespond());
- if (amount > 0) {
+ if (amount > 0) {
TargetCard targetInHand;
do {
FilterCard filterInHand = new FilterCard();
- filterInHand.setMessage("card from your hand (" + amount + " left in total)");
+ filterInHand.setMessage("card from your hand (" + amount + " left in total)");
targetInHand = new TargetCard(0, 1, Zone.HAND, filterInHand);
List uuidPredicates = new ArrayList<>();
- for (UUID uuid :selectedObjects) {
+ for (UUID uuid : selectedObjects) {
uuidPredicates.add(new CardIdPredicate(uuid));
}
- filterInHand.add(Predicates.not(Predicates.or(uuidPredicates)));
+ filterInHand.add(Predicates.not(Predicates.or(uuidPredicates)));
if (targetInHand.canChoose(player.getId(), game) &&
player.choose(Outcome.Exile, player.getHand(), targetInHand, game)) {
@@ -188,7 +189,7 @@ class DescentIntoMadnessEffect extends OneShotEffect {
}
}
if (cardsFromHand > 0) {
- game.informPlayers(player.getLogName() + " selects " + cardsFromHand + (cardsFromHand == 1?" card":" cards") + " from their hand");
+ game.informPlayers(player.getLogName() + " selects " + cardsFromHand + (cardsFromHand == 1 ? " card" : " cards") + " from their hand");
}
}
}
diff --git a/Mage.Sets/src/mage/cards/d/DestroyTheEvidence.java b/Mage.Sets/src/mage/cards/d/DestroyTheEvidence.java
index a0c1b4046aa..93820f75f0a 100644
--- a/Mage.Sets/src/mage/cards/d/DestroyTheEvidence.java
+++ b/Mage.Sets/src/mage/cards/d/DestroyTheEvidence.java
@@ -24,7 +24,7 @@ public final class DestroyTheEvidence extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}");
// Destroy target land. Its controller reveals cards from the top of his
- // or her library until he or she reveals a land card, then puts those cards into their graveyard.
+ // or her library until they reveal a land card, then puts those cards into their graveyard.
TargetLandPermanent target = new TargetLandPermanent();
this.getSpellAbility().addTarget(target);
this.getSpellAbility().addEffect(new DestroyTargetEffect());
@@ -45,7 +45,7 @@ class DestroyTheEvidenceEffect extends OneShotEffect {
public DestroyTheEvidenceEffect() {
super(Outcome.Discard);
- this.staticText = "Its controller reveals cards from the top of their library until he or she reveals a land card, then puts those cards into their graveyard";
+ this.staticText = "Its controller reveals cards from the top of their library until they reveal a land card, then puts those cards into their graveyard";
}
public DestroyTheEvidenceEffect(final DestroyTheEvidenceEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/d/DidntSayPlease.java b/Mage.Sets/src/mage/cards/d/DidntSayPlease.java
new file mode 100644
index 00000000000..f4e6a186b51
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/d/DidntSayPlease.java
@@ -0,0 +1,69 @@
+package mage.cards.d;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CounterTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.TargetSpell;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class DidntSayPlease extends CardImpl {
+
+ public DidntSayPlease(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}{U}");
+
+ // Counter target spell. Its controller puts the top three cards of their library into their graveyard.
+ this.getSpellAbility().addEffect(new DidntSayPleaseEffect());
+ this.getSpellAbility().addTarget(new TargetSpell());
+ }
+
+ private DidntSayPlease(final DidntSayPlease card) {
+ super(card);
+ }
+
+ @Override
+ public DidntSayPlease copy() {
+ return new DidntSayPlease(this);
+ }
+}
+
+class DidntSayPleaseEffect extends OneShotEffect {
+
+ private static final Effect effect = new CounterTargetEffect();
+
+ DidntSayPleaseEffect() {
+ super(Outcome.Benefit);
+ staticText = "Counter target spell. Its controller puts " +
+ "the top three cards of their library into their graveyard.";
+ }
+
+ private DidntSayPleaseEffect(final DidntSayPleaseEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public DidntSayPleaseEffect copy() {
+ return new DidntSayPleaseEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(game.getControllerId(source.getFirstTarget()));
+ if (player == null) {
+ return false;
+ }
+ player.moveCards(player.getLibrary().getTopCards(game, 3), Zone.GRAVEYARD, source, game);
+ return effect.apply(game, source);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/d/DiffusionSliver.java b/Mage.Sets/src/mage/cards/d/DiffusionSliver.java
index 22a2ec40446..07fe7b000ca 100644
--- a/Mage.Sets/src/mage/cards/d/DiffusionSliver.java
+++ b/Mage.Sets/src/mage/cards/d/DiffusionSliver.java
@@ -1,7 +1,5 @@
-
package mage.cards.d;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.costs.mana.GenericManaCost;
@@ -12,32 +10,33 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
+import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
-import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
-import mage.target.TargetStackObject;
+import mage.target.targetpointer.FixedTarget;
+
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class DiffusionSliver extends CardImpl {
public DiffusionSliver(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.subtype.add(SubType.SLIVER);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Whenever a Sliver creature you control becomes the target of a spell or ability an opponent controls, counter that spell or ability unless its controller pays {2}.
- this.addAbility(new DiffusionSliverTriggeredAbility(new CounterUnlessPaysEffect(new GenericManaCost(2))));
+ this.addAbility(new DiffusionSliverTriggeredAbility());
}
- public DiffusionSliver(final DiffusionSliver card) {
+ private DiffusionSliver(final DiffusionSliver card) {
super(card);
}
@@ -49,17 +48,13 @@ public final class DiffusionSliver extends CardImpl {
class DiffusionSliverTriggeredAbility extends TriggeredAbilityImpl {
- private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Sliver creature you control");
+ private static final FilterPermanent filter = new FilterControlledCreaturePermanent(SubType.SLIVER);
- static {
- filter.add(new SubtypePredicate(SubType.SLIVER));
+ DiffusionSliverTriggeredAbility() {
+ super(Zone.BATTLEFIELD, null);
}
- public DiffusionSliverTriggeredAbility(Effect effect) {
- super(Zone.BATTLEFIELD, effect);
- }
-
- public DiffusionSliverTriggeredAbility(final DiffusionSliverTriggeredAbility ability) {
+ private DiffusionSliverTriggeredAbility(final DiffusionSliverTriggeredAbility ability) {
super(ability);
}
@@ -75,21 +70,23 @@ class DiffusionSliverTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
- if (game.getOpponents(this.controllerId).contains(event.getPlayerId())) {
- Permanent creature = game.getPermanent(event.getTargetId());
- if (creature != null && filter.match(creature, getSourceId(), getControllerId(), game)) {
- this.getTargets().clear();
- TargetStackObject target = new TargetStackObject();
- target.add(event.getSourceId(), game);
- this.addTarget(target);
- return true;
- }
+ if (!game.getOpponents(this.controllerId).contains(event.getPlayerId())) {
+ return false;
}
- return false;
+ Permanent creature = game.getPermanent(event.getTargetId());
+ if (creature == null || !filter.match(creature, getSourceId(), getControllerId(), game)) {
+ return false;
+ }
+ this.getEffects().clear();
+ Effect effect = new CounterUnlessPaysEffect(new GenericManaCost(2));
+ effect.setTargetPointer(new FixedTarget(event.getSourceId(), game));
+ this.addEffect(effect);
+ return true;
}
@Override
public String getRule() {
- return "Whenever a Sliver creature you control becomes the target of a spell or ability an opponent controls, counter that spell or ability unless its controller pays {2}.";
+ return "Whenever a Sliver creature you control becomes the target of a spell or ability an opponent controls, " +
+ "counter that spell or ability unless its controller pays {2}.";
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/d/DiluvianPrimordial.java b/Mage.Sets/src/mage/cards/d/DiluvianPrimordial.java
index 98bde31f8f6..5ebaeb3e536 100644
--- a/Mage.Sets/src/mage/cards/d/DiluvianPrimordial.java
+++ b/Mage.Sets/src/mage/cards/d/DiluvianPrimordial.java
@@ -1,4 +1,3 @@
-
package mage.cards.d;
import mage.MageInt;
@@ -44,7 +43,10 @@ public final class DiluvianPrimordial extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
- // When Diluvian Primordial enters the battlefield, for each opponent, you may cast up to one target instant or sorcery card from that player's graveyard without paying its mana cost. If a card cast this way would be put into a graveyard this turn, exile it instead.
+ // When Diluvian Primordial enters the battlefield, for each opponent,
+ // you may cast up to one target instant or sorcery card from that
+ // player's graveyard without paying its mana cost. If a card cast this way
+ // would be put into a graveyard this turn, exile it instead.
Ability ability = new EntersBattlefieldTriggeredAbility(new DiluvianPrimordialEffect(), false);
ability.setTargetAdjuster(DiluvianPrimordialAdjuster.instance);
this.addAbility(ability);
@@ -71,7 +73,8 @@ enum DiluvianPrimordialAdjuster implements TargetAdjuster {
if (opponent == null) {
continue;
}
- FilterCard filter = new FilterCard("instant or sorcery card from " + opponent.getLogName() + "'s graveyard");
+ FilterCard filter = new FilterCard("instant or sorcery card from "
+ + opponent.getLogName() + "'s graveyard");
filter.add(new OwnerIdPredicate(opponentId));
filter.add(Predicates.or(new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.SORCERY)));
TargetCardInOpponentsGraveyard target = new TargetCardInOpponentsGraveyard(0, 1, filter);
@@ -84,7 +87,10 @@ class DiluvianPrimordialEffect extends OneShotEffect {
public DiluvianPrimordialEffect() {
super(Outcome.PlayForFree);
- this.staticText = "for each opponent, you may cast up to one target instant or sorcery card from that player's graveyard without paying its mana cost. If a card cast this way would be put into a graveyard this turn, exile it instead";
+ this.staticText = "for each opponent, you may cast up to one target "
+ + "instant or sorcery card from that player's graveyard without "
+ + "paying its mana cost. If a card cast this way would be put "
+ + "into a graveyard this turn, exile it instead";
}
public DiluvianPrimordialEffect(final DiluvianPrimordialEffect effect) {
@@ -104,8 +110,12 @@ class DiluvianPrimordialEffect extends OneShotEffect {
if (target instanceof TargetCardInOpponentsGraveyard) {
Card targetCard = game.getCard(target.getFirstTarget());
if (targetCard != null) {
- if (controller.chooseUse(outcome, "Cast " + targetCard.getLogName() + '?', source, game)) {
- if (controller.cast(targetCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
+ if (controller.chooseUse(Outcome.PlayForFree, "Cast " + targetCard.getLogName() + '?', source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + targetCard.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(targetCard, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + targetCard.getId(), null);
+ if (cardWasCast) {
ContinuousEffect effect = new DiluvianPrimordialReplacementEffect();
effect.setTargetPointer(new FixedTarget(targetCard.getId(), game.getState().getZoneChangeCounter(targetCard.getId())));
game.addEffect(effect, source);
diff --git a/Mage.Sets/src/mage/cards/d/DimensionalBreach.java b/Mage.Sets/src/mage/cards/d/DimensionalBreach.java
index 28131d4099e..51defb36128 100644
--- a/Mage.Sets/src/mage/cards/d/DimensionalBreach.java
+++ b/Mage.Sets/src/mage/cards/d/DimensionalBreach.java
@@ -32,7 +32,7 @@ public final class DimensionalBreach extends CardImpl {
public DimensionalBreach(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{W}{W}");
- // Exile all permanents. For as long as any of those cards remain exiled, at the beginning of each player's upkeep, that player returns one of the exiled cards he or she owns to the battlefield.
+ // Exile all permanents. For as long as any of those cards remain exiled, at the beginning of each player's upkeep, that player returns one of the exiled cards they own to the battlefield.
this.getSpellAbility().addEffect(new DimensionalBreachExileEffect());
this.addAbility(new ConditionalInterveningIfTriggeredAbility(new BeginningOfUpkeepTriggeredAbility(Zone.ALL, new DimensionalBreachReturnFromExileEffect(), TargetController.ANY, false, true, null), new CardsStillInExileCondition(), null));
@@ -86,7 +86,7 @@ class DimensionalBreachReturnFromExileEffect extends OneShotEffect {
public DimensionalBreachReturnFromExileEffect() {
super(Outcome.PutCardInPlay);
- staticText = "For as long as any of those cards remain exiled, at the beginning of each player's upkeep, that player returns one of the exiled cards he or she owns to the battlefield.";
+ staticText = "For as long as any of those cards remain exiled, at the beginning of each player's upkeep, that player returns one of the exiled cards they own to the battlefield.";
}
public DimensionalBreachReturnFromExileEffect(final DimensionalBreachReturnFromExileEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/d/DimirCutpurse.java b/Mage.Sets/src/mage/cards/d/DimirCutpurse.java
index 54476bf662f..5d6beefa3ba 100644
--- a/Mage.Sets/src/mage/cards/d/DimirCutpurse.java
+++ b/Mage.Sets/src/mage/cards/d/DimirCutpurse.java
@@ -56,7 +56,7 @@ class DimirCutpurseEffect extends OneShotEffect {
Player you = game.getPlayer(source.getControllerId());
Player damagedPlayer = game.getPlayer(targetPointer.getFirst(game, source));
if (damagedPlayer != null) {
- damagedPlayer.discard(1, source, game);
+ damagedPlayer.discard(1, false,source, game);
}
if (you != null) {
you.drawCards(1, game);
diff --git a/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java b/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java
index c39708c8936..0b068cb21aa 100644
--- a/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java
+++ b/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java
@@ -1,27 +1,15 @@
package mage.cards.d;
-import java.util.Objects;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.effects.AsThoughEffectImpl;
-import mage.abilities.effects.AsThoughManaEffect;
-import mage.abilities.effects.ContinuousEffect;
-import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.ReplacementEffectImpl;
+import mage.abilities.effects.*;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.AsThoughEffectType;
-import mage.constants.CardType;
-import mage.constants.Duration;
-import mage.constants.ManaType;
-import mage.constants.Outcome;
-import mage.constants.SubType;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
@@ -33,9 +21,12 @@ import mage.players.ManaPoolItem;
import mage.players.Player;
import mage.target.common.TargetCardInOpponentsGraveyard;
import mage.target.targetpointer.FixedTarget;
+import mage.util.CardUtil;
+
+import java.util.Objects;
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class DireFleetDaredevil extends CardImpl {
@@ -143,11 +134,12 @@ class DireFleetDaredevilSpendAnyManaEffect extends AsThoughEffectImpl implements
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
- objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
+ FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
return source.isControlledBy(affectedControllerId)
&& Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget())
- && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)
- && game.getState().getZone(objectId) == Zone.STACK;
+ && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
+ && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
}
@Override
@@ -192,7 +184,7 @@ class DireFleetDaredevilReplacementEffect extends ReplacementEffectImpl {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
return zEvent.getToZone() == Zone.GRAVEYARD
&& event.getTargetId().equals(((FixedTarget) getTargetPointer()).getTarget())
- && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1
+ && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1
== game.getState().getZoneChangeCounter(event.getTargetId());
}
}
diff --git a/Mage.Sets/src/mage/cards/d/DirtcowlWurm.java b/Mage.Sets/src/mage/cards/d/DirtcowlWurm.java
index 99beb661154..fb402a7a6cc 100644
--- a/Mage.Sets/src/mage/cards/d/DirtcowlWurm.java
+++ b/Mage.Sets/src/mage/cards/d/DirtcowlWurm.java
@@ -1,7 +1,5 @@
-
package mage.cards.d;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
@@ -16,14 +14,15 @@ import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class DirtcowlWurm extends CardImpl {
public DirtcowlWurm(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}");
this.subtype.add(SubType.WURM);
this.power = new MageInt(3);
this.toughness = new MageInt(4);
@@ -59,7 +58,7 @@ class DirtcowlWurmTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent land = game.getPermanent(event.getTargetId());
- return game.getOpponents(controllerId).contains(land.getControllerId());
+ return land != null && game.getOpponents(controllerId).contains(land.getControllerId());
}
@Override
diff --git a/Mage.Sets/src/mage/cards/d/DiscipleOfPhenax.java b/Mage.Sets/src/mage/cards/d/DiscipleOfPhenax.java
index 01244aeea45..7ac0707d672 100644
--- a/Mage.Sets/src/mage/cards/d/DiscipleOfPhenax.java
+++ b/Mage.Sets/src/mage/cards/d/DiscipleOfPhenax.java
@@ -1,4 +1,3 @@
-
package mage.cards.d;
import mage.MageInt;
@@ -7,7 +6,10 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.common.DevotionCount;
import mage.abilities.effects.OneShotEffect;
import mage.cards.*;
-import mage.constants.*;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
@@ -35,11 +37,12 @@ public final class DiscipleOfPhenax extends CardImpl {
// from their hand equal to your devotion to black. You choose one of them. That player discards that card.
Ability ability = new EntersBattlefieldTriggeredAbility(new DiscipleOfPhenaxEffect(), false);
ability.addTarget(new TargetPlayer());
+ ability.addHint(DevotionCount.B.getHint());
this.addAbility(ability);
}
- public DiscipleOfPhenax(final DiscipleOfPhenax card) {
+ private DiscipleOfPhenax(final DiscipleOfPhenax card) {
super(card);
}
@@ -51,12 +54,12 @@ public final class DiscipleOfPhenax extends CardImpl {
class DiscipleOfPhenaxEffect extends OneShotEffect {
- public DiscipleOfPhenaxEffect() {
+ DiscipleOfPhenaxEffect() {
super(Outcome.Discard);
staticText = "target player reveals a number of cards from their hand equal to your devotion to black. You choose one of them. That player discards that card";
}
- public DiscipleOfPhenaxEffect(final DiscipleOfPhenaxEffect effect) {
+ private DiscipleOfPhenaxEffect(final DiscipleOfPhenaxEffect effect) {
super(effect);
}
@@ -67,48 +70,46 @@ class DiscipleOfPhenaxEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- int devotion = new DevotionCount(ColoredManaSymbol.B).calculate(game, source, this);
+ int devotion = DevotionCount.B.calculate(game, source, this);
Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
- if (devotion > 0 && targetPlayer != null) {
- Cards revealedCards = new CardsImpl();
- int amount = Math.min(targetPlayer.getHand().size(), devotion);
- if (targetPlayer.getHand().size() > amount) {
- FilterCard filter = new FilterCard("card in target player's hand");
- TargetCardInHand chosenCards = new TargetCardInHand(amount, amount, filter);
- chosenCards.setNotTarget(true);
- if (chosenCards.canChoose(targetPlayer.getId(), game) && targetPlayer.choose(Outcome.Discard, targetPlayer.getHand(), chosenCards, game)) {
- if (!chosenCards.getTargets().isEmpty()) {
- List targets = chosenCards.getTargets();
- for (UUID targetid : targets) {
- Card card = game.getCard(targetid);
- if (card != null) {
- revealedCards.add(card);
- }
+ if (devotion <= 0 || targetPlayer == null) {
+ return false;
+ }
+ Cards revealedCards = new CardsImpl();
+ int amount = Math.min(targetPlayer.getHand().size(), devotion);
+ if (targetPlayer.getHand().size() > amount) {
+ FilterCard filter = new FilterCard("card in target player's hand");
+ TargetCardInHand chosenCards = new TargetCardInHand(amount, amount, filter);
+ chosenCards.setNotTarget(true);
+ if (chosenCards.canChoose(targetPlayer.getId(), game) && targetPlayer.choose(Outcome.Discard, targetPlayer.getHand(), chosenCards, game)) {
+ if (!chosenCards.getTargets().isEmpty()) {
+ List targets = chosenCards.getTargets();
+ for (UUID targetid : targets) {
+ Card card = game.getCard(targetid);
+ if (card != null) {
+ revealedCards.add(card);
}
}
}
- } else {
- revealedCards.addAll(targetPlayer.getHand());
- }
- if (!revealedCards.isEmpty()) {
- targetPlayer.revealCards("Disciple of Phenax", revealedCards, game);
- Player you = game.getPlayer(source.getControllerId());
- if (you != null) {
- TargetCard yourChoice = new TargetCard(Zone.HAND, new FilterCard());
- yourChoice.setNotTarget(true);
- if (you.choose(Outcome.Benefit, revealedCards, yourChoice, game)) {
- Card card = targetPlayer.getHand().get(yourChoice.getFirstTarget(), game);
- return targetPlayer.discard(card, source, game);
-
- }
- } else {
- return false;
- }
}
+ } else {
+ revealedCards.addAll(targetPlayer.getHand());
+ }
+ if (revealedCards.isEmpty()) {
return true;
+ }
+ targetPlayer.revealCards("Disciple of Phenax", revealedCards, game);
+ Player you = game.getPlayer(source.getControllerId());
+ if (you == null) {
+ return false;
+ }
+ TargetCard yourChoice = new TargetCard(Zone.HAND, new FilterCard());
+ yourChoice.setNotTarget(true);
+ if (you.choose(Outcome.Benefit, revealedCards, yourChoice, game)) {
+ Card card = targetPlayer.getHand().get(yourChoice.getFirstTarget(), game);
+ return targetPlayer.discard(card, source, game);
}
-
- return false;
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/d/DistantMemories.java b/Mage.Sets/src/mage/cards/d/DistantMemories.java
index 68d8ffe9e72..66d93d9610f 100644
--- a/Mage.Sets/src/mage/cards/d/DistantMemories.java
+++ b/Mage.Sets/src/mage/cards/d/DistantMemories.java
@@ -70,7 +70,7 @@ class DistantMemoriesEffect extends OneShotEffect {
StringBuilder sb = new StringBuilder();
sb.append("Have ").append(player.getLogName()).append(" put ").append(card.getName());
- sb.append(" in his hand? If none of his opponents says yes, he'll draw three cards.");
+ sb.append(" in their hand? If none of their opponents says yes, they will draw three cards.");
boolean putInHand = false;
Set opponents = game.getOpponents(source.getControllerId());
diff --git a/Mage.Sets/src/mage/cards/d/DivergentTransformations.java b/Mage.Sets/src/mage/cards/d/DivergentTransformations.java
index 79a7b54aa58..efc3d43a2b7 100644
--- a/Mage.Sets/src/mage/cards/d/DivergentTransformations.java
+++ b/Mage.Sets/src/mage/cards/d/DivergentTransformations.java
@@ -27,7 +27,7 @@ public final class DivergentTransformations extends CardImpl {
// Undaunted
this.addAbility(new UndauntedAbility());
- // Exile two target creatures. For each of those creatures, its controller reveals cards from the top of their library until he or she reveals a creature card, puts that card onto the battlefield, then shuffles the rest into their library.
+ // Exile two target creatures. For each of those creatures, its controller reveals cards from the top of their library until they reveal a creature card, puts that card onto the battlefield, then shuffles the rest into their library.
this.getSpellAbility().addEffect(new DivergentTransformationsEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent(2, 2, FILTER_PERMANENT_CREATURES, false));
@@ -48,7 +48,7 @@ class DivergentTransformationsEffect extends OneShotEffect {
public DivergentTransformationsEffect() {
super(Outcome.Detriment);
this.staticText = "Exile two target creatures. For each of those creatures, its controller reveals cards from the top of their library "
- + "until he or she reveals a creature card, puts that card onto the battlefield, then shuffles the rest into their library";
+ + "until they reveal a creature card, puts that card onto the battlefield, then shuffles the rest into their library";
}
public DivergentTransformationsEffect(final DivergentTransformationsEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/d/DivineReckoning.java b/Mage.Sets/src/mage/cards/d/DivineReckoning.java
index 784babe0fcb..84a80a1cccf 100644
--- a/Mage.Sets/src/mage/cards/d/DivineReckoning.java
+++ b/Mage.Sets/src/mage/cards/d/DivineReckoning.java
@@ -31,7 +31,7 @@ public final class DivineReckoning extends CardImpl {
public DivineReckoning(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{W}{W}");
- // Each player chooses a creature he or she controls. Destroy the rest.
+ // Each player chooses a creature they control. Destroy the rest.
this.getSpellAbility().addEffect(new DivineReckoningEffect());
// Flashback {5}{W}{W}
@@ -52,7 +52,7 @@ class DivineReckoningEffect extends OneShotEffect {
public DivineReckoningEffect() {
super(Outcome.DestroyPermanent);
- staticText = "Each player chooses a creature he or she controls. Destroy the rest";
+ staticText = "Each player chooses a creature they control. Destroy the rest";
}
public DivineReckoningEffect(DivineReckoningEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/d/DolmenGate.java b/Mage.Sets/src/mage/cards/d/DolmenGate.java
index 24cad2f4d3d..734349f2b7a 100644
--- a/Mage.Sets/src/mage/cards/d/DolmenGate.java
+++ b/Mage.Sets/src/mage/cards/d/DolmenGate.java
@@ -1,7 +1,5 @@
-
package mage.cards.d;
-import java.util.UUID;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.PreventAllDamageToAllEffect;
import mage.cards.CardImpl;
@@ -9,23 +7,24 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
-import mage.filter.common.FilterControlledCreatureInPlay;
+import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.permanent.AttackingPredicate;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class DolmenGate extends CardImpl {
- private static final FilterControlledCreatureInPlay filter = new FilterControlledCreatureInPlay("attacking creatures you control");
+ private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("attacking creatures you control");
static {
- filter.getCreatureFilter().add(AttackingPredicate.instance);
+ filter.add(AttackingPredicate.instance);
}
public DolmenGate(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
// Prevent all combat damage that would be dealt to attacking creatures you control.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventAllDamageToAllEffect(Duration.WhileOnBattlefield, filter, true)));
diff --git a/Mage.Sets/src/mage/cards/d/DoomForetold.java b/Mage.Sets/src/mage/cards/d/DoomForetold.java
new file mode 100644
index 00000000000..2a997df0c61
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/d/DoomForetold.java
@@ -0,0 +1,105 @@
+package mage.cards.d;
+
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.SacrificeSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.TargetController;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterNonlandPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.permanent.ControllerIdPredicate;
+import mage.filter.predicate.permanent.TokenPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.token.KnightToken;
+import mage.players.Player;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class DoomForetold extends CardImpl {
+
+ public DoomForetold(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{B}");
+
+ // At the beginning of each player's upkeep, that player sacrifices a nonland, nontoken permanent. If that player can't, they discard a card, they lose 2 life, you draw a card, you gain 2 life, you create a 2/2 white Knight creature token with vigilance, then you sacrifice Doom Foretold.
+ this.addAbility(new BeginningOfUpkeepTriggeredAbility(
+ new DoomForetoldEffect(), TargetController.ACTIVE, false
+ ));
+ }
+
+ private DoomForetold(final DoomForetold card) {
+ super(card);
+ }
+
+ @Override
+ public DoomForetold copy() {
+ return new DoomForetold(this);
+ }
+}
+
+class DoomForetoldEffect extends OneShotEffect {
+
+ private static final FilterPermanent filter = new FilterNonlandPermanent("nonland, nontoken permanent");
+
+ static {
+ filter.add(Predicates.not(TokenPredicate.instance));
+ }
+
+ private static final Effect effect1 = new CreateTokenEffect(new KnightToken());
+ private static final Effect effect2 = new SacrificeSourceEffect();
+
+ DoomForetoldEffect() {
+ super(Outcome.Benefit);
+ staticText = "that player sacrifices a nonland, nontoken permanent. " +
+ "If that player can't, they discard a card, they lose 2 life, you draw a card, you gain 2 life, " +
+ "you create a 2/2 white Knight creature token with vigilance, then you sacrifice {this}";
+ }
+
+ private DoomForetoldEffect(final DoomForetoldEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public DoomForetoldEffect copy() {
+ return new DoomForetoldEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Player player = game.getPlayer(game.getActivePlayerId());
+ if (controller == null || player == null) {
+ return false;
+ }
+ FilterPermanent filter2 = filter.copy();
+ filter2.add(new ControllerIdPredicate(player.getId()));
+ if (game.getBattlefield().contains(filter2, 1, game)) {
+ TargetPermanent target = new TargetPermanent(filter2);
+ target.setNotTarget(true);
+ if (player.choose(Outcome.Sacrifice, target, source.getSourceId(), game)) {
+ Permanent permanent = game.getPermanent(target.getFirstTarget());
+ if (permanent != null && permanent.sacrifice(source.getSourceId(), game)) {
+ return true;
+ }
+ }
+ }
+ player.discard(1, false, source, game);
+ player.loseLife(2, game, false);
+ controller.drawCards(1, game);
+ controller.gainLife(2, game, source);
+ effect1.apply(game, source);
+ effect2.apply(game, source);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/d/Doomfall.java b/Mage.Sets/src/mage/cards/d/Doomfall.java
index f66ae408c8e..b582bdda3b3 100644
--- a/Mage.Sets/src/mage/cards/d/Doomfall.java
+++ b/Mage.Sets/src/mage/cards/d/Doomfall.java
@@ -31,7 +31,7 @@ public final class Doomfall extends CardImpl {
this.getSpellAbility().getModes().setMinModes(1);
this.getSpellAbility().getModes().setMaxModes(1);
- // • Target opponent exiles a creature he or she controls.
+ // • Target opponent exiles a creature they control.
this.getSpellAbility().addEffect(new DoomfallEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
@@ -57,7 +57,7 @@ class DoomfallEffect extends OneShotEffect {
public DoomfallEffect() {
super(Outcome.Exile);
- this.staticText = "target player exiles a creature he or she controls";
+ this.staticText = "target player exiles a creature they control";
}
public DoomfallEffect(final DoomfallEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/d/DrakestownForgotten.java b/Mage.Sets/src/mage/cards/d/DrakestownForgotten.java
index ad3078c87e7..5123e53da71 100644
--- a/Mage.Sets/src/mage/cards/d/DrakestownForgotten.java
+++ b/Mage.Sets/src/mage/cards/d/DrakestownForgotten.java
@@ -1,4 +1,3 @@
-
package mage.cards.d;
import java.util.UUID;
@@ -14,11 +13,11 @@ 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.constants.Duration;
+import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCreaturePermanent;
/**
@@ -28,7 +27,7 @@ import mage.target.common.TargetCreaturePermanent;
public final class DrakestownForgotten extends CardImpl {
public DrakestownForgotten(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
this.subtype.add(SubType.ZOMBIE);
this.power = new MageInt(0);
this.toughness = new MageInt(0);
@@ -36,11 +35,11 @@ public final class DrakestownForgotten extends CardImpl {
// Drakestown Forgotten enters the battlefield with X +1/+1 counters on it, where X is the number of creature cards in all graveyards.
this.addAbility(new EntersBattlefieldAbility(
new AddCountersSourceEffect(
- CounterType.P1P1.createInstance(),
- new CardsInAllGraveyardsCount(new FilterCreatureCard()),
+ CounterType.P1P1.createInstance(),
+ new CardsInAllGraveyardsCount(StaticFilters.FILTER_CARD_CREATURE),
false),
"with X +1/+1 counters on it, where X is the number of creature cards in all graveyards"));
-
+
// {2}{B}, Remove a +1/+1 counter from Drakestown Forgotten: Target creature gets -1/-1 until end of turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(-1, -1, Duration.EndOfTurn), new ManaCostsImpl<>("{2}{B}"));
ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance()));
diff --git a/Mage.Sets/src/mage/cards/d/DrakusethMawOfFlames.java b/Mage.Sets/src/mage/cards/d/DrakusethMawOfFlames.java
index dc1bb3e29ee..bf50bee430e 100644
--- a/Mage.Sets/src/mage/cards/d/DrakusethMawOfFlames.java
+++ b/Mage.Sets/src/mage/cards/d/DrakusethMawOfFlames.java
@@ -1,5 +1,6 @@
package mage.cards.d;
+import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
@@ -11,13 +12,14 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
+import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
+import mage.filter.predicate.mageobject.AnotherTargetPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
+import mage.target.Target;
import mage.target.common.TargetAnyTarget;
-import java.util.UUID;
-
/**
* @author TheElk801
*/
@@ -36,8 +38,16 @@ public final class DrakusethMawOfFlames extends CardImpl {
// Whenever Drakuseth, Maw of Flames attacks, it deals 4 damage to any target and 3 damage to each of up to two other targets.
Ability ability = new AttacksTriggeredAbility(new DrakusethMawOfFlamesEffect(), false);
- ability.addTarget(new TargetAnyTarget().withChooseHint("to deal 4 damage"));
- ability.addTarget(new TargetAnyTarget(0, 2).withChooseHint("to deal 3 damage"));
+ Target target = new TargetAnyTarget().withChooseHint("to deal 4 damage");
+ target.setTargetTag(1);
+ ability.addTarget(target);
+ FilterCreaturePlayerOrPlaneswalker filter = new FilterCreaturePlayerOrPlaneswalker("any target");
+ filter.getCreatureFilter().add(new AnotherTargetPredicate(2, true));
+ filter.getPlayerFilter().add(new AnotherTargetPredicate(2, true));
+ filter.getPlaneswalkerFilter().add(new AnotherTargetPredicate(2, true));
+ target = new TargetAnyTarget(0, 2, filter).withChooseHint("to deal 3 damage");
+ target.setTargetTag(2);
+ ability.addTarget(target);
this.addAbility(ability);
}
@@ -54,8 +64,9 @@ public final class DrakusethMawOfFlames extends CardImpl {
class DrakusethMawOfFlamesEffect extends OneShotEffect {
DrakusethMawOfFlamesEffect() {
- super(Outcome.Benefit);
- staticText = "it deals 4 damage to any target and 3 damage to each of up to two other targets.";
+ super(Outcome.Damage);
+ staticText = "it deals 4 damage to any target and 3 damage to each of "
+ + "up to two other targets.";
}
private DrakusethMawOfFlamesEffect(final DrakusethMawOfFlamesEffect effect) {
@@ -81,13 +92,11 @@ class DrakusethMawOfFlamesEffect extends OneShotEffect {
private static void damage(int damage, UUID targetId, Game game, Ability source) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
- permanent.damage(damage, source.getSourceId(), game);
- return;
+ permanent.damage(damage, source.getSourceId(), game, false, true);
}
Player player = game.getPlayer(targetId);
if (player != null) {
- player.damage(damage, source.getSourceId(), game);
- return;
+ player.damage(damage, source.getSourceId(), game, false, true);
}
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/d/DralnusPet.java b/Mage.Sets/src/mage/cards/d/DralnusPet.java
index 5bc6d64742d..f5b527f1373 100644
--- a/Mage.Sets/src/mage/cards/d/DralnusPet.java
+++ b/Mage.Sets/src/mage/cards/d/DralnusPet.java
@@ -1,4 +1,3 @@
-
package mage.cards.d;
import java.util.UUID;
@@ -22,11 +21,11 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AbilityType;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.counters.CounterType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -47,7 +46,7 @@ public final class DralnusPet extends CardImpl {
// Kicker-{2}{B}, Discard a creature card.
Costs kickerCosts = new CostsImpl<>();
kickerCosts.add(new ManaCostsImpl<>("{2}{B}"));
- kickerCosts.add(new DiscardCardCost(new FilterCreatureCard()));
+ kickerCosts.add(new DiscardCardCost(StaticFilters.FILTER_CARD_CREATURE));
this.addAbility(new KickerAbility(kickerCosts));
// If Dralnu's Pet was kicked, it enters the battlefield with flying and with X +1/+1 counters on it, where X is the discarded card's converted mana cost.
Ability ability = new EntersBattlefieldAbility(new DralnusPetEffect(), KickedCondition.instance,
diff --git a/Mage.Sets/src/mage/cards/d/DreadWarlock.java b/Mage.Sets/src/mage/cards/d/DreadWarlock.java
index 7652b982f56..48c352c4f15 100644
--- a/Mage.Sets/src/mage/cards/d/DreadWarlock.java
+++ b/Mage.Sets/src/mage/cards/d/DreadWarlock.java
@@ -31,6 +31,7 @@ public final class DreadWarlock extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}{B}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
+ this.subtype.add(SubType.WARLOCK);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
diff --git a/Mage.Sets/src/mage/cards/d/DreadhordeArcanist.java b/Mage.Sets/src/mage/cards/d/DreadhordeArcanist.java
index 0a7880c94c7..94c9c39694d 100644
--- a/Mage.Sets/src/mage/cards/d/DreadhordeArcanist.java
+++ b/Mage.Sets/src/mage/cards/d/DreadhordeArcanist.java
@@ -50,7 +50,10 @@ public final class DreadhordeArcanist extends CardImpl {
// Trample
this.addAbility(TrampleAbility.getInstance());
- // Whenever Dreadhorde Arcanist attacks, you may cast target instant or sorcery card with converted mana cost less than or equal to Dreadhorde Arcanist's power from your graveyard without paying its mana cost. If that card would be put into your graveyard this turn, exile it instead.
+ // Whenever Dreadhorde Arcanist attacks, you may cast target instant or
+ // sorcery card with converted mana cost less than or equal to Dreadhorde Arcanist's
+ // power from your graveyard without paying its mana cost. If that card would be put
+ // into your graveyard this turn, exile it instead.
Ability ability = new AttacksTriggeredAbility(new DreadhordeArcanistEffect(), false);
ability.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(ability);
@@ -80,10 +83,10 @@ enum DreadhordeArcanistPredicate implements ObjectSourcePlayerPredicate {
+ instance;
+
+ @Override
+ public boolean apply(MageObject input, Game game) {
+ Player player = game.getPlayer(game.getControllerId(input.getId()));
+ return player != null && input.getConvertedManaCost() <= player.getGraveyard().size();
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/d/DryadsCaress.java b/Mage.Sets/src/mage/cards/d/DryadsCaress.java
index 6c0fa378375..4450f3abf2d 100644
--- a/Mage.Sets/src/mage/cards/d/DryadsCaress.java
+++ b/Mage.Sets/src/mage/cards/d/DryadsCaress.java
@@ -33,7 +33,7 @@ public final class DryadsCaress extends CardImpl {
//If {W} was spent to cast Dryad's Caress, untap all creatures you control.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new UntapAllControllerEffect(new FilterControlledCreaturePermanent(), rule),
- new ManaWasSpentCondition(ColoredManaSymbol.W), "If {W} was spent to cast {this}, untap all creatures you control"));
+ new ManaWasSpentCondition(ColoredManaSymbol.W), "If {W} was spent to cast this spell, untap all creatures you control"));
}
public DryadsCaress(final DryadsCaress card) {
diff --git a/Mage.Sets/src/mage/cards/d/DubiousChallenge.java b/Mage.Sets/src/mage/cards/d/DubiousChallenge.java
index 3bc9362d28b..5eed94c46ce 100644
--- a/Mage.Sets/src/mage/cards/d/DubiousChallenge.java
+++ b/Mage.Sets/src/mage/cards/d/DubiousChallenge.java
@@ -1,4 +1,3 @@
-
package mage.cards.d;
import java.util.UUID;
@@ -9,7 +8,7 @@ import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
@@ -22,7 +21,7 @@ import mage.target.common.TargetOpponent;
public final class DubiousChallenge extends CardImpl {
public DubiousChallenge(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}");
// Look at the top ten cards of your library, exile up to two creature cards from among them, then shuffle your library. Target opponent may choose one of the exiled cards and put it onto the battlefield under their control. Put the rest onto the battlefield under your control.
getSpellAbility().addEffect(new DubiousChallengeEffect());
@@ -65,7 +64,7 @@ class DubiousChallengeEffect extends OneShotEffect {
Cards topCards = new CardsImpl();
topCards.addAll(controller.getLibrary().getTopCards(game, 10));
controller.lookAtCards(sourceObject.getIdName(), topCards, game);
- TargetCard targetCreatures = new TargetCard(0, 2, Zone.LIBRARY, new FilterCreatureCard());
+ TargetCard targetCreatures = new TargetCard(0, 2, Zone.LIBRARY, StaticFilters.FILTER_CARD_CREATURE);
controller.choose(outcome, topCards, targetCreatures, game);
Cards exiledCards = new CardsImpl(targetCreatures.getTargets());
if (!exiledCards.isEmpty()) {
@@ -73,7 +72,7 @@ class DubiousChallengeEffect extends OneShotEffect {
controller.shuffleLibrary(source, game);
Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source));
if (opponent != null) {
- TargetCard targetOpponentCreature = new TargetCard(0, 1, Zone.EXILED, new FilterCreatureCard());
+ TargetCard targetOpponentCreature = new TargetCard(0, 1, Zone.EXILED, StaticFilters.FILTER_CARD_CREATURE);
DubiousChallengeMoveToBattlefieldEffect opponentEffect = (DubiousChallengeMoveToBattlefieldEffect) source.getEffects().get(1);
DubiousChallengeMoveToBattlefieldEffect controllerEffect = (DubiousChallengeMoveToBattlefieldEffect) source.getEffects().get(2);
if (opponent.choose(outcome, exiledCards, targetOpponentCreature, game)) {
@@ -111,8 +110,7 @@ class DubiousChallengeMoveToBattlefieldEffect extends OneShotEffect {
return new DubiousChallengeMoveToBattlefieldEffect(this);
}
- public void setPlayerAndCards(Player targetPlayer, Cards targetCards)
- {
+ public void setPlayerAndCards(Player targetPlayer, Cards targetCards) {
this.player = targetPlayer;
this.cards = targetCards;
}
diff --git a/Mage.Sets/src/mage/cards/d/DwarvenDriller.java b/Mage.Sets/src/mage/cards/d/DwarvenDriller.java
index 5e6a3e91b4d..e956f5fa221 100644
--- a/Mage.Sets/src/mage/cards/d/DwarvenDriller.java
+++ b/Mage.Sets/src/mage/cards/d/DwarvenDriller.java
@@ -31,7 +31,7 @@ public final class DwarvenDriller extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- // {tap}: Destroy target land unless its controller has Dwarven Driller deal 2 damage to him or her.
+ // {tap}: Destroy target land unless its controller has Dwarven Driller deal 2 damage to them.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DwarvenDrillerEffect(), new TapSourceCost());
ability.addTarget(new TargetLandPermanent());
this.addAbility(ability);
@@ -51,7 +51,7 @@ class DwarvenDrillerEffect extends OneShotEffect {
public DwarvenDrillerEffect() {
super(Outcome.Detriment);
- this.staticText = "Destroy target land unless its controller has {this} deal 2 damage to him or her";
+ this.staticText = "Destroy target land unless its controller has {this} deal 2 damage to them";
}
public DwarvenDrillerEffect(final DwarvenDrillerEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/d/DwarvenMine.java b/Mage.Sets/src/mage/cards/d/DwarvenMine.java
new file mode 100644
index 00000000000..bf26b0e4b4f
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/d/DwarvenMine.java
@@ -0,0 +1,64 @@
+package mage.cards.d;
+
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.common.EntersBattlefieldUntappedTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.TapSourceEffect;
+import mage.abilities.mana.RedManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.game.permanent.token.DwarfToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class DwarvenMine extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterControlledPermanent(SubType.MOUNTAIN);
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ }
+
+ private static final Condition condition
+ = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.FEWER_THAN, 3);
+
+ public DwarvenMine(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ this.subtype.add(SubType.MOUNTAIN);
+
+ // ({T}: Add {R}.)
+ this.addAbility(new RedManaAbility());
+
+ // Dwarven Mine enters the battlefield tapped unless you control three or more other Mountains.
+ this.addAbility(new EntersBattlefieldAbility(
+ new ConditionalOneShotEffect(new TapSourceEffect(), condition),
+ "tapped unless you control three or more other Mountains"
+ ));
+
+ // When Dwarven Mine enters the battlefield untapped, create a 1/1 red Dwarf creature token.
+ this.addAbility(new EntersBattlefieldUntappedTriggeredAbility(new CreateTokenEffect(new DwarfToken()), false));
+ }
+
+ private DwarvenMine(final DwarvenMine card) {
+ super(card);
+ }
+
+ @Override
+ public DwarvenMine copy() {
+ return new DwarvenMine(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/d/DwarvenSong.java b/Mage.Sets/src/mage/cards/d/DwarvenSong.java
index 6cae2173d93..ac6962d25f4 100644
--- a/Mage.Sets/src/mage/cards/d/DwarvenSong.java
+++ b/Mage.Sets/src/mage/cards/d/DwarvenSong.java
@@ -1,7 +1,5 @@
-
package mage.cards.d;
-import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BecomesColorTargetEffect;
@@ -9,11 +7,11 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
-import mage.filter.StaticFilters;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author maxlebedev
*/
public final class DwarvenSong extends CardImpl {
@@ -23,13 +21,12 @@ public final class DwarvenSong extends CardImpl {
// Any number of target creatures become red until end of turn.
Effect effect = new BecomesColorTargetEffect(ObjectColor.RED, Duration.EndOfTurn);
- effect.setText("Any number of target creatures become red until end of turn");
+ effect.setText("One or more target creatures become red until end of turn");
this.getSpellAbility().addEffect(effect);
- this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, Integer.MAX_VALUE, StaticFilters.FILTER_PERMANENT_CREATURE, false));
-
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent(1, Integer.MAX_VALUE));
}
- public DwarvenSong(final DwarvenSong card) {
+ private DwarvenSong(final DwarvenSong card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/e/EarlyHarvest.java b/Mage.Sets/src/mage/cards/e/EarlyHarvest.java
index a2d55ce1c94..414e8568efc 100644
--- a/Mage.Sets/src/mage/cards/e/EarlyHarvest.java
+++ b/Mage.Sets/src/mage/cards/e/EarlyHarvest.java
@@ -25,7 +25,7 @@ public final class EarlyHarvest extends CardImpl {
public EarlyHarvest(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{G}{G}");
- // Target player untaps all basic lands he or she controls.
+ // Target player untaps all basic lands they control.
this.getSpellAbility().addEffect(new UntapAllLandsTargetEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
}
@@ -49,7 +49,7 @@ class UntapAllLandsTargetEffect extends OneShotEffect {
public UntapAllLandsTargetEffect() {
super(Outcome.Untap);
- staticText = "Target player untaps all basic lands he or she controls";
+ staticText = "Target player untaps all basic lands they control";
}
public UntapAllLandsTargetEffect(final UntapAllLandsTargetEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/e/EarthshakerGiant.java b/Mage.Sets/src/mage/cards/e/EarthshakerGiant.java
new file mode 100644
index 00000000000..8c6c2c75216
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EarthshakerGiant.java
@@ -0,0 +1,53 @@
+package mage.cards.e;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.continuous.BoostControlledEffect;
+import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
+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.filter.StaticFilters;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class EarthshakerGiant extends CardImpl {
+
+ public EarthshakerGiant(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}");
+
+ this.subtype.add(SubType.GIANT);
+ this.subtype.add(SubType.DRUID);
+ this.power = new MageInt(6);
+ this.toughness = new MageInt(6);
+
+ // Trample
+ this.addAbility(TrampleAbility.getInstance());
+
+ // When Earthshaker Giant enters the battlefield, other creatures you control get +3/+3 and gain trample until end of turn.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new BoostControlledEffect(
+ 3, 3, Duration.EndOfTurn, true
+ ).setText("other creatures you control get +3/+3"));
+ ability.addEffect(new GainAbilityControlledEffect(
+ TrampleAbility.getInstance(), Duration.EndOfTurn,
+ StaticFilters.FILTER_PERMANENT_CREATURE, true
+ ).setText("and gain trample until end of turn"));
+ this.addAbility(ability);
+ }
+
+ private EarthshakerGiant(final EarthshakerGiant card) {
+ super(card);
+ }
+
+ @Override
+ public EarthshakerGiant copy() {
+ return new EarthshakerGiant(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/EaterOfTheDead.java b/Mage.Sets/src/mage/cards/e/EaterOfTheDead.java
index 982ab47c2f9..f70c7d8dd34 100644
--- a/Mage.Sets/src/mage/cards/e/EaterOfTheDead.java
+++ b/Mage.Sets/src/mage/cards/e/EaterOfTheDead.java
@@ -1,4 +1,3 @@
-
package mage.cards.e;
import java.util.UUID;
@@ -11,10 +10,10 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCardInGraveyard;
@@ -26,14 +25,14 @@ import mage.target.common.TargetCardInGraveyard;
public final class EaterOfTheDead extends CardImpl {
public EaterOfTheDead(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
this.subtype.add(SubType.HORROR);
this.power = new MageInt(3);
this.toughness = new MageInt(4);
// {0}: If Eater of the Dead is tapped, exile target creature card from a graveyard and untap Eater of the Dead.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new EaterOfTheDeadEffect(), new GenericManaCost(0));
- ability.addTarget(new TargetCardInGraveyard(new FilterCreatureCard()));
+ ability.addTarget(new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE));
this.addAbility(ability);
}
@@ -48,6 +47,7 @@ public final class EaterOfTheDead extends CardImpl {
}
class EaterOfTheDeadEffect extends OneShotEffect {
+
EaterOfTheDeadEffect() {
super(Outcome.DestroyPermanent);
staticText = "If {this} is tapped, exile target creature card from a graveyard and untap {this}";
diff --git a/Mage.Sets/src/mage/cards/e/EbonyOwlNetsuke.java b/Mage.Sets/src/mage/cards/e/EbonyOwlNetsuke.java
index 886a8886a12..4a9dc522342 100644
--- a/Mage.Sets/src/mage/cards/e/EbonyOwlNetsuke.java
+++ b/Mage.Sets/src/mage/cards/e/EbonyOwlNetsuke.java
@@ -23,7 +23,7 @@ public final class EbonyOwlNetsuke extends CardImpl {
public EbonyOwlNetsuke(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
- // At the beginning of each opponent's upkeep, if that player has seven or more cards in hand, Ebony Owl Netsuke deals 4 damage to him or her.
+ // At the beginning of each opponent's upkeep, if that player has seven or more cards in hand, Ebony Owl Netsuke deals 4 damage to that player.
this.addAbility(new EbonyOwlNetsukeTriggeredAbility());
}
diff --git a/Mage.Sets/src/mage/cards/e/EchoChamber.java b/Mage.Sets/src/mage/cards/e/EchoChamber.java
index 7702cfbef9d..49e226f2e2c 100644
--- a/Mage.Sets/src/mage/cards/e/EchoChamber.java
+++ b/Mage.Sets/src/mage/cards/e/EchoChamber.java
@@ -34,7 +34,7 @@ public final class EchoChamber extends CardImpl {
public EchoChamber(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
- // {4}, {tap}: An opponent chooses target creature he or she controls. Create a token that's a copy of that creature. That token gains haste until end of turn. Exile the token at the beginning of the next end step. Activate this ability only any time you could cast a sorcery.
+ // {4}, {tap}: An opponent chooses target creature they control. Create a token that's a copy of that creature. That token gains haste until end of turn. Exile the token at the beginning of the next end step. Activate this ability only any time you could cast a sorcery.
Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new EchoChamberCreateTokenEffect(), new GenericManaCost(4));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetOpponentsChoicePermanent(1, 1, filter, false, true));
@@ -55,7 +55,7 @@ class EchoChamberCreateTokenEffect extends OneShotEffect {
EchoChamberCreateTokenEffect() {
super(Outcome.Copy);
- this.staticText = "An opponent chooses target creature he or she controls. Create a token that's a copy of that creature. That token gains haste until end of turn. Exile the token at the beginning of the next end step";
+ this.staticText = "An opponent chooses target creature they control. Create a token that's a copy of that creature. That token gains haste until end of turn. Exile the token at the beginning of the next end step";
}
EchoChamberCreateTokenEffect(final EchoChamberCreateTokenEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/e/EdgewallInnkeeper.java b/Mage.Sets/src/mage/cards/e/EdgewallInnkeeper.java
new file mode 100644
index 00000000000..95ef140f1fc
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EdgewallInnkeeper.java
@@ -0,0 +1,50 @@
+package mage.cards.e;
+
+import mage.MageInt;
+import mage.abilities.common.SpellCastControllerTriggeredAbility;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterSpell;
+import mage.filter.common.FilterCreatureSpell;
+import mage.filter.predicate.mageobject.AdventurePredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class EdgewallInnkeeper extends CardImpl {
+
+ private static final FilterSpell filter
+ = new FilterCreatureSpell("a creature spell that has an Adventure");
+
+ static {
+ filter.add(AdventurePredicate.instance);
+ }
+
+ public EdgewallInnkeeper(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.PEASANT);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Whenever you cast a creature spell that has an Adventure, draw a card.
+ this.addAbility(new SpellCastControllerTriggeredAbility(
+ new DrawCardSourceControllerEffect(1), filter, false
+ ));
+ }
+
+ private EdgewallInnkeeper(final EdgewallInnkeeper card) {
+ super(card);
+ }
+
+ @Override
+ public EdgewallInnkeeper copy() {
+ return new EdgewallInnkeeper(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/EidolonOfPhilosophy.java b/Mage.Sets/src/mage/cards/e/EidolonOfPhilosophy.java
new file mode 100644
index 00000000000..fe02b244343
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EidolonOfPhilosophy.java
@@ -0,0 +1,45 @@
+package mage.cards.e;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+
+import java.util.UUID;
+
+/**
+ * @author jmharmon
+ */
+
+public final class EidolonOfPhilosophy extends CardImpl {
+
+ public EidolonOfPhilosophy(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{U}");
+
+ this.subtype.add(SubType.SPIRIT);
+
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(2);
+
+ // {6}{U}, Sacrifice Eidolon of Philosophy: Draw three cards.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(3), new ManaCostsImpl("{6}{U}"));
+ ability.addCost(new SacrificeSourceCost());
+ this.addAbility(ability);
+ }
+
+ public EidolonOfPhilosophy(final EidolonOfPhilosophy card) {
+ super(card);
+ }
+
+ @Override
+ public EidolonOfPhilosophy copy() {
+ return new EidolonOfPhilosophy(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/ElementalUprising.java b/Mage.Sets/src/mage/cards/e/ElementalUprising.java
index 319dcf1e2f0..56fb5578331 100644
--- a/Mage.Sets/src/mage/cards/e/ElementalUprising.java
+++ b/Mage.Sets/src/mage/cards/e/ElementalUprising.java
@@ -27,11 +27,11 @@ public final class ElementalUprising extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{G}");
// Target land you control becomes a 4/4 Elemental creature with haste until end of turn. It's still a land. It must be blocked this turn if able.
- getSpellAbility().addEffect(new BecomesCreatureTargetEffect(new ElementalUprisingToken(), false, true, Duration.EndOfTurn));
- getSpellAbility().addTarget(new TargetPermanent(new FilterControlledLandPermanent()));
+ this.getSpellAbility().addEffect(new BecomesCreatureTargetEffect(new ElementalUprisingToken(), false, true, Duration.EndOfTurn));
+ this.getSpellAbility().addTarget(new TargetPermanent(new FilterControlledLandPermanent()));
Effect effect = new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn);
effect.setText("It must be blocked this turn if able");
- getSpellAbility().addEffect(effect);
+ this.getSpellAbility().addEffect(effect);
}
public ElementalUprising(final ElementalUprising card) {
diff --git a/Mage.Sets/src/mage/cards/e/ElephantGrass.java b/Mage.Sets/src/mage/cards/e/ElephantGrass.java
index 41c52799bc3..b261c624cff 100644
--- a/Mage.Sets/src/mage/cards/e/ElephantGrass.java
+++ b/Mage.Sets/src/mage/cards/e/ElephantGrass.java
@@ -40,7 +40,7 @@ public final class ElephantGrass extends CardImpl {
// Black creatures can't attack you.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackYouAllEffect(Duration.WhileOnBattlefield, filterBlack)));
- // Nonblack creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you.
+ // Nonblack creatures can't attack you unless their controller pays {2} for each creature they control that's attacking you.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackYouUnlessPayManaAllEffect(new ManaCostsImpl<>("{2"), false, filter)));
}
diff --git a/Mage.Sets/src/mage/cards/e/ElfhameSanctuary.java b/Mage.Sets/src/mage/cards/e/ElfhameSanctuary.java
index 15beccd114e..7007ce985b8 100644
--- a/Mage.Sets/src/mage/cards/e/ElfhameSanctuary.java
+++ b/Mage.Sets/src/mage/cards/e/ElfhameSanctuary.java
@@ -19,22 +19,23 @@ import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
/**
- *
* @author Markedagain
*/
public final class ElfhameSanctuary extends CardImpl {
public ElfhameSanctuary(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
// At the beginning of your upkeep, you may search your library for a basic land card, reveal that card, and put it into your hand. If you do, you skip your draw step this turn and shuffle your library.
- Ability ability = new BeginningOfUpkeepTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND)), TargetController.YOU, true);
+ Ability ability = new BeginningOfUpkeepTriggeredAbility(new SearchLibraryPutInHandEffect(
+ new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true
+ ), TargetController.YOU, true);
ability.addEffect(new SkipDrawStepThisTurn());
-
+
this.addAbility(ability);
}
- public ElfhameSanctuary(final ElfhameSanctuary card) {
+ private ElfhameSanctuary(final ElfhameSanctuary card) {
super(card);
}
@@ -46,12 +47,12 @@ public final class ElfhameSanctuary extends CardImpl {
class SkipDrawStepThisTurn extends ReplacementEffectImpl {
- public SkipDrawStepThisTurn() {
+ SkipDrawStepThisTurn() {
super(Duration.UntilYourNextTurn, Outcome.Neutral);
staticText = "Skip your draw step this turn";
}
- public SkipDrawStepThisTurn(final SkipDrawStepThisTurn effect) {
+ private SkipDrawStepThisTurn(final SkipDrawStepThisTurn effect) {
super(effect);
}
diff --git a/Mage.Sets/src/mage/cards/e/EliteArcanist.java b/Mage.Sets/src/mage/cards/e/EliteArcanist.java
index 9ca13d7fa50..37f39b971d9 100644
--- a/Mage.Sets/src/mage/cards/e/EliteArcanist.java
+++ b/Mage.Sets/src/mage/cards/e/EliteArcanist.java
@@ -1,4 +1,3 @@
-
package mage.cards.e;
import mage.MageInt;
@@ -132,8 +131,9 @@ class EliteArcanistImprintEffect extends OneShotEffect {
class EliteArcanistCopyEffect extends OneShotEffect {
public EliteArcanistCopyEffect() {
- super(Outcome.Copy);
- this.staticText = "Copy the exiled card. You may cast the copy without paying its mana cost. X is the converted mana cost of the exiled card";
+ super(Outcome.PlayForFree);
+ this.staticText = "Copy the exiled card. You may cast the copy "
+ + "without paying its mana cost. X is the converted mana cost of the exiled card";
}
public EliteArcanistCopyEffect(final EliteArcanistCopyEffect effect) {
@@ -151,17 +151,24 @@ class EliteArcanistCopyEffect extends OneShotEffect {
if (sourcePermanent == null) {
sourcePermanent = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
}
- if (sourcePermanent != null && sourcePermanent.getImprinted() != null && !sourcePermanent.getImprinted().isEmpty()) {
+ if (sourcePermanent != null
+ && sourcePermanent.getImprinted() != null
+ && !sourcePermanent.getImprinted().isEmpty()) {
Card imprintedInstant = game.getCard(sourcePermanent.getImprinted().get(0));
- if (imprintedInstant != null && game.getState().getZone(imprintedInstant.getId()) == Zone.EXILED) {
+ if (imprintedInstant != null
+ && game.getState().getZone(imprintedInstant.getId()) == Zone.EXILED) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Card copiedCard = game.copyCard(imprintedInstant, source, source.getControllerId());
if (copiedCard != null) {
game.getExile().add(source.getSourceId(), "", copiedCard);
game.getState().setZone(copiedCard.getId(), Zone.EXILED);
- if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
- return controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ if (controller.chooseUse(Outcome.PlayForFree, "Cast the copied card without paying mana cost?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(copiedCard, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), null);
+ return cardWasCast;
}
}
}
diff --git a/Mage.Sets/src/mage/cards/e/EliteHeadhunter.java b/Mage.Sets/src/mage/cards/e/EliteHeadhunter.java
new file mode 100644
index 00000000000..b5e86c75379
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EliteHeadhunter.java
@@ -0,0 +1,77 @@
+package mage.cards.e;
+
+import mage.MageInt;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.keyword.MenaceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.ObjectSourcePlayer;
+import mage.filter.predicate.ObjectSourcePlayerPredicate;
+import mage.game.Game;
+import mage.target.common.TargetControlledPermanent;
+import mage.target.common.TargetCreatureOrPlaneswalker;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class EliteHeadhunter extends CardImpl {
+
+ private static final FilterControlledPermanent filter
+ = new FilterControlledPermanent("another creature or an artifact");
+
+ static {
+ filter.add(EliteHeadhunterPredicate.instance);
+ }
+
+ public EliteHeadhunter(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B/R}{B/R}{B/R}{B/R}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // Menace
+ this.addAbility(new MenaceAbility());
+
+ // {B/R}{B/R}{B/R}, Sacrifice another creature or an artifact: Elite Headhunter deals 2 damage to target creature or planeswalker.
+ Ability ability = new SimpleActivatedAbility(
+ new DamageTargetEffect(2), new ManaCostsImpl("{B/R}{B/R}{B/R}")
+ );
+ ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter)));
+ ability.addTarget(new TargetCreatureOrPlaneswalker());
+ this.addAbility(ability);
+ }
+
+ private EliteHeadhunter(final EliteHeadhunter card) {
+ super(card);
+ }
+
+ @Override
+ public EliteHeadhunter copy() {
+ return new EliteHeadhunter(this);
+ }
+}
+
+enum EliteHeadhunterPredicate implements ObjectSourcePlayerPredicate> {
+ instance;
+
+ @Override
+ public boolean apply(ObjectSourcePlayer input, Game game) {
+ MageObject obj = input.getObject();
+ if (obj.getId().equals(input.getSourceId())) {
+ return obj.isArtifact();
+ }
+ return obj.isCreature() || obj.isArtifact();
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/ElkinLair.java b/Mage.Sets/src/mage/cards/e/ElkinLair.java
index 5822a8bfb24..fda9f86843c 100644
--- a/Mage.Sets/src/mage/cards/e/ElkinLair.java
+++ b/Mage.Sets/src/mage/cards/e/ElkinLair.java
@@ -35,7 +35,7 @@ public final class ElkinLair extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
addSuperType(SuperType.WORLD);
- // At the beginning of each player's upkeep, that player exiles a card at random from their hand. The player may play that card this turn. At the beginning of the next end step, if the player hasn't played the card, he or she puts it into their graveyard.
+ // At the beginning of each player's upkeep, that player exiles a card at random from their hand. The player may play that card this turn. At the beginning of the next end step, if the player hasn't played the card, they put it into their graveyard.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ElkinLairUpkeepEffect(), TargetController.ANY, false));
}
@@ -58,7 +58,7 @@ class ElkinLairUpkeepEffect extends OneShotEffect {
this.staticText = "that player exiles a card at random from their hand. "
+ "The player may play that card this turn. "
+ "At the beginning of the next end step, if the "
- + "player hasn't played the card, he or she puts it into their graveyard";
+ + "player hasn't played the card, they put it into their graveyard";
}
public ElkinLairUpkeepEffect(final ElkinLairUpkeepEffect effect) {
@@ -103,7 +103,7 @@ class ElkinLairPutIntoGraveyardEffect extends OneShotEffect {
public ElkinLairPutIntoGraveyardEffect() {
super(Outcome.Neutral);
- staticText = "if the player hasn't played the card, he or she puts it into their graveyard";
+ staticText = "if the player hasn't played the card, they put it into their graveyard";
}
public ElkinLairPutIntoGraveyardEffect(final ElkinLairPutIntoGraveyardEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/e/ElshaOfTheInfinite.java b/Mage.Sets/src/mage/cards/e/ElshaOfTheInfinite.java
index 211afb1cc4d..3dfdc703be5 100644
--- a/Mage.Sets/src/mage/cards/e/ElshaOfTheInfinite.java
+++ b/Mage.Sets/src/mage/cards/e/ElshaOfTheInfinite.java
@@ -7,7 +7,6 @@ import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashAllEffect;
import mage.abilities.effects.common.continuous.LookAtTopCardOfLibraryAnyTimeEffect;
import mage.abilities.effects.common.continuous.PlayTheTopCardEffect;
import mage.abilities.keyword.ProwessAbility;
-import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -16,11 +15,8 @@ import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterCard;
import mage.filter.common.FilterNonlandCard;
-import mage.filter.predicate.Predicate;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
-import mage.game.Game;
-import mage.players.Player;
import java.util.UUID;
@@ -33,7 +29,6 @@ public final class ElshaOfTheInfinite extends CardImpl {
static {
filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
- filter.add(ElshaOfTheInfinitePredicate.instance);
}
public ElshaOfTheInfinite(UUID ownerId, CardSetInfo setInfo) {
@@ -72,13 +67,3 @@ public final class ElshaOfTheInfinite extends CardImpl {
return new ElshaOfTheInfinite(this);
}
}
-
-enum ElshaOfTheInfinitePredicate implements Predicate {
- instance;
-
- @Override
- public boolean apply(Card input, Game game) {
- Player player = game.getPlayer(input.getOwnerId());
- return player != null && player.getLibrary().getFromTop(game).equals(input);
- }
-}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/e/ElspethSunsNemesis.java b/Mage.Sets/src/mage/cards/e/ElspethSunsNemesis.java
new file mode 100644
index 00000000000..22c8b5ef11b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/ElspethSunsNemesis.java
@@ -0,0 +1,56 @@
+package mage.cards.e;
+
+import mage.abilities.Ability;
+import mage.abilities.LoyaltyAbility;
+import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.abilities.keyword.EscapeAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.game.permanent.token.HumanSoldierToken;
+import mage.target.common.TargetControlledCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ElspethSunsNemesis extends CardImpl {
+
+ public ElspethSunsNemesis(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{W}{W}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.ELSPETH);
+ this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+
+ // −1: Up to two target creatures you control each get +2/+1 until end of turn.
+ Ability ability = new LoyaltyAbility(new BoostTargetEffect(2, 1)
+ .setText("up to two target creatures you control each get +2/+1 until end of turn"), -1);
+ ability.addTarget(new TargetControlledCreaturePermanent(0, 2));
+ this.addAbility(ability);
+
+ // −2: Create two 1/1 white Human Soldier creature tokens.
+ this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new HumanSoldierToken(), 2), -2));
+
+ // −3: You gain 5 life.
+ this.addAbility(new LoyaltyAbility(new GainLifeEffect(5), -3));
+
+ // Escape—{4}{W}{W}, Exile four other cards from your graveyard.
+ this.addAbility(new EscapeAbility(this, "{4}{W}{W}", 4));
+ }
+
+ private ElspethSunsNemesis(final ElspethSunsNemesis card) {
+ super(card);
+ }
+
+ @Override
+ public ElspethSunsNemesis copy() {
+ return new ElspethSunsNemesis(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/ElspethUndauntedHero.java b/Mage.Sets/src/mage/cards/e/ElspethUndauntedHero.java
new file mode 100644
index 00000000000..445548bb214
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/ElspethUndauntedHero.java
@@ -0,0 +1,72 @@
+package mage.cards.e;
+
+import mage.abilities.Ability;
+import mage.abilities.LoyaltyAbility;
+import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
+import mage.abilities.dynamicvalue.common.DevotionCount;
+import mage.abilities.effects.common.continuous.BoostControlledEffect;
+import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.abilities.effects.common.search.SearchLibraryGraveyardPutOntoBattlefieldEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.counters.CounterType;
+import mage.filter.FilterCard;
+import mage.filter.StaticFilters;
+import mage.filter.predicate.mageobject.NamePredicate;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ElspethUndauntedHero extends CardImpl {
+
+ private static final FilterCard filter = new FilterCard("Sunlit Hoplite");
+
+ static {
+ filter.add(new NamePredicate("Sunlit Hoplite"));
+ }
+
+ public ElspethUndauntedHero(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{W}{W}{W}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.ELSPETH);
+ this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+
+ // +2: Put a +1/+1 counter on each of up to two target creatures.
+ Ability ability = new LoyaltyAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), 2);
+ ability.addTarget(new TargetCreaturePermanent(0, 2));
+ this.addAbility(ability);
+
+ // −2: Search your library and/or graveyard for a card named Sunlit Hoplite and put it onto the battlefield. If you search your library this way, shuffle it.
+ this.addAbility(new LoyaltyAbility(new SearchLibraryGraveyardPutOntoBattlefieldEffect(filter), -2));
+
+ // −8: Until end of turn, creatures you control gain flying and get +X/+X, where X is your devotion to white.
+ ability = new LoyaltyAbility(new GainAbilityControlledEffect(
+ FlyingAbility.getInstance(), Duration.EndOfTurn,
+ StaticFilters.FILTER_PERMANENT_CREATURES
+ ).setText("Until end of turn, creatures you control gain flying"), -8);
+ ability.addEffect(new BoostControlledEffect(
+ DevotionCount.W, DevotionCount.W, Duration.EndOfTurn
+ ).setText("and get +X/+X, where X is your devotion to white"));
+ ability.addHint(DevotionCount.W.getHint());
+ this.addAbility(ability);
+ }
+
+ private ElspethUndauntedHero(final ElspethUndauntedHero card) {
+ super(card);
+ }
+
+ @Override
+ public ElspethUndauntedHero copy() {
+ return new ElspethUndauntedHero(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/ElvishHealer.java b/Mage.Sets/src/mage/cards/e/ElvishHealer.java
new file mode 100644
index 00000000000..27199744592
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/ElvishHealer.java
@@ -0,0 +1,79 @@
+package mage.cards.e;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.PreventDamageToTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetAnyTarget;
+import mage.target.targetpointer.FixedTarget;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ElvishHealer extends CardImpl {
+
+ public ElvishHealer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
+
+ this.subtype.add(SubType.ELF);
+ this.subtype.add(SubType.CLERIC);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(2);
+
+ // {T}: Prevent the next 1 damage that would be dealt to any target this turn. If it’s a green creature, prevent the next 2 damage instead.
+ Ability ability = new SimpleActivatedAbility(new ElvishHealerEffect(), new TapSourceCost());
+ ability.addTarget(new TargetAnyTarget());
+ this.addAbility(ability);
+ }
+
+ private ElvishHealer(final ElvishHealer card) {
+ super(card);
+ }
+
+ @Override
+ public ElvishHealer copy() {
+ return new ElvishHealer(this);
+ }
+}
+
+class ElvishHealerEffect extends OneShotEffect {
+
+ ElvishHealerEffect() {
+ super(Outcome.Benefit);
+ staticText = "Prevent the next 1 damage that would be dealt to any target this turn. " +
+ "If it’s a green creature, prevent the next 2 damage instead.";
+ }
+
+ private ElvishHealerEffect(final ElvishHealerEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ElvishHealerEffect copy() {
+ return new ElvishHealerEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ int toPrevent = 1;
+ Permanent permanent = game.getPermanent(source.getFirstTarget());
+ if (permanent != null && permanent.isCreature() && permanent.getColor(game).isGreen()) {
+ toPrevent = 2;
+ }
+ game.addEffect(new PreventDamageToTargetEffect(Duration.EndOfTurn, toPrevent)
+ .setTargetPointer(new FixedTarget(source.getFirstTarget(), game)), source);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/e/Embercleave.java b/Mage.Sets/src/mage/cards/e/Embercleave.java
new file mode 100644
index 00000000000..2c0d2baa7dd
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/Embercleave.java
@@ -0,0 +1,111 @@
+package mage.cards.e;
+
+import mage.abilities.Ability;
+import mage.abilities.SpellAbility;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.continuous.BoostEquippedEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.abilities.effects.common.cost.CostModificationEffectImpl;
+import mage.abilities.keyword.DoubleStrikeAbility;
+import mage.abilities.keyword.EquipAbility;
+import mage.abilities.keyword.FlashAbility;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.permanent.AttackingPredicate;
+import mage.game.Game;
+import mage.target.common.TargetControlledCreaturePermanent;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class Embercleave extends CardImpl {
+
+ public Embercleave(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}{R}{R}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.EQUIPMENT);
+
+ // Flash
+ this.addAbility(FlashAbility.getInstance());
+
+ // This spell costs {1} less to cast for each attacking creature you control.
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new EmbercleaveCostReductionEffect()));
+
+ // When Embercleave enters the battlefield, attach it to target creature you control.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new AttachEffect(
+ Outcome.BoostCreature, "attach it to target creature you control"
+ ), false);
+ ability.addTarget(new TargetControlledCreaturePermanent());
+ this.addAbility(ability);
+
+ // Equipped creature gets +1/+1 and has double strike and trample.
+ ability = new SimpleStaticAbility(new BoostEquippedEffect(1, 1));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ DoubleStrikeAbility.getInstance(), AttachmentType.EQUIPMENT
+ ).setText("and has double strike"));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ TrampleAbility.getInstance(), AttachmentType.EQUIPMENT
+ ).setText("and trample"));
+ this.addAbility(ability);
+
+ // Equip {3}
+ this.addAbility(new EquipAbility(3));
+ }
+
+ private Embercleave(final Embercleave card) {
+ super(card);
+ }
+
+ @Override
+ public Embercleave copy() {
+ return new Embercleave(this);
+ }
+}
+
+class EmbercleaveCostReductionEffect extends CostModificationEffectImpl {
+
+ private static final FilterPermanent filter = new FilterControlledCreaturePermanent();
+
+ static {
+ filter.add(AttackingPredicate.instance);
+ }
+
+ EmbercleaveCostReductionEffect() {
+ super(Duration.WhileOnStack, Outcome.Benefit, CostModificationType.REDUCE_COST);
+ staticText = "This spell costs {1} less to cast for each attacking creature you control";
+ }
+
+ private EmbercleaveCostReductionEffect(EmbercleaveCostReductionEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source, Ability abilityToModify) {
+ int reductionAmount = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
+ CardUtil.reduceCost(abilityToModify, reductionAmount);
+ return true;
+ }
+
+ @Override
+ public boolean applies(Ability abilityToModify, Ability source, Game game) {
+ if ((abilityToModify instanceof SpellAbility) && abilityToModify.getSourceId().equals(source.getSourceId())) {
+ return game.getCard(abilityToModify.getSourceId()) != null;
+ }
+ return false;
+ }
+
+ @Override
+ public EmbercleaveCostReductionEffect copy() {
+ return new EmbercleaveCostReductionEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/EmberethPaladin.java b/Mage.Sets/src/mage/cards/e/EmberethPaladin.java
new file mode 100644
index 00000000000..001ca3a7b69
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EmberethPaladin.java
@@ -0,0 +1,49 @@
+package mage.cards.e;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.condition.common.AdamantCondition;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.keyword.HasteAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.watchers.common.ManaSpentToCastWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class EmberethPaladin extends CardImpl {
+
+ public EmberethPaladin(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(1);
+
+ // Haste
+ this.addAbility(HasteAbility.getInstance());
+
+ // Adamant — If at least three red mana was spent to cast this spell, Embereth Paladin enters the battlefield with a +1/+1 counter on it.
+ this.addAbility(new EntersBattlefieldAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false, AdamantCondition.RED,
+ "
Adamant — If at least three red mana was spent to cast this spell, " +
+ "{this} enters the battlefield with a +1/+1 counter on it.", ""
+ ), new ManaSpentToCastWatcher());
+ }
+
+ private EmberethPaladin(final EmberethPaladin card) {
+ super(card);
+ }
+
+ @Override
+ public EmberethPaladin copy() {
+ return new EmberethPaladin(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/EmberethShieldbreaker.java b/Mage.Sets/src/mage/cards/e/EmberethShieldbreaker.java
new file mode 100644
index 00000000000..fe781fc842c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EmberethShieldbreaker.java
@@ -0,0 +1,40 @@
+package mage.cards.e;
+
+import mage.MageInt;
+import mage.abilities.effects.common.DestroyTargetEffect;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.target.common.TargetArtifactPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class EmberethShieldbreaker extends AdventureCard {
+
+ public EmberethShieldbreaker(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{1}{R}", "Battle Display", "{R}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(1);
+
+ // Battle Display
+ // Destroy target artifact.
+ this.getSpellCard().getSpellAbility().addEffect(new DestroyTargetEffect());
+ this.getSpellCard().getSpellAbility().addTarget(new TargetArtifactPermanent());
+ }
+
+ private EmberethShieldbreaker(final EmberethShieldbreaker card) {
+ super(card);
+ }
+
+ @Override
+ public EmberethShieldbreaker copy() {
+ return new EmberethShieldbreaker(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/EmberethSkyblazer.java b/Mage.Sets/src/mage/cards/e/EmberethSkyblazer.java
new file mode 100644
index 00000000000..9eff0199960
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EmberethSkyblazer.java
@@ -0,0 +1,61 @@
+package mage.cards.e;
+
+import mage.MageInt;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.common.MyTurnCondition;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.decorator.ConditionalContinuousEffect;
+import mage.abilities.dynamicvalue.common.OpponentsCount;
+import mage.abilities.dynamicvalue.common.StaticValue;
+import mage.abilities.effects.common.DoIfCostPaid;
+import mage.abilities.effects.common.continuous.BoostControlledEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class EmberethSkyblazer extends CardImpl {
+
+ public EmberethSkyblazer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(3);
+
+ // As long as it's your turn, Embereth Skyblazer has flying.
+ this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
+ new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield),
+ MyTurnCondition.instance, "As long as it's your turn, {this} has flying."
+ )));
+
+ // Whenever Embereth Skyblazer attacks, you may pay {2}{R}. If you do, creatures you control get +X/+0 until end of turn, where X is the number of opponents you have.
+ this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(
+ new BoostControlledEffect(
+ OpponentsCount.instance, StaticValue.getZeroValue(), Duration.EndOfTurn,
+ StaticFilters.FILTER_PERMANENT_CREATURE, false, true
+ ).setText("creatures you control get +X/+0 until end of turn, where X is the number of opponents you have"),
+ new ManaCostsImpl("{2}{R}")
+ ), false));
+ }
+
+ private EmberethSkyblazer(final EmberethSkyblazer card) {
+ super(card);
+ }
+
+ @Override
+ public EmberethSkyblazer copy() {
+ return new EmberethSkyblazer(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/EmberwildeDjinn.java b/Mage.Sets/src/mage/cards/e/EmberwildeDjinn.java
index e6c89e4b877..19879c3dca7 100644
--- a/Mage.Sets/src/mage/cards/e/EmberwildeDjinn.java
+++ b/Mage.Sets/src/mage/cards/e/EmberwildeDjinn.java
@@ -41,7 +41,7 @@ public final class EmberwildeDjinn extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
- // At the beginning of each player's upkeep, that player may pay {R}{R} or 2 life. If he or she does, the player gains control of Emberwilde Djinn.
+ // At the beginning of each player's upkeep, that player may pay {R}{R} or 2 life. If they do, the player gains control of Emberwilde Djinn.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new EmberwildeDjinnEffect(), TargetController.ANY, false));
}
@@ -59,7 +59,7 @@ class EmberwildeDjinnEffect extends OneShotEffect {
EmberwildeDjinnEffect() {
super(Outcome.Benefit);
- this.staticText = "that player may pay {R}{R} or 2 life. If he or she does, the player gains control of {this}";
+ this.staticText = "that player may pay {R}{R} or 2 life. If they do, the player gains control of {this}";
}
EmberwildeDjinnEffect(final EmberwildeDjinnEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/e/EmergentGrowth.java b/Mage.Sets/src/mage/cards/e/EmergentGrowth.java
index 3aa667cbcb7..c7d9c68d461 100644
--- a/Mage.Sets/src/mage/cards/e/EmergentGrowth.java
+++ b/Mage.Sets/src/mage/cards/e/EmergentGrowth.java
@@ -23,7 +23,7 @@ public final class EmergentGrowth extends CardImpl {
// Target creature gets +5/+5 until end of turn and must be blocked this turn if able.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new BoostTargetEffect(5, 5, Duration.EndOfTurn));
- Effect effect = new MustBeBlockedByAtLeastOneTargetEffect();
+ Effect effect = new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn);
effect.setText("and must be blocked this turn if able");
this.getSpellAbility().addEffect(effect);
}
diff --git a/Mage.Sets/src/mage/cards/e/EmissaryOfDespair.java b/Mage.Sets/src/mage/cards/e/EmissaryOfDespair.java
index 47671b9de83..ed295e4897d 100644
--- a/Mage.Sets/src/mage/cards/e/EmissaryOfDespair.java
+++ b/Mage.Sets/src/mage/cards/e/EmissaryOfDespair.java
@@ -31,7 +31,7 @@ public final class EmissaryOfDespair extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
- // Whenever Emissary of Despair deals combat damage to a player, that player loses 1 life for each artifact he or she controls.
+ // Whenever Emissary of Despair deals combat damage to a player, that player loses 1 life for each artifact they control.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new LoseLifeTargetEffect(new EmissaryOfDespairCount()), false, true));
}
@@ -69,6 +69,6 @@ class EmissaryOfDespairCount implements DynamicValue {
@Override
public String getMessage() {
- return "artifact he or she controls";
+ return "artifact they control";
}
}
diff --git a/Mage.Sets/src/mage/cards/e/EmmaraTandris.java b/Mage.Sets/src/mage/cards/e/EmmaraTandris.java
index 11d0794557e..fff826969d5 100644
--- a/Mage.Sets/src/mage/cards/e/EmmaraTandris.java
+++ b/Mage.Sets/src/mage/cards/e/EmmaraTandris.java
@@ -1,33 +1,32 @@
-
package mage.cards.e;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.PreventAllDamageToAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
-import mage.filter.common.FilterCreatureOrPlayer;
-import mage.filter.predicate.other.PlayerIdPredicate;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.filter.predicate.permanent.TokenPredicate;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class EmmaraTandris extends CardImpl {
- private static final FilterCreatureOrPlayer filter = new FilterCreatureOrPlayer("creature tokens you control");
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature tokens you control");
+
static {
- filter.getCreatureFilter().add(TokenPredicate.instance);
- filter.getCreatureFilter().add(new ControllerPredicate(TargetController.YOU));
- filter.getPlayerFilter().add(new PlayerIdPredicate(UUID.randomUUID()));
+ filter.add(TokenPredicate.instance);
+ filter.add(new ControllerPredicate(TargetController.YOU));
}
public EmmaraTandris(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{G}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{W}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ELF);
this.subtype.add(SubType.SHAMAN);
@@ -36,7 +35,7 @@ public final class EmmaraTandris extends CardImpl {
this.toughness = new MageInt(7);
// Prevent all damage that would be dealt to creature tokens you control.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventAllDamageToAllEffect(Duration.WhileOnBattlefield, filter)));
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventAllDamageToAllEffect(Duration.WhileOnBattlefield, StaticFilters.FILTER_CREATURE_TOKENS)));
}
public EmmaraTandris(final EmmaraTandris card) {
diff --git a/Mage.Sets/src/mage/cards/e/EmpoweredAutogenerator.java b/Mage.Sets/src/mage/cards/e/EmpoweredAutogenerator.java
new file mode 100644
index 00000000000..3d12f810c3c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EmpoweredAutogenerator.java
@@ -0,0 +1,131 @@
+package mage.cards.e;
+
+import mage.Mana;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTappedAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.common.ManaEffect;
+import mage.abilities.mana.SimpleManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.choices.ChoiceColor;
+import mage.constants.CardType;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class EmpoweredAutogenerator extends CardImpl {
+
+ public EmpoweredAutogenerator(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
+
+ // Empowered Autogenerator enters the battlefield tapped.
+ this.addAbility(new EntersBattlefieldTappedAbility());
+
+ // {T}: Put a charge counter on Empowered Autogenerator. Add X mana of any one color, where X is the number of charge counters on Empowered Autogenerator.
+ this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new EmpoweredAutogeneratorManaEffect(), new TapSourceCost()));
+ }
+
+ private EmpoweredAutogenerator(final EmpoweredAutogenerator card) {
+ super(card);
+ }
+
+ @Override
+ public EmpoweredAutogenerator copy() {
+ return new EmpoweredAutogenerator(this);
+ }
+}
+
+class EmpoweredAutogeneratorManaEffect extends ManaEffect {
+
+ private final Mana computedMana;
+
+ EmpoweredAutogeneratorManaEffect() {
+ super();
+ computedMana = new Mana();
+ this.staticText = "Put a charge counter on {this}. Add X mana of any one color, "
+ + "where X is the number of charge counters on {this}";
+ }
+
+ private EmpoweredAutogeneratorManaEffect(final EmpoweredAutogeneratorManaEffect effect) {
+ super(effect);
+ this.computedMana = effect.computedMana.copy();
+ }
+
+ @Override
+ public EmpoweredAutogeneratorManaEffect copy() {
+ return new EmpoweredAutogeneratorManaEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Permanent sourcePermanent = game.getPermanent(source.getSourceId());
+ if (controller == null
+ || sourcePermanent == null) {
+ return false;
+ }
+ sourcePermanent.addCounters(CounterType.CHARGE.createInstance(), source, game);
+ checkToFirePossibleEvents(getMana(game, source), game, source);
+ controller.getManaPool().addMana(getMana(game, source), game, source);
+ return true;
+
+ }
+
+ @Override
+ public Mana produceMana(boolean netMana, Game game, Ability source) {
+ Mana mana = new Mana();
+ game.applyEffects();
+ Permanent sourcePermanent = game.getState().getPermanent(source.getSourceId());
+ if (sourcePermanent == null) {
+ return mana;
+ }
+ int counters = sourcePermanent.getCounters(game).getCount(CounterType.CHARGE) + 1;
+ if (counters == 0) {
+ return mana;
+ }
+ if (netMana) {
+ return new Mana(0, 0, 0, 0, 0, 0, counters, 0);
+ }
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) {
+ return mana;
+ }
+ ChoiceColor choice = new ChoiceColor();
+ choice.setMessage("Choose a color to add mana of that color");
+ if (!controller.choose(outcome, choice, game)) {
+ return mana;
+ }
+ if (choice.getChoice() == null) {
+ return mana;
+ }
+ String color = choice.getChoice();
+ switch (color) {
+ case "Red":
+ mana.setRed(counters);
+ break;
+ case "Blue":
+ mana.setBlue(counters);
+ break;
+ case "White":
+ mana.setWhite(counters);
+ break;
+ case "Black":
+ mana.setBlack(counters);
+ break;
+ case "Green":
+ mana.setGreen(counters);
+ break;
+ }
+
+ return mana;
+ }
+
+}
diff --git a/Mage.Sets/src/mage/cards/e/EmpressGalina.java b/Mage.Sets/src/mage/cards/e/EmpressGalina.java
index cf5419eed4a..f07c72a432d 100644
--- a/Mage.Sets/src/mage/cards/e/EmpressGalina.java
+++ b/Mage.Sets/src/mage/cards/e/EmpressGalina.java
@@ -1,7 +1,5 @@
-
package mage.cards.e;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -10,21 +8,18 @@ import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Duration;
-import mage.constants.SuperType;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.SupertypePredicate;
import mage.target.TargetPermanent;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class EmpressGalina extends CardImpl {
-
+
private static final FilterPermanent filter = new FilterPermanent("legendary permanent");
static {
@@ -32,9 +27,9 @@ public final class EmpressGalina extends CardImpl {
}
public EmpressGalina(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
addSuperType(SuperType.LEGENDARY);
- this.subtype.add(SubType.MERFOLK);
+ this.subtype.add(SubType.MERFOLK, SubType.NOBLE);
this.power = new MageInt(1);
this.toughness = new MageInt(3);
diff --git a/Mage.Sets/src/mage/cards/e/EmryLurkerOfTheLoch.java b/Mage.Sets/src/mage/cards/e/EmryLurkerOfTheLoch.java
new file mode 100644
index 00000000000..428efcfb497
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EmryLurkerOfTheLoch.java
@@ -0,0 +1,129 @@
+package mage.cards.e;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.SpellAbility;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.AsThoughEffectImpl;
+import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveControllerEffect;
+import mage.abilities.effects.common.cost.CostModificationEffectImpl;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.target.common.TargetCardInYourGraveyard;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class EmryLurkerOfTheLoch extends CardImpl {
+
+ public EmryLurkerOfTheLoch(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.MERFOLK);
+ this.subtype.add(SubType.WIZARD);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(2);
+
+ // This spell costs {1} less to cast for each artifact you control.
+ this.addAbility(new SimpleStaticAbility(Zone.STACK, new EmryLurkerOfTheLochCostReductionEffect()));
+
+ // When Emry, Lurker of the Loch enters the battlefield, put the top four cards of your library into your graveyard.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(
+ new PutTopCardOfLibraryIntoGraveControllerEffect(4)
+ ));
+
+ // {T}: Choose target artifact card in your graveyard. You may cast that card this turn.
+ Ability ability = new SimpleActivatedAbility(new EmryLurkerOfTheLochPlayEffect(), new TapSourceCost());
+ ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_ARTIFACT));
+ this.addAbility(ability);
+ }
+
+ private EmryLurkerOfTheLoch(final EmryLurkerOfTheLoch card) {
+ super(card);
+ }
+
+ @Override
+ public EmryLurkerOfTheLoch copy() {
+ return new EmryLurkerOfTheLoch(this);
+ }
+}
+
+class EmryLurkerOfTheLochCostReductionEffect extends CostModificationEffectImpl {
+
+ EmryLurkerOfTheLochCostReductionEffect() {
+ super(Duration.WhileOnStack, Outcome.Benefit, CostModificationType.REDUCE_COST);
+ staticText = "This spell costs {1} less to cast for each artifact you control";
+ }
+
+ private EmryLurkerOfTheLochCostReductionEffect(final EmryLurkerOfTheLochCostReductionEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source, Ability abilityToModify) {
+ int reductionAmount = game.getBattlefield().count(
+ StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT,
+ source.getSourceId(), source.getControllerId(), game
+ );
+ CardUtil.reduceCost(abilityToModify, reductionAmount);
+ return true;
+ }
+
+ @Override
+ public boolean applies(Ability abilityToModify, Ability source, Game game) {
+ return abilityToModify instanceof SpellAbility
+ && abilityToModify.getSourceId().equals(source.getSourceId())
+ && game.getCard(abilityToModify.getSourceId()) != null;
+ }
+
+ @Override
+ public EmryLurkerOfTheLochCostReductionEffect copy() {
+ return new EmryLurkerOfTheLochCostReductionEffect(this);
+ }
+}
+
+class EmryLurkerOfTheLochPlayEffect extends AsThoughEffectImpl {
+
+ EmryLurkerOfTheLochPlayEffect() {
+ super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
+ staticText = "Choose target artifact card in your graveyard. You may cast that card this turn.";
+ }
+
+ private EmryLurkerOfTheLochPlayEffect(final EmryLurkerOfTheLochPlayEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public EmryLurkerOfTheLochPlayEffect copy() {
+ return new EmryLurkerOfTheLochPlayEffect(this);
+ }
+
+ @Override
+ public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
+ UUID targetId = getTargetPointer().getFirst(game, source);
+ if (targetId != null) {
+ return targetId.equals(objectId)
+ && source.isControlledBy(affectedControllerId)
+ && Zone.GRAVEYARD == game.getState().getZone(objectId);
+ } else {
+ // the target card has changed zone meanwhile, so the effect is no longer needed
+ discard();
+ return false;
+ }
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/EnchantedCarriage.java b/Mage.Sets/src/mage/cards/e/EnchantedCarriage.java
new file mode 100644
index 00000000000..5a4b3011fc0
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EnchantedCarriage.java
@@ -0,0 +1,42 @@
+package mage.cards.e;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.constants.SubType;
+import mage.abilities.keyword.CrewAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.game.permanent.token.MouseToken;
+
+/**
+ *
+ * @author TheElk801
+ */
+public final class EnchantedCarriage extends CardImpl {
+
+ public EnchantedCarriage(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
+
+ this.subtype.add(SubType.VEHICLE);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(4);
+
+ // When Enchanted Carriage enters the battlefield, create two 1/1 white Mouse creature tokens.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new MouseToken(),2)));
+
+ // Crew 2
+ this.addAbility(new CrewAbility(2));
+ }
+
+ private EnchantedCarriage(final EnchantedCarriage card) {
+ super(card);
+ }
+
+ @Override
+ public EnchantedCarriage copy() {
+ return new EnchantedCarriage(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/EndbringersRevel.java b/Mage.Sets/src/mage/cards/e/EndbringersRevel.java
index 6e2648f83b2..64385264357 100644
--- a/Mage.Sets/src/mage/cards/e/EndbringersRevel.java
+++ b/Mage.Sets/src/mage/cards/e/EndbringersRevel.java
@@ -24,7 +24,7 @@ public final class EndbringersRevel extends CardImpl {
public EndbringersRevel(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}");
- // {4}: Return target creature card from a graveyard to its owner's hand. Any player may activate this ability but only any time he or she could cast a sorcery.
+ // {4}: Return target creature card from a graveyard to its owner's hand. Any player may activate this ability but only any time they could cast a sorcery.
ActivateAsSorceryActivatedAbility ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new ManaCostsImpl("{4}"));
ability.addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard")));
ability.setMayActivate(TargetController.ANY);
diff --git a/Mage.Sets/src/mage/cards/e/EnduringIdeal.java b/Mage.Sets/src/mage/cards/e/EnduringIdeal.java
index 29b2856c176..552f32613b3 100644
--- a/Mage.Sets/src/mage/cards/e/EnduringIdeal.java
+++ b/Mage.Sets/src/mage/cards/e/EnduringIdeal.java
@@ -1,4 +1,3 @@
-
package mage.cards.e;
import java.util.UUID;
@@ -11,8 +10,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.FilterCard;
-import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
@@ -25,7 +23,7 @@ import mage.target.common.TargetCardInLibrary;
public final class EnduringIdeal extends CardImpl {
public EnduringIdeal(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{W}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{W}{W}");
// Search your library for an enchantment card and put it onto the battlefield. Then shuffle your library.
this.getSpellAbility().addEffect(new EnduringIdealEffect());
@@ -47,12 +45,6 @@ public final class EnduringIdeal extends CardImpl {
class EnduringIdealEffect extends OneShotEffect {
- private static final FilterCard filter = new FilterCard();
-
- static {
- filter.add(new CardTypePredicate(CardType.ENCHANTMENT));
- }
-
public EnduringIdealEffect() {
super(Outcome.Benefit);
staticText = "Search your library for an enchantment card and put it onto the battlefield. Then shuffle your library";
@@ -67,7 +59,7 @@ class EnduringIdealEffect extends OneShotEffect {
boolean applied = false;
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- TargetCardInLibrary target = new TargetCardInLibrary(filter);
+ TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_ENTCHANTMENT);
controller.searchLibrary(target, source, game);
Card targetCard = game.getCard(target.getFirstTarget());
if (targetCard == null) {
diff --git a/Mage.Sets/src/mage/cards/e/EnergyField.java b/Mage.Sets/src/mage/cards/e/EnergyField.java
index 21c02de9dbb..1b5fb3d65cf 100644
--- a/Mage.Sets/src/mage/cards/e/EnergyField.java
+++ b/Mage.Sets/src/mage/cards/e/EnergyField.java
@@ -1,8 +1,5 @@
-
package mage.cards.e;
-import java.util.Objects;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.PutCardIntoGraveFromAnywhereAllTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@@ -15,7 +12,12 @@ import mage.constants.Duration;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
+
+import java.util.Objects;
+import java.util.UUID;
/**
* @author Plopman
@@ -57,7 +59,7 @@ class EnergyFieldEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
event.setAmount(0);
diff --git a/Mage.Sets/src/mage/cards/e/EnergyVortex.java b/Mage.Sets/src/mage/cards/e/EnergyVortex.java
index a8667f2a62b..620bd4f6e92 100644
--- a/Mage.Sets/src/mage/cards/e/EnergyVortex.java
+++ b/Mage.Sets/src/mage/cards/e/EnergyVortex.java
@@ -41,7 +41,7 @@ public final class EnergyVortex extends CardImpl {
new RemoveAllCountersSourceEffect(CounterType.VORTEX), TargetController.YOU, false
));
- // At the beginning of the chosen player's upkeep, Energy Vortex deals 3 damage to that player unless he or she pays {1} for each vortex counter on Energy Vortex.
+ // At the beginning of the chosen player's upkeep, Energy Vortex deals 3 damage to that player unless they pay {1} for each vortex counter on Energy Vortex.
this.addAbility(new ConditionalTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility(
new EnergyVortexEffect(), TargetController.ANY, false
diff --git a/Mage.Sets/src/mage/cards/e/Enlarge.java b/Mage.Sets/src/mage/cards/e/Enlarge.java
index 73349d3edad..0e8a887a21c 100644
--- a/Mage.Sets/src/mage/cards/e/Enlarge.java
+++ b/Mage.Sets/src/mage/cards/e/Enlarge.java
@@ -2,6 +2,7 @@
package mage.cards.e;
import java.util.UUID;
+import mage.abilities.effects.Effect;
import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneTargetEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
@@ -25,7 +26,9 @@ public final class Enlarge extends CardImpl {
// Target creature gets +7/+7 and gains trample until end of turn. It must be blocked this turn if able.
this.getSpellAbility().addEffect(new BoostTargetEffect(7,7, Duration.EndOfTurn));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn));
- this.getSpellAbility().addEffect(new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn));
+ Effect effect = new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn);
+ effect.setText("It must be blocked this turn if able");
+ this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
diff --git a/Mage.Sets/src/mage/cards/e/EnshrinedMemories.java b/Mage.Sets/src/mage/cards/e/EnshrinedMemories.java
index 9dbaf7728b2..5a34b58033f 100644
--- a/Mage.Sets/src/mage/cards/e/EnshrinedMemories.java
+++ b/Mage.Sets/src/mage/cards/e/EnshrinedMemories.java
@@ -1,4 +1,3 @@
-
package mage.cards.e;
import java.util.UUID;
@@ -8,7 +7,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -20,7 +19,7 @@ public final class EnshrinedMemories extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{G}");
// Reveal the top X cards of your library. Put all creature cards revealed this way into your hand and the rest on the bottom of your library in any order.
- this.getSpellAbility().addEffect(new RevealLibraryPutIntoHandEffect(ManacostVariableValue.instance, new FilterCreatureCard(), Zone.LIBRARY, true));
+ this.getSpellAbility().addEffect(new RevealLibraryPutIntoHandEffect(ManacostVariableValue.instance, StaticFilters.FILTER_CARD_CREATURE, Zone.LIBRARY, true));
}
public EnshrinedMemories(final EnshrinedMemories card) {
diff --git a/Mage.Sets/src/mage/cards/e/EnsnaringBridge.java b/Mage.Sets/src/mage/cards/e/EnsnaringBridge.java
index eb322322668..dfac1b9ca35 100644
--- a/Mage.Sets/src/mage/cards/e/EnsnaringBridge.java
+++ b/Mage.Sets/src/mage/cards/e/EnsnaringBridge.java
@@ -53,7 +53,7 @@ class EnsnaringBridgeRestrictionEffect extends RestrictionEffect {
if (controller == null) {
return false;
}
- return controller.getInRange().contains(permanent.getControllerId())
+ return game.getState().getPlayersInRange(controller.getId(), game).contains(permanent.getControllerId())
&& permanent.getPower().getValue() > controller.getHand().size();
}
diff --git a/Mage.Sets/src/mage/cards/e/EntomberExarch.java b/Mage.Sets/src/mage/cards/e/EntomberExarch.java
index 839aaf8fe7d..f424b55ff6c 100644
--- a/Mage.Sets/src/mage/cards/e/EntomberExarch.java
+++ b/Mage.Sets/src/mage/cards/e/EntomberExarch.java
@@ -14,10 +14,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.FilterCard;
import mage.filter.StaticFilters;
-import mage.filter.predicate.Predicates;
-import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
@@ -60,12 +57,6 @@ public final class EntomberExarch extends CardImpl {
class EntomberExarchEffect extends OneShotEffect {
- private static final FilterCard filter = new FilterCard("noncreature card");
-
- static {
- filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
- }
-
EntomberExarchEffect() {
super(Outcome.Discard);
staticText = "target opponent reveals their hand, you choose a noncreature card from it, then that player discards that card";
@@ -82,7 +73,7 @@ class EntomberExarchEffect extends OneShotEffect {
player.revealCards("Entomber Exarch", player.getHand(), game);
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
- TargetCard target = new TargetCard(Zone.HAND, filter);
+ TargetCard target = new TargetCard(Zone.HAND, StaticFilters.FILTER_CARD_A_NON_CREATURE);
if (you.choose(Outcome.Benefit, player.getHand(), target, game)) {
Card card = player.getHand().get(target.getFirstTarget(), game);
return player.discard(card, source, game);
diff --git a/Mage.Sets/src/mage/cards/e/EpharaGodOfThePolis.java b/Mage.Sets/src/mage/cards/e/EpharaGodOfThePolis.java
index c3ae62a97ad..ad727a0038b 100644
--- a/Mage.Sets/src/mage/cards/e/EpharaGodOfThePolis.java
+++ b/Mage.Sets/src/mage/cards/e/EpharaGodOfThePolis.java
@@ -1,7 +1,5 @@
-
package mage.cards.e;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
@@ -9,7 +7,6 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.dynamicvalue.common.DevotionCount;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
import mage.abilities.keyword.IndestructibleAbility;
@@ -20,8 +17,9 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.watchers.common.PermanentsEnteredBattlefieldWatcher;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class EpharaGodOfThePolis extends CardImpl {
@@ -38,20 +36,20 @@ public final class EpharaGodOfThePolis extends CardImpl {
this.addAbility(IndestructibleAbility.getInstance());
// As long as your devotion to white and blue is less than seven, Ephara isn't a creature.
- Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.W, ColoredManaSymbol.U), 7);
- effect.setText("As long as your devotion to white and blue is less than seven, Ephara isn't a creature");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.WU, 7))
+ .addHint(DevotionCount.WU.getHint()));
// At the beginning of each upkeep, if you had another creature enter the battlefield under your control last turn, draw a card.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
- new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), TargetController.ANY, false, false),
- HadAnotherCreatureEnterTheBattlefieldCondition.instance,
- "At the beginning of each upkeep, if you had another creature enter the battlefield under your control last turn, draw a card."),
- new PermanentsEnteredBattlefieldWatcher());
-
+ new BeginningOfUpkeepTriggeredAbility(
+ Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1),
+ TargetController.ANY, false, false
+ ), EpharaGodOfThePolisCondition.instance, "At the beginning of each upkeep, " +
+ "if you had another creature enter the battlefield under your control last turn, draw a card."
+ ), new PermanentsEnteredBattlefieldWatcher());
}
- public EpharaGodOfThePolis(final EpharaGodOfThePolis card) {
+ private EpharaGodOfThePolis(final EpharaGodOfThePolis card) {
super(card);
}
@@ -61,12 +59,10 @@ public final class EpharaGodOfThePolis extends CardImpl {
}
}
-enum HadAnotherCreatureEnterTheBattlefieldCondition implements Condition {
+enum EpharaGodOfThePolisCondition implements Condition {
instance;
-
-
@Override
public boolean apply(Game game, Ability source) {
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
diff --git a/Mage.Sets/src/mage/cards/e/EpicDownfall.java b/Mage.Sets/src/mage/cards/e/EpicDownfall.java
new file mode 100644
index 00000000000..79e307b008b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EpicDownfall.java
@@ -0,0 +1,43 @@
+package mage.cards.e;
+
+import mage.abilities.effects.common.ExileTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class EpicDownfall extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterCreaturePermanent("creature with converted mana cost 3 or greater");
+
+ static {
+ filter.add(new ConvertedManaCostPredicate(ComparisonType.MORE_THAN, 2));
+ }
+
+ public EpicDownfall(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}");
+
+ // Exile target creature with converted mana cost 3 or greater.
+ this.getSpellAbility().addEffect(new ExileTargetEffect());
+ this.getSpellAbility().addTarget(new TargetPermanent(filter));
+ }
+
+ private EpicDownfall(final EpicDownfall card) {
+ super(card);
+ }
+
+ @Override
+ public EpicDownfall copy() {
+ return new EpicDownfall(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/EpicExperiment.java b/Mage.Sets/src/mage/cards/e/EpicExperiment.java
index ed85156345d..eb650b82dd2 100644
--- a/Mage.Sets/src/mage/cards/e/EpicExperiment.java
+++ b/Mage.Sets/src/mage/cards/e/EpicExperiment.java
@@ -1,4 +1,3 @@
-
package mage.cards.e;
import java.util.UUID;
@@ -48,7 +47,10 @@ class EpicExperimentEffect extends OneShotEffect {
public EpicExperimentEffect() {
super(Outcome.PlayForFree);
- staticText = "Exile the top X cards of your library. For each instant and sorcery card with converted mana cost X or less among them, you may cast that card without paying its mana cost. Then put all cards exiled this way that weren't cast into your graveyard";
+ staticText = "Exile the top X cards of your library. For each instant and "
+ + "sorcery card with converted mana cost X or less among them, "
+ + "you may cast that card without paying its mana cost. Then put all "
+ + "cards exiled this way that weren't cast into your graveyard";
}
public EpicExperimentEffect(final EpicExperimentEffect effect) {
@@ -61,27 +63,39 @@ class EpicExperimentEffect extends OneShotEffect {
MageObject sourceObject = source.getSourceObject(game);
if (controller != null && sourceObject != null) {
// move cards from library to exile
- controller.moveCardsToExile(controller.getLibrary().getTopCards(game, source.getManaCostsToPay().getX()), source, game, true, source.getSourceId(), sourceObject.getIdName());
+ controller.moveCardsToExile(controller.getLibrary().getTopCards(game,
+ source.getManaCostsToPay().getX()), source, game, true,
+ source.getSourceId(), sourceObject.getIdName());
// cast the possible cards without paying the mana
ExileZone epicExperimentExileZone = game.getExile().getExileZone(source.getSourceId());
FilterCard filter = new FilterInstantOrSorceryCard();
- filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, source.getManaCostsToPay().getX() + 1));
- filter.setMessage("instant and sorcery cards with converted mana cost " + source.getManaCostsToPay().getX() + " or less");
+ filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN,
+ source.getManaCostsToPay().getX() + 1));
+ filter.setMessage("instant and sorcery cards with converted mana cost "
+ + source.getManaCostsToPay().getX() + " or less");
Cards cardsToCast = new CardsImpl();
if (epicExperimentExileZone == null) {
return true;
}
- cardsToCast.addAll(epicExperimentExileZone.getCards(filter, source.getSourceId(), source.getControllerId(), game));
+ cardsToCast.addAll(epicExperimentExileZone.getCards(filter, source.getSourceId(),
+ source.getControllerId(), game));
while (!cardsToCast.isEmpty()) {
- if (!controller.chooseUse(Outcome.PlayForFree, "Cast (another) a card exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
+ if (!controller.chooseUse(Outcome.PlayForFree, "Cast (another) a card exiled with "
+ + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
break;
}
- TargetCard targetCard = new TargetCard(1, Zone.EXILED, new FilterCard("instant or sorcery card to cast for free"));
+ TargetCard targetCard = new TargetCard(1, Zone.EXILED, new FilterCard(
+ "instant or sorcery card to cast for free"));
if (controller.choose(Outcome.PlayForFree, cardsToCast, targetCard, game)) {
Card card = game.getCard(targetCard.getFirstTarget());
if (card != null) {
- if (!controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
- game.informPlayer(controller, "You're not able to cast " + card.getIdName() + " or you canceled the casting.");
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (!cardWasCast) {
+ game.informPlayer(controller, "You're not able to cast "
+ + card.getIdName() + " or you canceled the casting.");
}
cardsToCast.remove(card);
} else {
@@ -98,6 +112,7 @@ class EpicExperimentEffect extends OneShotEffect {
}
return true;
}
+
return false;
}
diff --git a/Mage.Sets/src/mage/cards/e/Epicenter.java b/Mage.Sets/src/mage/cards/e/Epicenter.java
index aa54475f9d5..2ad129e43ec 100644
--- a/Mage.Sets/src/mage/cards/e/Epicenter.java
+++ b/Mage.Sets/src/mage/cards/e/Epicenter.java
@@ -33,7 +33,7 @@ public final class Epicenter extends CardImpl {
new InvertCondition(new CardsInControllerGraveCondition(7)),
"Target player sacrifices a land"
));
- // Threshold - Each player sacrifices all lands he or she controls instead if seven or more cards are in your graveyard.
+ // Threshold - Each player sacrifices all lands they control instead if seven or more cards are in your graveyard.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new EpicenterEffect(),
new CardsInControllerGraveCondition(7),
diff --git a/Mage.Sets/src/mage/cards/e/Equipoise.java b/Mage.Sets/src/mage/cards/e/Equipoise.java
index bf06fbfd073..08163dde815 100644
--- a/Mage.Sets/src/mage/cards/e/Equipoise.java
+++ b/Mage.Sets/src/mage/cards/e/Equipoise.java
@@ -32,7 +32,7 @@ public final class Equipoise extends CardImpl {
public Equipoise(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
- // At the beginning of your upkeep, for each land target player controls in excess of the number you control, choose a land he or she controls, then the chosen permanents phase out. Repeat this process for artifacts and creatures.
+ // At the beginning of your upkeep, for each land target player controls in excess of the number you control, choose a land they control, then the chosen permanents phase out. Repeat this process for artifacts and creatures.
Ability ability = new BeginningOfUpkeepTriggeredAbility(new EquipoiseEffect(), TargetController.YOU, false);
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
@@ -52,7 +52,7 @@ class EquipoiseEffect extends OneShotEffect {
public EquipoiseEffect() {
super(Outcome.Benefit);
- this.staticText = "for each land target player controls in excess of the number you control, choose a land he or she controls, then the chosen permanents phase out. Repeat this process for artifacts and creatures";
+ this.staticText = "for each land target player controls in excess of the number you control, choose a land they control, then the chosen permanents phase out. Repeat this process for artifacts and creatures";
}
public EquipoiseEffect(final EquipoiseEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/e/ErebosBleakHearted.java b/Mage.Sets/src/mage/cards/e/ErebosBleakHearted.java
new file mode 100644
index 00000000000..2fe671c3a04
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/ErebosBleakHearted.java
@@ -0,0 +1,72 @@
+package mage.cards.e;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.DiesCreatureTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.PayLifeCost;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.dynamicvalue.common.DevotionCount;
+import mage.abilities.effects.common.DoIfCostPaid;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
+import mage.abilities.keyword.IndestructibleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.filter.StaticFilters;
+import mage.target.common.TargetControlledPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ErebosBleakHearted extends CardImpl {
+
+ public ErebosBleakHearted(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{3}{B}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.GOD);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(6);
+
+ // Indestructible
+ this.addAbility(IndestructibleAbility.getInstance());
+
+ // As long as your devotion to black is less than five, Erebos isn't a creature.
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.B, 5))
+ .addHint(DevotionCount.B.getHint()));
+
+ // Whenever another creature you control dies, you may pay 2 life. If you do, draw a card.
+ this.addAbility(new DiesCreatureTriggeredAbility(new DoIfCostPaid(
+ new DrawCardSourceControllerEffect(1), new PayLifeCost(2)
+ ), false, true));
+
+ // {1}{B}, Sacrifice another creature: Target creature gets -2/-1 until end of turn.
+ Ability ability = new SimpleActivatedAbility(
+ new BoostTargetEffect(-2, -1), new ManaCostsImpl("{1}{B}")
+ );
+ ability.addCost(new SacrificeTargetCost(
+ new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)
+ ));
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+ }
+
+ private ErebosBleakHearted(final ErebosBleakHearted card) {
+ super(card);
+ }
+
+ @Override
+ public ErebosBleakHearted copy() {
+ return new ErebosBleakHearted(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/ErebosGodOfTheDead.java b/Mage.Sets/src/mage/cards/e/ErebosGodOfTheDead.java
index 3d8470a02b0..dde3940d613 100644
--- a/Mage.Sets/src/mage/cards/e/ErebosGodOfTheDead.java
+++ b/Mage.Sets/src/mage/cards/e/ErebosGodOfTheDead.java
@@ -1,7 +1,5 @@
-
package mage.cards.e;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -9,7 +7,6 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.PayLifeCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.DevotionCount;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.CantGainLifeAllEffect;
import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
@@ -18,8 +15,9 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class ErebosGodOfTheDead extends CardImpl {
@@ -36,27 +34,24 @@ public final class ErebosGodOfTheDead extends CardImpl {
this.addAbility(IndestructibleAbility.getInstance());
// As long as your devotion to black is less than five, Erebos isn't a creature.
- Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.B), 5);
- effect.setText("As long as your devotion to black is less than five, Erebos isn't a creature.(Each {B} in the mana costs of permanents you control counts towards your devotion to black.)");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.B, 5))
+ .addHint(DevotionCount.B.getHint()));
// Your opponents can't gain life.
this.addAbility(new SimpleStaticAbility(
- Zone.BATTLEFIELD,
- new CantGainLifeAllEffect(
- Duration.WhileOnBattlefield,
- TargetController.OPPONENT
- )
+ new CantGainLifeAllEffect(Duration.WhileOnBattlefield, TargetController.OPPONENT)
));
// {1}{B}, Pay 2 life: Draw a card.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{1}{B}"));
+ Ability ability = new SimpleActivatedAbility(
+ new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{1}{B}")
+ );
ability.addCost(new PayLifeCost(2));
this.addAbility(ability);
}
- public ErebosGodOfTheDead(final ErebosGodOfTheDead card) {
+ private ErebosGodOfTheDead(final ErebosGodOfTheDead card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/e/ErebossEmissary.java b/Mage.Sets/src/mage/cards/e/ErebossEmissary.java
index 2684d3a91b0..9b5fb1ffe5e 100644
--- a/Mage.Sets/src/mage/cards/e/ErebossEmissary.java
+++ b/Mage.Sets/src/mage/cards/e/ErebossEmissary.java
@@ -1,4 +1,3 @@
-
package mage.cards.e;
import java.util.UUID;
@@ -17,7 +16,7 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCardInHand;
/**
@@ -27,7 +26,7 @@ import mage.target.common.TargetCardInHand;
public final class ErebossEmissary extends CardImpl {
public ErebossEmissary(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{3}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{3}{B}");
this.subtype.add(SubType.SNAKE);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
@@ -41,7 +40,7 @@ public final class ErebossEmissary extends CardImpl {
new BoostSourceEffect(2, 2, Duration.EndOfTurn),
new SourceHasSubtypeCondition(SubType.AURA),
"{this} gets +2/+2 until end of turn. If Erebos's Emissary is an Aura, enchanted creature gets +2/+2 until end of turn instead"),
- new DiscardTargetCost(new TargetCardInHand(new FilterCreatureCard()))));
+ new DiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE))));
// Enchanted creature gets +3/+3
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield)));
diff --git a/Mage.Sets/src/mage/cards/e/EscapeToTheWilds.java b/Mage.Sets/src/mage/cards/e/EscapeToTheWilds.java
new file mode 100644
index 00000000000..0c36bdd0972
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EscapeToTheWilds.java
@@ -0,0 +1,119 @@
+package mage.cards.e;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.AsThoughEffectImpl;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.PlayAdditionalLandsControllerEffect;
+import mage.cards.*;
+import mage.constants.*;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.targetpointer.FixedTarget;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class EscapeToTheWilds extends CardImpl {
+
+ public EscapeToTheWilds(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}{G}");
+
+ // Exile the top five cards of your library. You may play cards exiled this way until the end of your next turn.
+ // You may play an additional land this turn.
+ this.getSpellAbility().addEffect(new EscapeToTheWildsEffect());
+ }
+
+ private EscapeToTheWilds(final EscapeToTheWilds card) {
+ super(card);
+ }
+
+ @Override
+ public EscapeToTheWilds copy() {
+ return new EscapeToTheWilds(this);
+ }
+}
+
+class EscapeToTheWildsEffect extends OneShotEffect {
+
+ EscapeToTheWildsEffect() {
+ super(Outcome.PlayForFree);
+ this.staticText = "Exile the top five cards of your library. " +
+ "You may play cards exiled this way until the end of your next turn.
" +
+ "You may play an additional land this turn.";
+ }
+
+ private EscapeToTheWildsEffect(final EscapeToTheWildsEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public EscapeToTheWildsEffect copy() {
+ return new EscapeToTheWildsEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) {
+ return false;
+ }
+ Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
+ Card sourceCard = game.getCard(source.getSourceId());
+ controller.moveCards(cards, Zone.EXILED, source, game);
+
+ cards.getCards(game).stream().forEach(card -> {
+ ContinuousEffect effect = new EscapeToTheWildsMayPlayEffect();
+ effect.setTargetPointer(new FixedTarget(card.getId()));
+ game.addEffect(effect, source);
+ });
+ game.addEffect(new PlayAdditionalLandsControllerEffect(1, Duration.EndOfTurn), source);
+ return true;
+ }
+}
+
+class EscapeToTheWildsMayPlayEffect extends AsThoughEffectImpl {
+
+ private int castOnTurn = 0;
+
+ EscapeToTheWildsMayPlayEffect() {
+ super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit);
+ this.staticText = "Until the end of your next turn, you may play that card.";
+ }
+
+ private EscapeToTheWildsMayPlayEffect(final EscapeToTheWildsMayPlayEffect effect) {
+ super(effect);
+ castOnTurn = effect.castOnTurn;
+ }
+
+ @Override
+ public EscapeToTheWildsMayPlayEffect copy() {
+ return new EscapeToTheWildsMayPlayEffect(this);
+ }
+
+ @Override
+ public void init(Ability source, Game game) {
+ super.init(source, game);
+ castOnTurn = game.getTurnNum();
+ }
+
+ @Override
+ public boolean isInactive(Ability source, Game game) {
+ return castOnTurn != game.getTurnNum()
+ && game.getPhase().getStep().getType() == PhaseStep.END_TURN
+ && game.isActivePlayer(source.getControllerId());
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
+ return source.isControlledBy(affectedControllerId)
+ && getTargetPointer().getTargets(game, source).contains(sourceId);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/e/EscapedShapeshifter.java b/Mage.Sets/src/mage/cards/e/EscapedShapeshifter.java
new file mode 100644
index 00000000000..935988818fc
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EscapedShapeshifter.java
@@ -0,0 +1,100 @@
+package mage.cards.e;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ContinuousEffectImpl;
+import mage.abilities.keyword.FirstStrikeAbility;
+import mage.abilities.keyword.FlyingAbility;
+import mage.abilities.keyword.ProtectionAbility;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.StaticFilters;
+import mage.filter.predicate.mageobject.ColorPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class EscapedShapeshifter extends CardImpl {
+
+ public EscapedShapeshifter(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
+
+ this.subtype.add(SubType.SHAPESHIFTER);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(4);
+
+ // As long as an opponent controls a creature with flying not named Escaped Shapeshifter, Escaped Shapeshifter has flying. The same is true for first strike, trample, and protection from any color.
+ this.addAbility(new SimpleStaticAbility(new EscapedShapeshifterEffect()));
+ }
+
+ private EscapedShapeshifter(final EscapedShapeshifter card) {
+ super(card);
+ }
+
+ @Override
+ public EscapedShapeshifter copy() {
+ return new EscapedShapeshifter(this);
+ }
+}
+
+class EscapedShapeshifterEffect extends ContinuousEffectImpl {
+
+ EscapedShapeshifterEffect() {
+ super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
+ this.addDependedToType(DependencyType.AddingAbility);
+ staticText = "As long as an opponent controls a creature with flying not named Escaped Shapeshifter, " +
+ "{this} has flying. The same is true for first strike, trample, and protection from any color.";
+ }
+
+ private EscapedShapeshifterEffect(final EscapedShapeshifterEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent sourcePermanent = game.getPermanent(source.getSourceId());
+ if (sourcePermanent == null) {
+ return false;
+ }
+
+ game.getBattlefield()
+ .getActivePermanents(
+ StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE,
+ source.getControllerId(), source.getSourceId(), game
+ ).stream()
+ .filter(Objects::nonNull)
+ .filter(permanent -> !permanent.getName().equals("Escaped Shapeshifter"))
+ .map(Permanent::getAbilities)
+ .flatMap(Collection::stream).filter(EscapedShapeshifterEffect::checkAbility)
+ .forEach(ability -> sourcePermanent.addAbility(ability, source.getSourceId(), game));
+ return true;
+ }
+
+ private static boolean checkAbility(Ability ability) {
+ if (ability instanceof FlyingAbility
+ || ability instanceof FirstStrikeAbility
+ || ability instanceof TrampleAbility) {
+ return true;
+ }
+ return ability instanceof ProtectionAbility
+ && ((ProtectionAbility) ability)
+ .getFilter()
+ .getPredicates()
+ .stream()
+ .anyMatch(ColorPredicate.class::isInstance);
+ }
+
+ @Override
+ public EscapedShapeshifterEffect copy() {
+ return new EscapedShapeshifterEffect(this);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/e/EssenceVortex.java b/Mage.Sets/src/mage/cards/e/EssenceVortex.java
new file mode 100644
index 00000000000..72256d73941
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EssenceVortex.java
@@ -0,0 +1,69 @@
+package mage.cards.e;
+
+import mage.abilities.Ability;
+import mage.abilities.costs.Cost;
+import mage.abilities.costs.common.PayLifeCost;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class EssenceVortex extends CardImpl {
+
+ public EssenceVortex(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}{B}");
+
+ // Destroy target creature unless its controller pays life equal to its toughness. A creature destroyed this way can't be regenerated.
+ this.getSpellAbility().addEffect(new EssenceVortexEffect());
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent());
+ }
+
+ private EssenceVortex(final EssenceVortex card) {
+ super(card);
+ }
+
+ @Override
+ public EssenceVortex copy() {
+ return new EssenceVortex(this);
+ }
+}
+
+class EssenceVortexEffect extends OneShotEffect {
+
+ EssenceVortexEffect() {
+ super(Outcome.Benefit);
+ staticText = "Destroy target creature unless its controller pays life equal to its toughness. " +
+ "A creature destroyed this way can't be regenerated.";
+ }
+
+ private EssenceVortexEffect(final EssenceVortexEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public EssenceVortexEffect copy() {
+ return new EssenceVortexEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = game.getPermanent(source.getFirstTarget());
+ if (permanent == null) {
+ return false;
+ }
+ Cost cost = new PayLifeCost(permanent.getToughness().getValue());
+ if (cost.pay(source, game, source.getSourceId(), permanent.getControllerId(), true)) {
+ return true;
+ }
+ return permanent.destroy(source.getSourceId(), game, true);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/e/EtaliPrimalStorm.java b/Mage.Sets/src/mage/cards/e/EtaliPrimalStorm.java
index 8e1f289874c..f75fb918ce1 100644
--- a/Mage.Sets/src/mage/cards/e/EtaliPrimalStorm.java
+++ b/Mage.Sets/src/mage/cards/e/EtaliPrimalStorm.java
@@ -1,4 +1,3 @@
-
package mage.cards.e;
import java.util.HashSet;
@@ -21,6 +20,7 @@ import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterCard;
+import mage.filter.common.FilterNonlandCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
@@ -41,7 +41,8 @@ public final class EtaliPrimalStorm extends CardImpl {
this.power = new MageInt(6);
this.toughness = new MageInt(6);
- // Whenever Etali, Primal Storm attacks, exile the top card of each player's library, then you may cast any number of nonland cards exiled this way without paying their mana costs.
+ // Whenever Etali, Primal Storm attacks, exile the top card of each player's library,
+ // then you may cast any number of nonland cards exiled this way without paying their mana costs.
this.addAbility(new AttacksTriggeredAbility(new EtaliPrimalStormEffect(), false));
}
@@ -58,15 +59,12 @@ public final class EtaliPrimalStorm extends CardImpl {
class EtaliPrimalStormEffect extends OneShotEffect {
- private static final FilterCard filter = new FilterCard("nonland cards");
-
- static {
- filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
- }
+ private static final FilterNonlandCard filter = new FilterNonlandCard("nonland cards");
public EtaliPrimalStormEffect() {
- super(Outcome.Benefit);
- this.staticText = "exile the top card of each player's library, then you may cast any number of nonland cards exiled this way without paying their mana costs";
+ super(Outcome.PlayForFree);
+ this.staticText = "exile the top card of each player's library, then you may cast "
+ + "any number of nonland cards exiled this way without paying their mana costs";
}
public EtaliPrimalStormEffect(final EtaliPrimalStormEffect effect) {
@@ -82,7 +80,8 @@ class EtaliPrimalStormEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
- if (controller != null && sourceObject != null) {
+ if (controller != null
+ && sourceObject != null) {
// move cards from library to exile
Set currentExiledCards = new HashSet<>();
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
@@ -103,7 +102,9 @@ class EtaliPrimalStormEffect extends OneShotEffect {
cardsToCast.addAll(currentExiledCards);
boolean alreadyCast = false;
while (!cardsToCast.isEmpty()) {
- if (!controller.chooseUse(Outcome.PlayForFree, "Cast a" + (alreadyCast ? "nother" : "") + " card exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
+ if (!controller.chooseUse(Outcome.PlayForFree, "Cast a"
+ + (alreadyCast ? "nother" : "") + " card exiled with "
+ + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
break;
}
@@ -115,10 +116,13 @@ class EtaliPrimalStormEffect extends OneShotEffect {
alreadyCast = true;
Card card = game.getCard(targetCard.getFirstTarget());
if (card != null) {
- if (!controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
- if (!game.isSimulation()) {
- game.informPlayer(controller, "You're not able to cast " + card.getIdName() + " or you canceled the casting.");
- }
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (!cardWasCast) {
+ game.informPlayer(controller, "You're not able to cast "
+ + card.getIdName() + " or you canceled the casting.");
}
cardsToCast.remove(card);
}
diff --git a/Mage.Sets/src/mage/cards/e/EunuchsIntrigues.java b/Mage.Sets/src/mage/cards/e/EunuchsIntrigues.java
index 2422e5e1bfa..bb021d44efc 100644
--- a/Mage.Sets/src/mage/cards/e/EunuchsIntrigues.java
+++ b/Mage.Sets/src/mage/cards/e/EunuchsIntrigues.java
@@ -27,7 +27,7 @@ public final class EunuchsIntrigues extends CardImpl {
public EunuchsIntrigues(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}");
- // Target opponent chooses a creature he or she controls. Other creatures he or she controls can't block this turn.
+ // Target opponent chooses a creature they control. Other creatures they control can't block this turn.
this.getSpellAbility().addEffect(new EunuchsIntriguesEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
}
@@ -46,7 +46,7 @@ class EunuchsIntriguesEffect extends OneShotEffect {
EunuchsIntriguesEffect() {
super(Outcome.Benefit);
- this.staticText = "Target opponent chooses a creature he or she controls. Other creatures he or she controls can't block this turn.";
+ this.staticText = "Target opponent chooses a creature they control. Other creatures they control can't block this turn.";
}
EunuchsIntriguesEffect(final EunuchsIntriguesEffect effect) {
@@ -73,7 +73,7 @@ class EunuchsIntriguesEffect extends OneShotEffect {
}
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
- game.informPlayers(player.getLogName() + " has chosen " + permanent.getLogName() + " as his only creature able to block this turn");
+ game.informPlayers(player.getLogName() + " has chosen " + permanent.getLogName() + " as their only creature able to block this turn");
}
}
game.addEffect(new EunuchsIntriguesRestrictionEffect(target.getFirstTarget()), source);
diff --git a/Mage.Sets/src/mage/cards/e/EvangelOfHeliod.java b/Mage.Sets/src/mage/cards/e/EvangelOfHeliod.java
index 19237faccce..008265216f5 100644
--- a/Mage.Sets/src/mage/cards/e/EvangelOfHeliod.java
+++ b/Mage.Sets/src/mage/cards/e/EvangelOfHeliod.java
@@ -1,7 +1,5 @@
-
package mage.cards.e;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.common.DevotionCount;
@@ -10,17 +8,17 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.ColoredManaSymbol;
import mage.game.permanent.token.SoldierToken;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class EvangelOfHeliod extends CardImpl {
public EvangelOfHeliod(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{W}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.CLERIC);
@@ -28,10 +26,12 @@ public final class EvangelOfHeliod extends CardImpl {
this.toughness = new MageInt(3);
// When Evangel of Heliod enters the battlefield, create a number of 1/1 white Soldier creature tokens equal to your devotion to white.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new SoldierToken(), new DevotionCount(ColoredManaSymbol.W))));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(
+ new CreateTokenEffect(new SoldierToken(), DevotionCount.W)
+ ).addHint(DevotionCount.W.getHint()));
}
- public EvangelOfHeliod(final EvangelOfHeliod card) {
+ private EvangelOfHeliod(final EvangelOfHeliod card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/e/Evangelize.java b/Mage.Sets/src/mage/cards/e/Evangelize.java
index 433194b0353..ce1f0dff68f 100644
--- a/Mage.Sets/src/mage/cards/e/Evangelize.java
+++ b/Mage.Sets/src/mage/cards/e/Evangelize.java
@@ -25,9 +25,9 @@ public final class Evangelize extends CardImpl {
// Buyback {2}{W}{W}
this.addAbility(new BuybackAbility("{2}{W}{W}"));
- // Gain control of target creature of an opponent's choice that he or she controls.
+ // Gain control of target creature of an opponent's choice that they control.
GainControlTargetEffect effect = new GainControlTargetEffect(Duration.EndOfGame);
- effect.setText("Gain control of target creature of an opponent's choice he or she controls");
+ effect.setText("Gain control of target creature of an opponent's choice they control");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetOpponentsChoicePermanent(1, 1, filter, false, true));
}
diff --git a/Mage.Sets/src/mage/cards/e/EvolutionaryLeap.java b/Mage.Sets/src/mage/cards/e/EvolutionaryLeap.java
index 38e0090f8f6..8e28963273e 100644
--- a/Mage.Sets/src/mage/cards/e/EvolutionaryLeap.java
+++ b/Mage.Sets/src/mage/cards/e/EvolutionaryLeap.java
@@ -1,4 +1,3 @@
-
package mage.cards.e;
import java.util.UUID;
@@ -11,8 +10,8 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
+import mage.filter.StaticFilters;
import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
-import mage.filter.common.FilterCreatureCard;
import mage.target.common.TargetControlledCreaturePermanent;
/**
@@ -25,7 +24,7 @@ public final class EvolutionaryLeap extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
// {G}, Sacrifice a creature: Reveal cards from the top of your library until you reveal a creature card. Put that card into your hand and the rest on the bottom of your library in a random order.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RevealCardsFromLibraryUntilEffect(new FilterCreatureCard(), Zone.HAND, Zone.LIBRARY), new ManaCostsImpl("{G}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RevealCardsFromLibraryUntilEffect(StaticFilters.FILTER_CARD_CREATURE, Zone.HAND, Zone.LIBRARY), new ManaCostsImpl("{G}"));
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/e/ExoskeletalArmor.java b/Mage.Sets/src/mage/cards/e/ExoskeletalArmor.java
index 34ac37bfd0b..69b52a0c911 100644
--- a/Mage.Sets/src/mage/cards/e/ExoskeletalArmor.java
+++ b/Mage.Sets/src/mage/cards/e/ExoskeletalArmor.java
@@ -1,4 +1,3 @@
-
package mage.cards.e;
import java.util.UUID;
@@ -12,11 +11,11 @@ import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
@@ -27,7 +26,7 @@ import mage.target.common.TargetCreaturePermanent;
public final class ExoskeletalArmor extends CardImpl {
public ExoskeletalArmor(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
this.subtype.add(SubType.AURA);
// Enchant creature
@@ -37,7 +36,7 @@ public final class ExoskeletalArmor extends CardImpl {
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Enchanted creature gets +X/+X, where X is the number of creature cards in all graveyards.
- CardsInAllGraveyardsCount count = new CardsInAllGraveyardsCount(new FilterCreatureCard());
+ CardsInAllGraveyardsCount count = new CardsInAllGraveyardsCount(StaticFilters.FILTER_CARD_CREATURES);
Effect effect = new BoostEnchantedEffect(count, count, Duration.WhileOnBattlefield);
effect.setText("Enchanted creature gets +X/+X, where X is the number of creature cards in all graveyards");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
diff --git a/Mage.Sets/src/mage/cards/e/Expropriate.java b/Mage.Sets/src/mage/cards/e/Expropriate.java
index 318fa8342f4..50b337157f1 100644
--- a/Mage.Sets/src/mage/cards/e/Expropriate.java
+++ b/Mage.Sets/src/mage/cards/e/Expropriate.java
@@ -1,5 +1,8 @@
package mage.cards.e;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl;
@@ -14,15 +17,10 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.turn.TurnMod;
import mage.players.Player;
-import mage.players.Players;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTarget;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
/**
* @author JRHerlehy
*/
@@ -49,19 +47,16 @@ public final class Expropriate extends CardImpl {
class ExpropriateDilemmaEffect extends CouncilsDilemmaVoteEffect {
- private Players moneyVoters = new Players();
+ private ArrayList choiceTwoVoters = new ArrayList<>();
public ExpropriateDilemmaEffect() {
super(Outcome.Benefit);
- this.staticText = "Council's dilemma — Starting with you, each player votes for time or money. For each time vote, take an extra turn after this one. For each money vote, choose a permanent owned by the voter and gain control of it.";
+ this.staticText = "Council's dilemma — Starting with you, each player votes for time or money. For each time vote, take an extra turn after this one. For each money vote, choose a permanent owned by the voter and gain control of it";
}
public ExpropriateDilemmaEffect(final ExpropriateDilemmaEffect effect) {
super(effect);
- }
-
- public ExpropriateDilemmaEffect(Outcome outcome) {
- super(outcome);
+ this.choiceTwoVoters.addAll(effect.choiceTwoVoters);
}
@Override
@@ -103,7 +98,7 @@ class ExpropriateDilemmaEffect extends CouncilsDilemmaVoteEffect {
private void controlForMoneyVote(Player controller, Game game, Ability source) {
List chosenCards = new ArrayList<>();
- for (UUID playerId : moneyVoters.keySet()) {
+ for (UUID playerId : choiceTwoVoters) {
FilterPermanent filter = new FilterPermanent("permanent owned by " + game.getPlayer(playerId).getName());
filter.add(new OwnerIdPredicate(playerId));
@@ -111,8 +106,7 @@ class ExpropriateDilemmaEffect extends CouncilsDilemmaVoteEffect {
target.setNotTarget(true);
if (controller != null
- && controller != game.getPlayer(playerId)
- && controller.choose(Outcome.GainControl, target, source.getSourceId(), game)) {
+ && controller.chooseTarget(Outcome.GainControl, target, source, game)) {
Permanent targetPermanent = game.getPermanent(target.getFirstTarget());
if (targetPermanent != null) {
@@ -123,27 +117,27 @@ class ExpropriateDilemmaEffect extends CouncilsDilemmaVoteEffect {
if (controller != null) {
for (Permanent permanent : chosenCards) {
ContinuousEffect effect = new ExpropriateControlEffect(controller.getId());
- effect.setTargetPointer(new FixedTarget(permanent.getId()));
+ effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
- game.informPlayers(controller.getName() + " gained control of " + permanent.getName() + " owned by " + game.getPlayer(permanent.getOwnerId()).getName());
+ game.informPlayers(controller.getName() + " gained control of " + permanent.getIdName() + " owned by " + game.getPlayer(permanent.getOwnerId()).getName());
}
}
}
@Override
protected void vote(String choiceOne, String choiceTwo, Player controller, Game game, Ability source) {
- for (UUID playerId : game.getState().getPlayerList(controller.getId())) {
+ for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
- if (player != null
- && player.canRespond()
- && player.isInGame()) {
- if (player.chooseUse(Outcome.Vote, "Choose " + choiceOne + '?', source, game)) {
+ if (player != null) {
+ if (player.chooseUse(Outcome.Vote,
+ "Choose " + choiceOne + " or " + choiceTwo + "?",
+ source.getRule(), choiceOne, choiceTwo, source, game)) {
voteOneCount++;
game.informPlayers(player.getName() + " has voted for " + choiceOne);
} else {
- moneyVoters.addPlayer(player);
voteTwoCount++;
game.informPlayers(player.getName() + " has voted for " + choiceTwo);
+ choiceTwoVoters.add(player.getId());
}
}
}
@@ -178,8 +172,11 @@ class ExpropriateControlEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
- return permanent != null
- && controllerId != null
- && permanent.changeControllerId(controllerId, game);
+ if (permanent == null || controllerId == null) {
+ this.discard();
+ } else {
+ permanent.changeControllerId(controllerId, game);
+ }
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/e/Extinction.java b/Mage.Sets/src/mage/cards/e/Extinction.java
index e77c192cb2f..27e3bc3be3e 100644
--- a/Mage.Sets/src/mage/cards/e/Extinction.java
+++ b/Mage.Sets/src/mage/cards/e/Extinction.java
@@ -1,7 +1,5 @@
-
package mage.cards.e;
-import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
@@ -18,8 +16,9 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class Extinction extends CardImpl {
@@ -44,7 +43,7 @@ public final class Extinction extends CardImpl {
class ExtinctionEffect extends OneShotEffect {
public ExtinctionEffect() {
- super(Outcome.UnboostCreature);
+ super(Outcome.DestroyPermanent);
staticText = "Destroy all creatures of the creature type of your choice";
}
diff --git a/Mage.Sets/src/mage/cards/e/ExtractFromDarkness.java b/Mage.Sets/src/mage/cards/e/ExtractFromDarkness.java
index d27b2671173..60fa0cc6823 100644
--- a/Mage.Sets/src/mage/cards/e/ExtractFromDarkness.java
+++ b/Mage.Sets/src/mage/cards/e/ExtractFromDarkness.java
@@ -1,4 +1,3 @@
-
package mage.cards.e;
import java.util.UUID;
@@ -9,7 +8,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.Target;
@@ -22,7 +21,7 @@ import mage.target.common.TargetCardInGraveyard;
public final class ExtractFromDarkness extends CardImpl {
public ExtractFromDarkness(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{U}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}{B}");
// Each player puts the top two cards of their library into their graveyard.
this.getSpellAbility().addEffect(new ExtractFromDarknessMillEffect());
@@ -88,7 +87,7 @@ class ExtractFromDarknessReturnFromGraveyardToBattlefieldEffect extends OneShotE
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- Target target = new TargetCardInGraveyard(new FilterCreatureCard());
+ Target target = new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE);
target.setNotTarget(true);
if (target.canChoose(source.getSourceId(), source.getControllerId(), game)
&& controller.chooseTarget(outcome, target, source, game)) {
diff --git a/Mage.Sets/src/mage/cards/e/EyeCollector.java b/Mage.Sets/src/mage/cards/e/EyeCollector.java
new file mode 100644
index 00000000000..708c9bec082
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/e/EyeCollector.java
@@ -0,0 +1,82 @@
+package mage.cards.e;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.keyword.FlyingAbility;
+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;
+import java.util.stream.Collectors;
+
+/**
+ * @author TheElk801
+ */
+public final class EyeCollector extends CardImpl {
+
+ public EyeCollector(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}");
+
+ this.subtype.add(SubType.FAERIE);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Whenever Eye Collector deals combat damage to a player, each player puts the top card of their library into their graveyard.
+ this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new EyeCollectorEffect(), false));
+ }
+
+ private EyeCollector(final EyeCollector card) {
+ super(card);
+ }
+
+ @Override
+ public EyeCollector copy() {
+ return new EyeCollector(this);
+ }
+}
+
+class EyeCollectorEffect extends OneShotEffect {
+
+ EyeCollectorEffect() {
+ super(Outcome.Benefit);
+ staticText = "each player puts the top card of their library into their graveyard";
+ }
+
+ private EyeCollectorEffect(final EyeCollectorEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public EyeCollectorEffect copy() {
+ return new EyeCollectorEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) {
+ return false;
+ }
+ return controller.moveCards(new CardsImpl(game.getState()
+ .getPlayersInRange(controller.getId(), game)
+ .stream()
+ .map(game::getPlayer)
+ .filter(player -> player != null)
+ .map(Player::getLibrary)
+ .map(library -> library.getFromTop(game))
+ .collect(Collectors.toSet())
+ ), Zone.GRAVEYARD, source, game);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/e/EyeOfDoom.java b/Mage.Sets/src/mage/cards/e/EyeOfDoom.java
index da09bdeea46..2ccd1e35591 100644
--- a/Mage.Sets/src/mage/cards/e/EyeOfDoom.java
+++ b/Mage.Sets/src/mage/cards/e/EyeOfDoom.java
@@ -1,9 +1,5 @@
-
package mage.cards.e;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
@@ -27,21 +23,26 @@ import mage.players.PlayerList;
import mage.target.Target;
import mage.target.common.TargetNonlandPermanent;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class EyeOfDoom extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("permanent with a doom counter on it");
+
static {
filter.add(new CounterPredicate(CounterType.DOOM));
}
+
public EyeOfDoom(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
// When Eye of Doom enters the battlefield, each player chooses a nonland permanent and puts a doom counter on it.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new EyeOfDoomEffect(),false));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new EyeOfDoomEffect(), false));
// {2}, {tap}, Sacrifice Eye of Doom: Destroy each permanent with a doom counter on it.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyAllEffect(filter), new GenericManaCost(2));
@@ -93,10 +94,10 @@ class EyeOfDoomEffect extends OneShotEffect {
game.informPlayers(player.getLogName() + " chooses " + permanent.getName());
}
}
- player = playerList.getNext(game);
+ player = playerList.getNext(game, false);
} while (!player.getId().equals(game.getActivePlayerId()));
- for (Permanent permanent: permanents) {
+ for (Permanent permanent : permanents) {
permanent.addCounters(CounterType.DOOM.createInstance(), source, game);
}
diff --git a/Mage.Sets/src/mage/cards/f/FabledPassage.java b/Mage.Sets/src/mage/cards/f/FabledPassage.java
new file mode 100644
index 00000000000..7897263e3aa
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FabledPassage.java
@@ -0,0 +1,90 @@
+package mage.cards.f;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeSourceCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.common.TargetCardInLibrary;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class FabledPassage extends CardImpl {
+
+ public FabledPassage(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ // {T}, Sacrifice Fabled Passage: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. Then if you control four or more lands, untap that land.
+ Ability ability = new SimpleActivatedAbility(new FabledPassageEffect(), new TapSourceCost());
+ ability.addCost(new SacrificeSourceCost());
+ this.addAbility(ability);
+ }
+
+ private FabledPassage(final FabledPassage card) {
+ super(card);
+ }
+
+ @Override
+ public FabledPassage copy() {
+ return new FabledPassage(this);
+ }
+}
+
+class FabledPassageEffect extends OneShotEffect {
+
+ FabledPassageEffect() {
+ super(Outcome.Benefit);
+ staticText = "Search your library for a basic land card, put it onto the battlefield tapped, " +
+ "then shuffle your library. Then if you control four or more lands, untap that land.";
+ }
+
+ private FabledPassageEffect(final FabledPassageEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public FabledPassageEffect copy() {
+ return new FabledPassageEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND_A);
+ if (!player.searchLibrary(target, source, game)) {
+ return false;
+ }
+ player.shuffleLibrary(source, game);
+ Card card = game.getCard(target.getFirstTarget());
+ if (card == null) {
+ return false;
+ }
+ if (!player.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null)) {
+ return false;
+ }
+ if (game.getBattlefield().countAll(StaticFilters.FILTER_LAND, source.getControllerId(), game) < 4) {
+ return true;
+ }
+ Permanent permanent = game.getPermanent(card.getId());
+ if (permanent == null) {
+ return false;
+ }
+ return permanent.untap(game);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FadeAway.java b/Mage.Sets/src/mage/cards/f/FadeAway.java
index d66da083617..199b8b4af41 100644
--- a/Mage.Sets/src/mage/cards/f/FadeAway.java
+++ b/Mage.Sets/src/mage/cards/f/FadeAway.java
@@ -26,7 +26,7 @@ public final class FadeAway extends CardImpl {
public FadeAway(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}");
- // For each creature, its controller sacrifices a permanent unless he or she pays {1}.
+ // For each creature, its controller sacrifices a permanent unless they pay {1}.
this.getSpellAbility().addEffect(new FadeAwayEffect());
}
@@ -46,7 +46,7 @@ class FadeAwayEffect extends OneShotEffect {
public FadeAwayEffect() {
super(Outcome.Sacrifice);
- this.staticText = "For each creature, its controller sacrifices a permanent unless he or she pays {1}";
+ this.staticText = "For each creature, its controller sacrifices a permanent unless they pay {1}";
}
public FadeAwayEffect(final FadeAwayEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/f/FaeOfWishes.java b/Mage.Sets/src/mage/cards/f/FaeOfWishes.java
new file mode 100644
index 00000000000..2c5ad0bdba5
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FaeOfWishes.java
@@ -0,0 +1,56 @@
+package mage.cards.f;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.DiscardTargetCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.ReturnToHandSourceEffect;
+import mage.abilities.effects.common.WishEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
+import mage.target.common.TargetCardInHand;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class FaeOfWishes extends AdventureCard {
+
+ public FaeOfWishes(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{1}{U}", "Granted", "{3}{U}");
+
+ this.subtype.add(SubType.FAERIE);
+ this.subtype.add(SubType.WIZARD);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(4);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // {1}{U}, Discard two cards: Return Fae of Wishes to its owner's hand.
+ Ability ability = new SimpleActivatedAbility(
+ new ReturnToHandSourceEffect(true), new ManaCostsImpl("{1}{U}")
+ );
+ ability.addCost(new DiscardTargetCost(new TargetCardInHand(2, StaticFilters.FILTER_CARD)));
+ this.addAbility(ability);
+
+ // Granted
+ // You may choose a noncreature card you own from outside the game, reveal it, and put it into your hand.
+ this.getSpellCard().getSpellAbility().addEffect(new WishEffect(StaticFilters.FILTER_CARD_A_NON_CREATURE));
+ }
+
+ private FaeOfWishes(final FaeOfWishes card) {
+ super(card);
+ }
+
+ @Override
+ public FaeOfWishes copy() {
+ return new FaeOfWishes(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FaeburrowElder.java b/Mage.Sets/src/mage/cards/f/FaeburrowElder.java
new file mode 100644
index 00000000000..6cfbe654307
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FaeburrowElder.java
@@ -0,0 +1,142 @@
+package mage.cards.f;
+
+import mage.MageInt;
+import mage.Mana;
+import mage.ObjectColor;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.ManaEffect;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.abilities.mana.SimpleManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class FaeburrowElder extends CardImpl {
+
+ public FaeburrowElder(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{W}");
+
+ this.subtype.add(SubType.TREEFOLK);
+ this.subtype.add(SubType.DRUID);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(0);
+
+ // Vigilance
+ this.addAbility(VigilanceAbility.getInstance());
+
+ // Faeburrow Elder gets +1/+1 for each color among permanents you control.
+ this.addAbility(new SimpleStaticAbility(new BoostSourceEffect(
+ FaeburrowElderValue.instance, FaeburrowElderValue.instance, Duration.WhileOnBattlefield, false
+ )));
+
+ // {T}: For each color among permanents you control, add one mana of that color.
+ this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new FaeburrowElderManaEffect(), new TapSourceCost()));
+ }
+
+ private FaeburrowElder(final FaeburrowElder card) {
+ super(card);
+ }
+
+ @Override
+ public FaeburrowElder copy() {
+ return new FaeburrowElder(this);
+ }
+}
+
+enum FaeburrowElderValue implements DynamicValue {
+ instance;
+
+ @Override
+ public int calculate(Game game, Ability sourceAbility, Effect effect) {
+ ObjectColor color = new ObjectColor("");
+ game.getBattlefield()
+ .getAllActivePermanents(sourceAbility.getControllerId())
+ .stream()
+ .map(permanent -> permanent.getColor(game))
+ .forEach(color::addColor);
+ return color.getColorCount();
+ }
+
+ @Override
+ public FaeburrowElderValue copy() {
+ return instance;
+ }
+
+ @Override
+ public String toString() {
+ return "1";
+ }
+
+ @Override
+ public String getMessage() {
+ return "for each color among permanents you control";
+ }
+}
+
+class FaeburrowElderManaEffect extends ManaEffect {
+
+ FaeburrowElderManaEffect() {
+ super();
+ staticText = "For each color among permanents you control, add one mana of that color";
+ }
+
+ private FaeburrowElderManaEffect(final FaeburrowElderManaEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public FaeburrowElderManaEffect copy() {
+ return new FaeburrowElderManaEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) {
+ return false;
+ }
+ Mana mana = getMana(game, source);
+ checkToFirePossibleEvents(mana, game, source);
+ controller.getManaPool().addMana(mana, game, source);
+ return true;
+ }
+
+ @Override
+ public Mana produceMana(boolean netMana, Game game, Ability source) {
+ Mana mana = new Mana();
+ for (Permanent permanent : game.getBattlefield().getAllActivePermanents(source.getControllerId())) {
+ if (mana.getBlack() == 0 && permanent.getColor(game).isBlack()) {
+ mana.increaseBlack();
+ }
+ if (mana.getBlue() == 0 && permanent.getColor(game).isBlue()) {
+ mana.increaseBlue();
+ }
+ if (mana.getRed() == 0 && permanent.getColor(game).isRed()) {
+ mana.increaseRed();
+ }
+ if (mana.getGreen() == 0 && permanent.getColor(game).isGreen()) {
+ mana.increaseGreen();
+ }
+ if (mana.getWhite() == 0 && permanent.getColor(game).isWhite()) {
+ mana.increaseWhite();
+ }
+ }
+ return mana;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FaerieArtisans.java b/Mage.Sets/src/mage/cards/f/FaerieArtisans.java
index f02fa39ba42..5d1e4899e63 100644
--- a/Mage.Sets/src/mage/cards/f/FaerieArtisans.java
+++ b/Mage.Sets/src/mage/cards/f/FaerieArtisans.java
@@ -1,4 +1,3 @@
-
package mage.cards.f;
import java.util.StringTokenizer;
@@ -81,7 +80,7 @@ class FaerieArtisansEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- Permanent permanentToCopy = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source));
+ Permanent permanentToCopy = game.getPermanentOrLKIBattlefield(getTargetPointer().getFixedTarget(game, source).getTarget());
Player controller = game.getPlayer(source.getControllerId());
if (controller != null && permanentToCopy != null) {
CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, CardType.ARTIFACT, false);
diff --git a/Mage.Sets/src/mage/cards/f/FaerieFormation.java b/Mage.Sets/src/mage/cards/f/FaerieFormation.java
new file mode 100644
index 00000000000..770fbef75c9
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FaerieFormation.java
@@ -0,0 +1,47 @@
+package mage.cards.f;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.game.permanent.token.FaerieToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class FaerieFormation extends CardImpl {
+
+ public FaerieFormation(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}");
+
+ this.subtype.add(SubType.FAERIE);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(4);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // {3}{U}: Create a 1/1 blue Faerie creature token with flying. Draw a card.
+ Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new FaerieToken()), new ManaCostsImpl("{3}{U}"));
+ ability.addEffect(new DrawCardSourceControllerEffect(1).setText("Draw a card"));
+ this.addAbility(ability);
+ }
+
+ private FaerieFormation(final FaerieFormation card) {
+ super(card);
+ }
+
+ @Override
+ public FaerieFormation copy() {
+ return new FaerieFormation(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FaerieGuidemother.java b/Mage.Sets/src/mage/cards/f/FaerieGuidemother.java
new file mode 100644
index 00000000000..24425fc8f13
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FaerieGuidemother.java
@@ -0,0 +1,50 @@
+package mage.cards.f;
+
+import mage.MageInt;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class FaerieGuidemother extends AdventureCard {
+
+ public FaerieGuidemother(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{W}", "Gift of the Fae", "{1}{W}");
+
+ this.subtype.add(SubType.FAERIE);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Gift of the Fae
+ // Target creature gets +2/+1 and gains flying until end of turn.
+ this.getSpellCard().getSpellAbility().addEffect(new BoostTargetEffect(
+ 2, 1, Duration.EndOfTurn
+ ).setText("Target creature gets +2/+1"));
+ this.getSpellCard().getSpellAbility().addEffect(new GainAbilityTargetEffect(
+ FlyingAbility.getInstance(), Duration.EndOfTurn
+ ).setText("and gains flying until end of turn"));
+ this.getSpellCard().getSpellAbility().addTarget(new TargetCreaturePermanent());
+ }
+
+ private FaerieGuidemother(final FaerieGuidemother card) {
+ super(card);
+ }
+
+ @Override
+ public FaerieGuidemother copy() {
+ return new FaerieGuidemother(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FaerieNoble.java b/Mage.Sets/src/mage/cards/f/FaerieNoble.java
index 6962d487189..e9d6f52b52e 100644
--- a/Mage.Sets/src/mage/cards/f/FaerieNoble.java
+++ b/Mage.Sets/src/mage/cards/f/FaerieNoble.java
@@ -1,7 +1,5 @@
-
package mage.cards.f;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -19,12 +17,13 @@ import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
+import java.util.UUID;
+
/**
- *
* @author ilcartographer
*/
public final class FaerieNoble extends CardImpl {
-
+
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Faerie creatures");
static {
@@ -32,8 +31,8 @@ public final class FaerieNoble extends CardImpl {
}
public FaerieNoble(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}");
- this.subtype.add(SubType.FAERIE);
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
+ this.subtype.add(SubType.FAERIE, SubType.NOBLE);
this.power = new MageInt(1);
this.toughness = new MageInt(2);
diff --git a/Mage.Sets/src/mage/cards/f/FaerieVandal.java b/Mage.Sets/src/mage/cards/f/FaerieVandal.java
new file mode 100644
index 00000000000..dff975f655d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FaerieVandal.java
@@ -0,0 +1,49 @@
+package mage.cards.f;
+
+import mage.MageInt;
+import mage.abilities.common.DrawSecondCardTriggeredAbility;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.keyword.FlashAbility;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+
+import java.util.UUID;
+
+/**
+ * @author jmharmon
+ */
+public final class FaerieVandal extends CardImpl {
+
+ public FaerieVandal(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
+ this.subtype.add(SubType.FAERIE);
+ this.subtype.add(SubType.ROGUE);
+
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(2);
+
+ // Flash
+ this.addAbility(FlashAbility.getInstance());
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Whenever you draw your second card each turn, put a +1/+1 counter on Faerie Vandal.
+ this.addAbility(new DrawSecondCardTriggeredAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false
+ ));
+ }
+
+ private FaerieVandal(final FaerieVandal card) {
+ super(card);
+ }
+
+ @Override
+ public FaerieVandal copy() {
+ return new FaerieVandal(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FalkenrathAristocrat.java b/Mage.Sets/src/mage/cards/f/FalkenrathAristocrat.java
index 7dbd0922e25..70ee0b725c1 100644
--- a/Mage.Sets/src/mage/cards/f/FalkenrathAristocrat.java
+++ b/Mage.Sets/src/mage/cards/f/FalkenrathAristocrat.java
@@ -1,7 +1,5 @@
-
package mage.cards.f;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -16,20 +14,22 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
-import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
+import java.util.UUID;
+
+import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
+
/**
- *
* @author North
*/
public final class FalkenrathAristocrat extends CardImpl {
public FalkenrathAristocrat(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}");
- this.subtype.add(SubType.VAMPIRE);
+ this.subtype.add(SubType.VAMPIRE, SubType.NOBLE);
this.power = new MageInt(4);
this.toughness = new MageInt(1);
diff --git a/Mage.Sets/src/mage/cards/f/FalkenrathNoble.java b/Mage.Sets/src/mage/cards/f/FalkenrathNoble.java
index 3491dc52628..35cc7bbde12 100644
--- a/Mage.Sets/src/mage/cards/f/FalkenrathNoble.java
+++ b/Mage.Sets/src/mage/cards/f/FalkenrathNoble.java
@@ -1,7 +1,5 @@
-
package mage.cards.f;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.GainLifeEffect;
@@ -19,15 +17,16 @@ import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.target.TargetPlayer;
+import java.util.UUID;
+
/**
- *
* @author North
*/
public final class FalkenrathNoble extends CardImpl {
public FalkenrathNoble(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}");
- this.subtype.add(SubType.VAMPIRE);
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
+ this.subtype.add(SubType.VAMPIRE, SubType.NOBLE);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
@@ -72,19 +71,17 @@ class FalkenrathNobleTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
- if (zEvent.isDiesEvent()) {
- Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
- if (permanent != null) {
- if (permanent.getId().equals(this.getSourceId())) {
- return true;
- } else {
- if (permanent.isCreature()) {
- return true;
- }
- }
- }
+ if (!zEvent.isDiesEvent()) {
+ return false;
}
- return false;
+ Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
+ if (permanent == null) {
+ return false;
+ }
+ if (permanent.getId().equals(this.getSourceId())) {
+ return true;
+ }
+ return permanent.isCreature();
}
@Override
diff --git a/Mage.Sets/src/mage/cards/f/FalseCure.java b/Mage.Sets/src/mage/cards/f/FalseCure.java
index 1ea96aaf14e..d156f4ff4e1 100644
--- a/Mage.Sets/src/mage/cards/f/FalseCure.java
+++ b/Mage.Sets/src/mage/cards/f/FalseCure.java
@@ -25,7 +25,7 @@ public final class FalseCure extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}{B}");
- // Until end of turn, whenever a player gains life, that player loses 2 life for each 1 life he or she gained.
+ // Until end of turn, whenever a player gains life, that player loses 2 life for each 1 life they gained.
this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new FalseCureTriggeredAbility()));
}
@@ -70,6 +70,6 @@ class FalseCureTriggeredAbility extends DelayedTriggeredAbility {
@Override
public String getRule() {
- return "Until end of turn, whenever a player gains life, that player loses 2 life for each 1 life he or she gained.";
+ return "Until end of turn, whenever a player gains life, that player loses 2 life for each 1 life they gained.";
}
}
diff --git a/Mage.Sets/src/mage/cards/f/FanaticOfMogis.java b/Mage.Sets/src/mage/cards/f/FanaticOfMogis.java
index 580421ec3c5..6c107a4d48a 100644
--- a/Mage.Sets/src/mage/cards/f/FanaticOfMogis.java
+++ b/Mage.Sets/src/mage/cards/f/FanaticOfMogis.java
@@ -1,28 +1,25 @@
-
package mage.cards.f;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.common.DevotionCount;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamagePlayersEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.ColoredManaSymbol;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.TargetController;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class FanaticOfMogis extends CardImpl {
public FanaticOfMogis(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
this.subtype.add(SubType.MINOTAUR);
this.subtype.add(SubType.SHAMAN);
@@ -30,12 +27,13 @@ public final class FanaticOfMogis extends CardImpl {
this.toughness = new MageInt(2);
// When Fanatic of Mogis enters the battlefield, it deals damage to each opponent equal to your devotion to red.
- Effect effect = new DamagePlayersEffect(Outcome.Damage, new DevotionCount(ColoredManaSymbol.R), TargetController.OPPONENT);
- effect.setText("it deals damage to each opponent equal to your devotion to red. (Each {R} in the mana costs of permanents you control counts towards your devotion to red.)");
- this.addAbility(new EntersBattlefieldTriggeredAbility(effect, false));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(
+ new DamagePlayersEffect(Outcome.Damage, DevotionCount.R, TargetController.OPPONENT)
+ .setText("it deals damage to each opponent equal to your devotion to red."), false
+ ).addHint(DevotionCount.R.getHint()));
}
- public FanaticOfMogis(final FanaticOfMogis card) {
+ private FanaticOfMogis(final FanaticOfMogis card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/f/Fatigue.java b/Mage.Sets/src/mage/cards/f/Fatigue.java
index 8f3ae9784b2..9cdd6176c33 100644
--- a/Mage.Sets/src/mage/cards/f/Fatigue.java
+++ b/Mage.Sets/src/mage/cards/f/Fatigue.java
@@ -13,13 +13,13 @@ import mage.target.TargetPlayer;
*/
public final class Fatigue extends CardImpl {
- private static final String rule = "Target player skips his or her next draw step.";
+ private static final String rule = "Target player skips their next draw step.";
public Fatigue(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}");
- // Target player skips his or her next draw step.
+ // Target player skips their next draw step.
this.getSpellAbility().addEffect(new SkipNextDrawStepTargetEffect().setText(rule));
this.getSpellAbility().addTarget(new TargetPlayer());
diff --git a/Mage.Sets/src/mage/cards/f/FaunaShaman.java b/Mage.Sets/src/mage/cards/f/FaunaShaman.java
index d82b8336646..10791cce5de 100644
--- a/Mage.Sets/src/mage/cards/f/FaunaShaman.java
+++ b/Mage.Sets/src/mage/cards/f/FaunaShaman.java
@@ -1,5 +1,3 @@
-
-
package mage.cards.f;
import java.util.UUID;
@@ -13,10 +11,10 @@ import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.ColoredManaSymbol;
+import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetCardInLibrary;
@@ -27,7 +25,7 @@ import mage.target.common.TargetCardInLibrary;
public final class FaunaShaman extends CardImpl {
public FaunaShaman(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.ELF);
this.subtype.add(SubType.SHAMAN);
@@ -36,10 +34,10 @@ public final class FaunaShaman extends CardImpl {
// {G}, {tap}, Discard a creature card: Search your library for a creature card, reveal it, and put it into your hand. Then shuffle your library.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
- new SearchLibraryPutInHandEffect(new TargetCardInLibrary(new FilterCreatureCard()), true),
+ new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_CREATURE), true),
new ColoredManaCost(ColoredManaSymbol.G));
ability.addCost(new TapSourceCost());
- ability.addCost(new DiscardTargetCost(new TargetCardInHand(new FilterCreatureCard())));
+ ability.addCost(new DiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE)));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/f/FeastingTrollKing.java b/Mage.Sets/src/mage/cards/f/FeastingTrollKing.java
new file mode 100644
index 00000000000..8a8955c7da9
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FeastingTrollKing.java
@@ -0,0 +1,71 @@
+package mage.cards.f;
+
+import mage.MageInt;
+import mage.abilities.common.ActivateIfConditionActivatedAbility;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.condition.common.CastFromHandSourceCondition;
+import mage.abilities.condition.common.MyTurnCondition;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect;
+import mage.abilities.keyword.TrampleAbility;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.common.FilterControlledPermanent;
+import mage.game.permanent.token.FoodToken;
+import mage.target.common.TargetControlledPermanent;
+import mage.watchers.common.CastFromHandWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class FeastingTrollKing extends CardImpl {
+
+ private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.FOOD, "Foods");
+
+ public FeastingTrollKing(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}{G}{G}");
+
+ this.subtype.add(SubType.TROLL);
+ this.subtype.add(SubType.NOBLE);
+ this.power = new MageInt(7);
+ this.toughness = new MageInt(6);
+
+ // Vigilance
+ this.addAbility(VigilanceAbility.getInstance());
+
+ // Trample
+ this.addAbility(TrampleAbility.getInstance());
+
+ // When Feasting Troll King enters the battlefield, if you cast it from your hand, create three Food tokens.
+ this.addAbility(new ConditionalInterveningIfTriggeredAbility(
+ new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new FoodToken(), 3)),
+ CastFromHandSourceCondition.instance, "When {this} enters the battlefield, " +
+ "if you cast it from your hand, create three Food tokens."
+ ), new CastFromHandWatcher());
+
+ // Sacrifice three Foods: Return Feasting Troll King from your graveyard to the battlefield. Activate this ability only during your turn.
+ this.addAbility(new ActivateIfConditionActivatedAbility(
+ Zone.GRAVEYARD,
+ new ReturnSourceFromGraveyardToBattlefieldEffect(),
+ new SacrificeTargetCost(new TargetControlledPermanent(3, filter)),
+ MyTurnCondition.instance
+ ));
+ }
+
+ private FeastingTrollKing(final FeastingTrollKing card) {
+ super(card);
+ }
+
+ @Override
+ public FeastingTrollKing copy() {
+ return new FeastingTrollKing(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FellThePheasant.java b/Mage.Sets/src/mage/cards/f/FellThePheasant.java
new file mode 100644
index 00000000000..14c4c01826e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FellThePheasant.java
@@ -0,0 +1,46 @@
+package mage.cards.f;
+
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.AbilityPredicate;
+import mage.game.permanent.token.FoodToken;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class FellThePheasant extends CardImpl {
+
+
+ private static final FilterPermanent filter = new FilterCreaturePermanent("creature with flying.");
+
+ static {
+ filter.add(new AbilityPredicate(FlyingAbility.class));
+ }
+
+ public FellThePheasant(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}");
+
+ // Fell the Pheasant deals 5 damage to target creature with flying. Create a Food token.
+ this.getSpellAbility().addEffect(new DamageTargetEffect(5));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new FoodToken()));
+ this.getSpellAbility().addTarget(new TargetPermanent(filter));
+ }
+
+ private FellThePheasant(final FellThePheasant card) {
+ super(card);
+ }
+
+ @Override
+ public FellThePheasant copy() {
+ return new FellThePheasant(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FerocityOfTheWilds.java b/Mage.Sets/src/mage/cards/f/FerocityOfTheWilds.java
new file mode 100644
index 00000000000..43da88093b6
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FerocityOfTheWilds.java
@@ -0,0 +1,57 @@
+package mage.cards.f;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.continuous.BoostControlledEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
+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.TargetController;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.filter.predicate.permanent.AttackingPredicate;
+import mage.filter.predicate.permanent.ControllerPredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class FerocityOfTheWilds extends CardImpl {
+
+ private static final FilterCreaturePermanent filter
+ = new FilterCreaturePermanent("attacking non-Human creatures");
+
+ static {
+ filter.add(AttackingPredicate.instance);
+ filter.add(new ControllerPredicate(TargetController.YOU));
+ filter.add(Predicates.not(new SubtypePredicate(SubType.HUMAN)));
+ }
+
+ public FerocityOfTheWilds(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
+
+ // Attacking non-Human creatures you control get +1/+0 and have trample.
+ Ability ability = new SimpleStaticAbility(
+ new BoostControlledEffect(1, 0, Duration.WhileOnBattlefield, filter)
+ );
+ ability.addEffect(new GainAbilityAllEffect(
+ TrampleAbility.getInstance(), Duration.WhileOnBattlefield, filter, "and have trample"
+ ));
+ this.addAbility(ability);
+ }
+
+ private FerocityOfTheWilds(final FerocityOfTheWilds card) {
+ super(card);
+ }
+
+ @Override
+ public FerocityOfTheWilds copy() {
+ return new FerocityOfTheWilds(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FerozsBan.java b/Mage.Sets/src/mage/cards/f/FerozsBan.java
index 55afde6661f..bda78ea60a2 100644
--- a/Mage.Sets/src/mage/cards/f/FerozsBan.java
+++ b/Mage.Sets/src/mage/cards/f/FerozsBan.java
@@ -1,4 +1,3 @@
-
package mage.cards.f;
import java.util.UUID;
@@ -9,20 +8,20 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
* @author LoneFox
-
+ *
*/
public final class FerozsBan extends CardImpl {
public FerozsBan(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{6}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{6}");
// Creature spells cost {2} more to cast.
- Effect effect = new SpellsCostIncreasementAllEffect(new FilterCreatureCard(), 2);
+ Effect effect = new SpellsCostIncreasementAllEffect(StaticFilters.FILTER_CARD_CREATURE, 2);
effect.setText("Creature spells cost {2} more to cast.");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
}
diff --git a/Mage.Sets/src/mage/cards/f/FerventChampion.java b/Mage.Sets/src/mage/cards/f/FerventChampion.java
new file mode 100644
index 00000000000..e6122045a49
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FerventChampion.java
@@ -0,0 +1,107 @@
+package mage.cards.f;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.abilities.effects.common.cost.CostModificationEffectImpl;
+import mage.abilities.keyword.EquipAbility;
+import mage.abilities.keyword.FirstStrikeAbility;
+import mage.abilities.keyword.HasteAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterPermanent;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.filter.predicate.permanent.AttackingPredicate;
+import mage.game.Game;
+import mage.target.Target;
+import mage.target.TargetPermanent;
+import mage.util.CardUtil;
+
+import java.util.Collection;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class FerventChampion extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterPermanent(SubType.KNIGHT, "another target attacking Knight");
+
+ static {
+ filter.add(AttackingPredicate.instance);
+ filter.add(AnotherPredicate.instance);
+ }
+
+ public FerventChampion(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // First strike
+ this.addAbility(FirstStrikeAbility.getInstance());
+
+ // Haste
+ this.addAbility(HasteAbility.getInstance());
+
+ // Whenever Fervent Champion attacks, another target attacking Knight you control gets +1/+0 until end of turn.
+ Ability ability = new AttacksTriggeredAbility(
+ new BoostTargetEffect(1, 0, Duration.EndOfTurn), false
+ );
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(ability);
+
+ // Equip abilities you activate that target Fervent Champion cost {3} less to activate.
+ this.addAbility(new SimpleStaticAbility(new FerventChampionEffect()));
+ }
+
+ private FerventChampion(final FerventChampion card) {
+ super(card);
+ }
+
+ @Override
+ public FerventChampion copy() {
+ return new FerventChampion(this);
+ }
+}
+
+class FerventChampionEffect extends CostModificationEffectImpl {
+
+ FerventChampionEffect() {
+ super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST);
+ staticText = "equip abilities you activate that target {this} cost {3} less to activate";
+ }
+
+ private FerventChampionEffect(final FerventChampionEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source, Ability abilityToModify) {
+ CardUtil.reduceCost(abilityToModify, 3);
+ return true;
+ }
+
+ @Override
+ public boolean applies(Ability abilityToModify, Ability source, Game game) {
+ return abilityToModify instanceof EquipAbility
+ && abilityToModify.isControlledBy(source.getControllerId())
+ && abilityToModify
+ .getTargets()
+ .stream()
+ .map(Target::getTargets)
+ .flatMap(Collection::stream)
+ .anyMatch(source.getSourceId()::equals);
+ }
+
+ @Override
+ public FerventChampionEffect copy() {
+ return new FerventChampionEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FestiveFuneral.java b/Mage.Sets/src/mage/cards/f/FestiveFuneral.java
new file mode 100644
index 00000000000..087e7d73d4d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FestiveFuneral.java
@@ -0,0 +1,40 @@
+package mage.cards.f;
+
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.filter.StaticFilters;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class FestiveFuneral extends CardImpl {
+
+ private static final DynamicValue xValue = new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD, -1);
+
+ public FestiveFuneral(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{B}");
+
+ // Target creature gets -X/-X until end of turn, where X is the number of cards in your graveyard.
+ this.getSpellAbility().addEffect(new BoostTargetEffect(
+ xValue, xValue, Duration.EndOfTurn, true
+ ).setText("target creature gets -X/-X until end of turn, where X is the number of cards in your graveyard"));
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent());
+ }
+
+ private FestiveFuneral(final FestiveFuneral card) {
+ super(card);
+ }
+
+ @Override
+ public FestiveFuneral copy() {
+ return new FestiveFuneral(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FeveredVisions.java b/Mage.Sets/src/mage/cards/f/FeveredVisions.java
index 8cb176271f7..94ecdabea0f 100644
--- a/Mage.Sets/src/mage/cards/f/FeveredVisions.java
+++ b/Mage.Sets/src/mage/cards/f/FeveredVisions.java
@@ -24,7 +24,7 @@ public final class FeveredVisions extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{U}{R}");
// At the beginning of each player's end step, that player draws a card. If the player is your opponent and has four or more cards in hand,
- // Fevered Visions deals 2 damage to him or her.
+ // Fevered Visions deals 2 damage to that player.
this.addAbility(new BeginningOfEndStepTriggeredAbility(new FeveredVisionsEffect(), TargetController.ANY, false));
}
@@ -42,7 +42,7 @@ class FeveredVisionsEffect extends OneShotEffect {
public FeveredVisionsEffect() {
super(Outcome.DrawCard);
- staticText = "that player draws a card. If the player is your opponent and has four or more cards in hand, {this} deals 2 damage to him or her";
+ staticText = "that player draws a card. If the player is your opponent and has four or more cards in hand, {this} deals 2 damage to that player";
}
public FeveredVisionsEffect(final FeveredVisionsEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/f/FiendishDuo.java b/Mage.Sets/src/mage/cards/f/FiendishDuo.java
new file mode 100644
index 00000000000..e8ae73d92ee
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FiendishDuo.java
@@ -0,0 +1,88 @@
+package mage.cards.f;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ReplacementEffectImpl;
+import mage.abilities.keyword.FirstStrikeAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.players.Player;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class FiendishDuo extends CardImpl {
+
+ public FiendishDuo(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}");
+
+ this.subtype.add(SubType.DEVIL);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(5);
+
+ // First strike
+ this.addAbility(FirstStrikeAbility.getInstance());
+
+ // If a source would deal damage to an opponent, it deals double that damage to that player instead.
+ this.addAbility(new SimpleStaticAbility(new FiendishDuoEffect()));
+ }
+
+ private FiendishDuo(final FiendishDuo card) {
+ super(card);
+ }
+
+ @Override
+ public FiendishDuo copy() {
+ return new FiendishDuo(this);
+ }
+}
+
+class FiendishDuoEffect extends ReplacementEffectImpl {
+
+ FiendishDuoEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.Damage);
+ staticText = "If a source would deal damage to an opponent, " +
+ "it deals double that damage to that player instead";
+ }
+
+ private FiendishDuoEffect(final FiendishDuoEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public FiendishDuoEffect copy() {
+ return new FiendishDuoEffect(this);
+ }
+
+ @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) {
+ Player player = game.getPlayer(source.getControllerId());
+ return player != null && player.hasOpponent(event.getTargetId(), game);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public boolean replaceEvent(GameEvent event, Ability source, Game game) {
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount()));
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FierceWitchstalker.java b/Mage.Sets/src/mage/cards/f/FierceWitchstalker.java
new file mode 100644
index 00000000000..a4defd85a5d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FierceWitchstalker.java
@@ -0,0 +1,42 @@
+package mage.cards.f;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.keyword.TrampleAbility;
+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 FierceWitchstalker extends CardImpl {
+
+ public FierceWitchstalker(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}");
+
+ this.subtype.add(SubType.WOLF);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(4);
+
+ // Trample
+ this.addAbility(TrampleAbility.getInstance());
+
+ // When Fierce Witchstalker enters the battlefield, create a Food token.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new FoodToken())));
+ }
+
+ private FierceWitchstalker(final FierceWitchstalker card) {
+ super(card);
+ }
+
+ @Override
+ public FierceWitchstalker copy() {
+ return new FierceWitchstalker(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FieryImpulse.java b/Mage.Sets/src/mage/cards/f/FieryImpulse.java
index b8e2e52d5fb..8a1738dc116 100644
--- a/Mage.Sets/src/mage/cards/f/FieryImpulse.java
+++ b/Mage.Sets/src/mage/cards/f/FieryImpulse.java
@@ -1,7 +1,6 @@
package mage.cards.f;
-import java.util.UUID;
import mage.abilities.condition.common.SpellMasteryCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
@@ -10,20 +9,21 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class FieryImpulse extends CardImpl {
public FieryImpulse(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}");
// Fiery Impulse deals 2 damage to target creature.
// Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, Fiery Impulse deals 3 damage to that creature instead.
- this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new DamageTargetEffect(3),
- new DamageTargetEffect(2), SpellMasteryCondition.instance,
- "{this} deals 2 damage to target creature. Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, {this} deals 3 damage to that creature instead"));
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new DamageTargetEffect(3), new DamageTargetEffect(2), SpellMasteryCondition.instance,
+ "{this} deals 2 damage to target creature.
Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, {this} deals 3 damage instead"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
diff --git a/Mage.Sets/src/mage/cards/f/FinalPunishment.java b/Mage.Sets/src/mage/cards/f/FinalPunishment.java
index abf048a6360..d9a81a7b62d 100644
--- a/Mage.Sets/src/mage/cards/f/FinalPunishment.java
+++ b/Mage.Sets/src/mage/cards/f/FinalPunishment.java
@@ -22,9 +22,9 @@ public final class FinalPunishment extends CardImpl {
public FinalPunishment(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}{B}");
- // Target player loses life equal to the damage already dealt to him or her this turn.
+ // Target player loses life equal to the damage already dealt to that player this turn.
Effect effect = new LoseLifeTargetEffect(new FinalPunishmentAmount());
- effect.setText("target player loses life equal to the damage already dealt to him or her this turn");
+ effect.setText("target player loses life equal to the damage already dealt to that player this turn");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addWatcher(new AmountOfDamageAPlayerReceivedThisTurnWatcher());
@@ -59,6 +59,6 @@ class FinalPunishmentAmount implements DynamicValue {
@Override
public String getMessage() {
- return "the damage already dealt to him or her this turn";
+ return "the damage already dealt to that player this turn";
}
}
diff --git a/Mage.Sets/src/mage/cards/f/FinaleOfPromise.java b/Mage.Sets/src/mage/cards/f/FinaleOfPromise.java
index b02b56dbb87..21183ceab34 100644
--- a/Mage.Sets/src/mage/cards/f/FinaleOfPromise.java
+++ b/Mage.Sets/src/mage/cards/f/FinaleOfPromise.java
@@ -126,7 +126,8 @@ class FinaleOfPromiseEffect extends OneShotEffect {
.filter(Objects::nonNull)
.map(Card::getName)
.collect(Collectors.joining(" -> "));
- if (!controller.chooseUse(Outcome.Detriment, "Cast cards by choose order: " + cardsOrder + "?", "Finale of Promise",
+ if (!controller.chooseUse(Outcome.Detriment, "Cast cards by choose order: "
+ + cardsOrder + "?", "Finale of Promise",
"Use that order", "Reverse", source, game)) {
Collections.reverse(cardsToCast);
}
@@ -136,7 +137,10 @@ class FinaleOfPromiseEffect extends OneShotEffect {
for (UUID id : cardsToCast) {
Card card = game.getCard(id);
if (card != null) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
ContinuousEffect effect = new FinaleOfPromiseReplacementEffect();
effect.setTargetPointer(new FixedTarget(card.getId(), game.getState().getZoneChangeCounter(card.getId())));
game.addEffect(effect, source);
@@ -205,6 +209,7 @@ class FinaleOfPromiseReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
- return zEvent.getToZone() == Zone.GRAVEYARD && event.getTargetId().equals(getTargetPointer().getFirst(game, source));
+ return zEvent.getToZone() == Zone.GRAVEYARD
+ && event.getTargetId().equals(getTargetPointer().getFirst(game, source));
}
}
diff --git a/Mage.Sets/src/mage/cards/f/FirebornKnight.java b/Mage.Sets/src/mage/cards/f/FirebornKnight.java
new file mode 100644
index 00000000000..7a2d0e82981
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FirebornKnight.java
@@ -0,0 +1,47 @@
+package mage.cards.f;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.abilities.keyword.DoubleStrikeAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.Zone;
+
+import java.util.UUID;
+
+/**
+ * @author jmharmon
+ */
+
+public final class FirebornKnight extends CardImpl {
+
+ public FirebornKnight(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R/W}{R/W}{R/W}{R/W}");
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // Double strike
+ this.addAbility(DoubleStrikeAbility.getInstance());
+
+ // {R/W}{R/W}{R/W}{R/W}: Fireborn Knight gets +1/+1 until end of turn.
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 1, Duration.EndOfTurn),
+ new ManaCostsImpl("{R/W}{R/W}{R/W}{R/W}")));
+ }
+
+ public FirebornKnight(final FirebornKnight card) {
+ super(card);
+ }
+
+ @Override
+ public FirebornKnight copy() {
+ return new FirebornKnight(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FirecannonBlast.java b/Mage.Sets/src/mage/cards/f/FirecannonBlast.java
index abebb600f09..ae1daf34610 100644
--- a/Mage.Sets/src/mage/cards/f/FirecannonBlast.java
+++ b/Mage.Sets/src/mage/cards/f/FirecannonBlast.java
@@ -1,7 +1,6 @@
package mage.cards.f;
-import java.util.UUID;
import mage.abilities.condition.InvertCondition;
import mage.abilities.condition.common.RaidCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
@@ -12,8 +11,9 @@ import mage.constants.CardType;
import mage.target.common.TargetCreaturePermanent;
import mage.watchers.common.PlayerAttackedWatcher;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class FirecannonBlast extends CardImpl {
@@ -22,16 +22,13 @@ public final class FirecannonBlast extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}{R}");
// Firecannon Blast deals 3 damage to target creature.
- this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
- new DamageTargetEffect(3),
- new InvertCondition(RaidCondition.instance),
- "{this} deals 3 damage to target creature"));
- this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Raid - Firecannon Blast deals 6 damage to that creature instead if you attacked with a creature this turn.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
- new DamageTargetEffect(6, false),
+ new DamageTargetEffect(6),
+ new DamageTargetEffect(3),
RaidCondition.instance,
- "
Raid — {this} deals 6 damage to that creature instead if you attacked with a creature this turn"));
+ "{this} deals 3 damage to target creature.
Raid — {this} deals 6 damage instead if you attacked with a creature this turn"));
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addWatcher(new PlayerAttackedWatcher());
}
diff --git a/Mage.Sets/src/mage/cards/f/FiresOfInvention.java b/Mage.Sets/src/mage/cards/f/FiresOfInvention.java
new file mode 100644
index 00000000000..b87e4c6185c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FiresOfInvention.java
@@ -0,0 +1,99 @@
+package mage.cards.f;
+
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
+import mage.abilities.effects.common.continuous.CastFromHandWithoutPayingManaCostEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.filter.FilterCard;
+import mage.filter.StaticFilters;
+import mage.filter.predicate.ObjectSourcePlayer;
+import mage.filter.predicate.ObjectSourcePlayerPredicate;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.watchers.common.CastSpellLastTurnWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class FiresOfInvention extends CardImpl {
+
+ private static final FilterCard filter
+ = new FilterCard("spells with converted mana cost less than or equal to the number of lands you control");
+
+ static {
+ filter.add(FiresOfInventionPredicate.instance);
+ }
+
+ public FiresOfInvention(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
+
+ // You can cast spells only during your turn and you can cast no more than two spells each turn.
+ this.addAbility(new SimpleStaticAbility(new FiresOfInventionCastEffect()));
+
+ // You may cast spells with converted mana cost less than or equal to the number of lands you control without paying their mana costs.
+ this.addAbility(new SimpleStaticAbility(new CastFromHandWithoutPayingManaCostEffect(filter, false)));
+ }
+
+ private FiresOfInvention(final FiresOfInvention card) {
+ super(card);
+ }
+
+ @Override
+ public FiresOfInvention copy() {
+ return new FiresOfInvention(this);
+ }
+}
+
+enum FiresOfInventionPredicate implements ObjectSourcePlayerPredicate> {
+ instance;
+
+ @Override
+ public boolean apply(ObjectSourcePlayer input, Game game) {
+ return input.getObject().getConvertedManaCost() <=
+ game.getBattlefield().countAll(StaticFilters.FILTER_LAND, game.getControllerId(input.getSourceId()), game);
+ }
+}
+
+class FiresOfInventionCastEffect extends ContinuousRuleModifyingEffectImpl {
+
+ FiresOfInventionCastEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.Detriment);
+ staticText = "you can cast spells only during your turn and you can cast no more than two spells each turn";
+ }
+
+ private FiresOfInventionCastEffect(final FiresOfInventionCastEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public FiresOfInventionCastEffect copy() {
+ return new FiresOfInventionCastEffect(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 (!event.getPlayerId().equals(source.getControllerId())) {
+ return false;
+ }
+ CastSpellLastTurnWatcher watcher = game.getState().getWatcher(CastSpellLastTurnWatcher.class);
+ if (watcher == null) {
+ return false;
+ }
+ return watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(source.getControllerId()) > 1
+ || !game.getActivePlayerId().equals(source.getControllerId());
+ }
+
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/f/Firespout.java b/Mage.Sets/src/mage/cards/f/Firespout.java
index 42d3b97e50b..5a2f51e5894 100644
--- a/Mage.Sets/src/mage/cards/f/Firespout.java
+++ b/Mage.Sets/src/mage/cards/f/Firespout.java
@@ -1,11 +1,9 @@
package mage.cards.f;
-import java.util.UUID;
import mage.abilities.condition.common.ManaWasSpentCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.DamageAllEffect;
-import mage.abilities.effects.common.InfoEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -16,35 +14,33 @@ import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.watchers.common.ManaSpentToCastWatcher;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class Firespout extends CardImpl {
private static final FilterCreaturePermanent filter1 = new FilterCreaturePermanent("creature without flying");
private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("creature with flying");
+
static {
filter1.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
filter2.add(new AbilityPredicate(FlyingAbility.class));
}
public Firespout(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R/G}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R/G}");
// Firespout deals 3 damage to each creature without flying if {R} was spent to cast Firespout and 3 damage to each creature with flying if {G} was spent to cast it.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new DamageAllEffect(3, filter1),
- new ManaWasSpentCondition(ColoredManaSymbol.R), "{this} deals 3 damage to each creature without flying if {R} was spent to cast {this}"));
+ new ManaWasSpentCondition(ColoredManaSymbol.R), "{this} deals 3 damage to each creature without flying if {R} was spent to cast this spell"));
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new DamageAllEffect(3, filter2),
- new ManaWasSpentCondition(ColoredManaSymbol.G), " And 3 damage to each creature with flying if {G} was spent to cast it"));
- this.getSpellAbility().addEffect(new InfoEffect("(Do both if {R}{G} was spent.)"));
+ new ManaWasSpentCondition(ColoredManaSymbol.G), "and 3 damage to each creature with flying if {G} was spent to cast it. (Do both if {R}{G} was spent.)"));
this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher());
-
-
-
}
public Firespout(final Firespout card) {
diff --git a/Mage.Sets/src/mage/cards/f/FlameWave.java b/Mage.Sets/src/mage/cards/f/FlameWave.java
index abfd025d4d6..13739510a8e 100644
--- a/Mage.Sets/src/mage/cards/f/FlameWave.java
+++ b/Mage.Sets/src/mage/cards/f/FlameWave.java
@@ -19,7 +19,7 @@ public final class FlameWave extends CardImpl {
public FlameWave(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}{R}{R}{R}");
- // Flame Wave deals 4 damage to target player and each creature he or she controls.
+ // Flame Wave deals 4 damage to target player and each creature they control.
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
this.getSpellAbility().addEffect(new DamageAllControlledTargetEffect(4, new FilterCreaturePermanent())
diff --git a/Mage.Sets/src/mage/cards/f/Flash.java b/Mage.Sets/src/mage/cards/f/Flash.java
index 5e4bba759d2..7d0628f1f7e 100644
--- a/Mage.Sets/src/mage/cards/f/Flash.java
+++ b/Mage.Sets/src/mage/cards/f/Flash.java
@@ -1,4 +1,3 @@
-
package mage.cards.f;
import java.util.UUID;
@@ -12,7 +11,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -67,7 +66,7 @@ class FlashEffect extends OneShotEffect {
return false;
}
- TargetCardInHand target = new TargetCardInHand(new FilterCreatureCard());
+ TargetCardInHand target = new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE);
if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
diff --git a/Mage.Sets/src/mage/cards/f/FlashConscription.java b/Mage.Sets/src/mage/cards/f/FlashConscription.java
index 4e2ac4a41a3..ec60a4b850d 100644
--- a/Mage.Sets/src/mage/cards/f/FlashConscription.java
+++ b/Mage.Sets/src/mage/cards/f/FlashConscription.java
@@ -38,7 +38,7 @@ public final class FlashConscription extends CardImpl {
this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
new GainAbilityTargetEffect(new FlashConscriptionTriggeredAbility(), Duration.EndOfTurn),
new ManaWasSpentCondition(ColoredManaSymbol.W),
- "If {W} was spent to cast {this}, the creature gains "
+ "If {W} was spent to cast this spell, the creature gains "
+ "\"Whenever this creature deals combat damage, you gain that much life\" until end of turn"
));
diff --git a/Mage.Sets/src/mage/cards/f/FlaxenIntruder.java b/Mage.Sets/src/mage/cards/f/FlaxenIntruder.java
new file mode 100644
index 00000000000..105e7d16c03
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FlaxenIntruder.java
@@ -0,0 +1,113 @@
+package mage.cards.f;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.DelayedTriggeredAbility;
+import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
+import mage.abilities.costs.common.SacrificeSourceCost;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DestroyTargetEffect;
+import mage.abilities.effects.common.DoIfCostPaid;
+import mage.abilities.effects.common.SendOptionUsedEventEffect;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.permanent.token.BearToken;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class FlaxenIntruder extends AdventureCard {
+
+ public FlaxenIntruder(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{G}", "Welcome Home", "{5}{G}{G}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.BERSERKER);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(2);
+
+ // Whenever Flaxen Intruder deals combat damage to a player, you may sacrifice it. When you do, destroy target artifact or enchantment.
+ this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new DoIfCostPaid(
+ new FlaxenIntruderCreateReflexiveTriggerEffect(), new SacrificeSourceCost()
+ ).setText("you may sacrifice it. When you do, destroy target artifact or enchantment."), false));
+
+ // Welcome Home
+ // Create three 2/2 green Bear creature tokens.
+ this.getSpellCard().getSpellAbility().addEffect(new CreateTokenEffect(new BearToken(), 3));
+ }
+
+ private FlaxenIntruder(final FlaxenIntruder card) {
+ super(card);
+ }
+
+ @Override
+ public FlaxenIntruder copy() {
+ return new FlaxenIntruder(this);
+ }
+}
+
+class FlaxenIntruderCreateReflexiveTriggerEffect extends OneShotEffect {
+
+ FlaxenIntruderCreateReflexiveTriggerEffect() {
+ super(Outcome.Benefit);
+ }
+
+ private FlaxenIntruderCreateReflexiveTriggerEffect(final FlaxenIntruderCreateReflexiveTriggerEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public FlaxenIntruderCreateReflexiveTriggerEffect copy() {
+ return new FlaxenIntruderCreateReflexiveTriggerEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ game.addDelayedTriggeredAbility(new FlaxenIntruderReflexiveTriggeredAbility(), source);
+ return new SendOptionUsedEventEffect().apply(game, source);
+ }
+}
+
+class FlaxenIntruderReflexiveTriggeredAbility extends DelayedTriggeredAbility {
+
+ FlaxenIntruderReflexiveTriggeredAbility() {
+ super(new DestroyTargetEffect(), Duration.OneUse, true);
+ this.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT));
+ }
+
+ private FlaxenIntruderReflexiveTriggeredAbility(final FlaxenIntruderReflexiveTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public FlaxenIntruderReflexiveTriggeredAbility copy() {
+ return new FlaxenIntruderReflexiveTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.OPTION_USED;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ return event.getPlayerId().equals(this.getControllerId())
+ && event.getSourceId().equals(this.getSourceId());
+ }
+
+ @Override
+ public String getRule() {
+ return "When you do, destroy target artifact or enchantment.";
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/f/Flay.java b/Mage.Sets/src/mage/cards/f/Flay.java
index d66b62072bc..dab5733cb01 100644
--- a/Mage.Sets/src/mage/cards/f/Flay.java
+++ b/Mage.Sets/src/mage/cards/f/Flay.java
@@ -20,10 +20,10 @@ public final class Flay extends CardImpl {
public Flay(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}");
- // Target player discards a card at random. Then that player discards another card at random unless he or she pays {1}.
+ // Target player discards a card at random. Then that player discards another card at random unless they pay {1}.
this.getSpellAbility().addEffect(new DiscardTargetEffect(1, true));
Effect effect = new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new DiscardTargetEffect(1, true), new ManaCostsImpl("{1}"));
- effect.setText("Then that player discards another card at random unless he or she pays {1}");
+ effect.setText("Then that player discards another card at random unless they pay {1}");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetPlayer());
}
diff --git a/Mage.Sets/src/mage/cards/f/FlayerOfTheHatebound.java b/Mage.Sets/src/mage/cards/f/FlayerOfTheHatebound.java
index b51a555a73a..ec1d2b26cad 100644
--- a/Mage.Sets/src/mage/cards/f/FlayerOfTheHatebound.java
+++ b/Mage.Sets/src/mage/cards/f/FlayerOfTheHatebound.java
@@ -1,7 +1,5 @@
-
package mage.cards.f;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
@@ -11,8 +9,8 @@ import mage.abilities.keyword.UndyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.EntersTheBattlefieldEvent;
@@ -22,14 +20,15 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetAnyTarget;
+import java.util.UUID;
+
/**
- *
* @author BetaSteward
*/
public final class FlayerOfTheHatebound extends CardImpl {
public FlayerOfTheHatebound(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}");
this.subtype.add(SubType.DEVIL);
this.power = new MageInt(4);
@@ -71,7 +70,8 @@ class FlayerTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
- if (((EntersTheBattlefieldEvent) event).getFromZone() == Zone.GRAVEYARD
+ if (permanent != null
+ && ((EntersTheBattlefieldEvent) event).getFromZone() == Zone.GRAVEYARD
&& permanent.isOwnedBy(controllerId)
&& permanent.isCreature()) {
Effect effect = this.getEffects().get(0);
diff --git a/Mage.Sets/src/mage/cards/f/FleshBlood.java b/Mage.Sets/src/mage/cards/f/FleshBlood.java
index 8a0945ef6d3..ba5e5ce89b2 100644
--- a/Mage.Sets/src/mage/cards/f/FleshBlood.java
+++ b/Mage.Sets/src/mage/cards/f/FleshBlood.java
@@ -1,4 +1,3 @@
-
package mage.cards.f;
import java.util.UUID;
@@ -12,7 +11,7 @@ import mage.constants.Outcome;
import mage.constants.SpellAbilityType;
import mage.constants.Zone;
import mage.counters.CounterType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -29,7 +28,7 @@ public final class FleshBlood extends SplitCard {
// Flesh
// Exile target creature card from a graveyard. Put X +1/+1 counters on target creature, where X is the power of the card you exiled.
- Target target = new TargetCardInGraveyard(new FilterCreatureCard());
+ Target target = new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE);
getLeftHalfCard().getSpellAbility().addTarget(target);
getLeftHalfCard().getSpellAbility().addTarget(new TargetCreaturePermanent());
getLeftHalfCard().getSpellAbility().addEffect(new FleshEffect());
diff --git a/Mage.Sets/src/mage/cards/f/FloodedWoodlands.java b/Mage.Sets/src/mage/cards/f/FloodedWoodlands.java
index ace7861dc13..cccc4f38ef4 100644
--- a/Mage.Sets/src/mage/cards/f/FloodedWoodlands.java
+++ b/Mage.Sets/src/mage/cards/f/FloodedWoodlands.java
@@ -29,7 +29,7 @@ public final class FloodedWoodlands extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{B}");
- // Green creatures can't attack unless their controller sacrifices a land for each green creature he or she controls that's attacking.
+ // Green creatures can't attack unless their controller sacrifices a land for each green creature they control that's attacking.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new FloodedWoodlandsCostToAttackBlockEffect()));
}
diff --git a/Mage.Sets/src/mage/cards/f/Fluctuator.java b/Mage.Sets/src/mage/cards/f/Fluctuator.java
index 7554bb482b8..c0a1e52d08d 100644
--- a/Mage.Sets/src/mage/cards/f/Fluctuator.java
+++ b/Mage.Sets/src/mage/cards/f/Fluctuator.java
@@ -1,4 +1,3 @@
-
package mage.cards.f;
import java.util.LinkedHashSet;
@@ -6,7 +5,6 @@ import java.util.Set;
import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
-import mage.abilities.ActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.abilities.keyword.CyclingAbility;
@@ -70,9 +68,8 @@ class FluctuatorEffect extends CostModificationEffectImpl {
reduceMax = 2;
}
if (reduceMax > 0) {
- int reduce = 0;
- if (abilityToModify.getAbilityType() == AbilityType.ACTIVATED
- && ((ActivatedAbility) abilityToModify).isCheckPlayableMode()) {
+ int reduce;
+ if (game.inCheckPlayableState()) {
reduce = reduceMax;
} else {
ChoiceImpl choice = new ChoiceImpl(true);
diff --git a/Mage.Sets/src/mage/cards/f/Flutterfox.java b/Mage.Sets/src/mage/cards/f/Flutterfox.java
new file mode 100644
index 00000000000..aaf6b55a8f2
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/Flutterfox.java
@@ -0,0 +1,57 @@
+package mage.cards.f;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.decorator.ConditionalContinuousEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterArtifactOrEnchantmentPermanent;
+import mage.filter.predicate.permanent.ControllerPredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class Flutterfox extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterArtifactOrEnchantmentPermanent();
+
+ static {
+ filter.add(new ControllerPredicate(TargetController.YOU));
+ }
+
+ private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter);
+
+ public Flutterfox(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
+
+ this.subtype.add(SubType.FOX);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // As long as you control an artifact or enchantment, Flutterfox has flying.
+ this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
+ new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield),
+ condition, "As long as you control an artifact or enchantment, {this} has flying."
+ )));
+ }
+
+ private Flutterfox(final Flutterfox card) {
+ super(card);
+ }
+
+ @Override
+ public Flutterfox copy() {
+ return new Flutterfox(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FoldIntoAether.java b/Mage.Sets/src/mage/cards/f/FoldIntoAether.java
index bd6f476ca23..bff45dca282 100644
--- a/Mage.Sets/src/mage/cards/f/FoldIntoAether.java
+++ b/Mage.Sets/src/mage/cards/f/FoldIntoAether.java
@@ -1,4 +1,3 @@
-
package mage.cards.f;
import java.util.UUID;
@@ -10,7 +9,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.stack.StackObject;
import mage.players.Player;
@@ -24,7 +23,7 @@ import mage.target.common.TargetCardInHand;
public final class FoldIntoAether extends CardImpl {
public FoldIntoAether(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{U}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{U}");
// Counter target spell. If that spell is countered this way, its controller may put a creature card from their hand onto the battlefield.
this.getSpellAbility().addEffect(new FoldIntoAetherEffect());
@@ -66,7 +65,7 @@ class FoldIntoAetherEffect extends OneShotEffect {
spellController = game.getPlayer(stackObject.getControllerId());
}
if (game.getStack().counter(targetId, source.getSourceId(), game)) {
- TargetCardInHand target = new TargetCardInHand(new FilterCreatureCard());
+ TargetCardInHand target = new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE);
if (spellController != null
&& target.canChoose(source.getSourceId(), spellController.getId(), game)
&& spellController.chooseUse(Outcome.Neutral, "Put a creature card from your hand in play?", source, game)
diff --git a/Mage.Sets/src/mage/cards/f/FolioOfFancies.java b/Mage.Sets/src/mage/cards/f/FolioOfFancies.java
new file mode 100644
index 00000000000..191fe2c06d0
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FolioOfFancies.java
@@ -0,0 +1,95 @@
+package mage.cards.f;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.dynamicvalue.common.ManacostVariableValue;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DrawCardAllEffect;
+import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.players.Player;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * @author TheElk801
+ */
+public final class FolioOfFancies extends CardImpl {
+
+ public FolioOfFancies(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{U}");
+
+ // Players have no maximum hand size.
+ this.addAbility(new SimpleStaticAbility(new MaximumHandSizeControllerEffect(
+ Integer.MAX_VALUE, Duration.WhileOnBattlefield,
+ MaximumHandSizeControllerEffect.HandSizeModification.SET, TargetController.ANY
+ )));
+
+ // {X}{X}, {T}: Each player draws X cards.
+ Ability ability = new SimpleActivatedAbility(
+ new DrawCardAllEffect(ManacostVariableValue.instance), new ManaCostsImpl("{X}{X}")
+ );
+ ability.addCost(new TapSourceCost());
+ this.addAbility(ability);
+
+ // {2}{U}, {T}: Each opponent puts a number of cards equal to the number of cards in their hand from the top of their library into their graveyard.
+ ability = new SimpleActivatedAbility(new FolioOfFanciesEffect(), new ManaCostsImpl("{2}{U}"));
+ ability.addCost(new TapSourceCost());
+ this.addAbility(ability);
+ }
+
+ private FolioOfFancies(final FolioOfFancies card) {
+ super(card);
+ }
+
+ @Override
+ public FolioOfFancies copy() {
+ return new FolioOfFancies(this);
+ }
+}
+
+class FolioOfFanciesEffect extends OneShotEffect {
+
+ FolioOfFanciesEffect() {
+ super(Outcome.Benefit);
+ staticText = "Each opponent puts a number of cards equal to the number of cards in their hand " +
+ "from the top of their library into their graveyard.";
+ }
+
+ private FolioOfFanciesEffect(final FolioOfFanciesEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public FolioOfFanciesEffect copy() {
+ return new FolioOfFanciesEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) {
+ return false;
+ }
+ Set cards = game.getOpponents(source.getControllerId())
+ .stream()
+ .map(game::getPlayer)
+ .filter(Objects::nonNull)
+ .filter(player -> !player.getHand().isEmpty())
+ .map(player -> player.getLibrary().getTopCards(game, player.getHand().size()))
+ .flatMap(Collection::stream)
+ .collect(Collectors.toSet());
+ return controller.moveCards(cards, Zone.GRAVEYARD, source, game);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/f/FootstepsOfTheGoryo.java b/Mage.Sets/src/mage/cards/f/FootstepsOfTheGoryo.java
index dbc5896b334..8f55ff10724 100644
--- a/Mage.Sets/src/mage/cards/f/FootstepsOfTheGoryo.java
+++ b/Mage.Sets/src/mage/cards/f/FootstepsOfTheGoryo.java
@@ -1,6 +1,6 @@
-
package mage.cards.f;
+import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
@@ -14,15 +14,13 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
import mage.target.targetpointer.FixedTarget;
-import java.util.UUID;
-
/**
*
* @author dustinconrad
@@ -30,12 +28,12 @@ import java.util.UUID;
public final class FootstepsOfTheGoryo extends CardImpl {
public FootstepsOfTheGoryo(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}");
this.subtype.add(SubType.ARCANE);
// Return target creature card from your graveyard to the battlefield. Sacrifice that creature at the beginning of the next end step.
this.getSpellAbility().addEffect(new FootstepsOfTheGoryoEffect());
- this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard()));
+ this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE));
}
public FootstepsOfTheGoryo(final FootstepsOfTheGoryo card) {
diff --git a/Mage.Sets/src/mage/cards/f/ForceOfWill.java b/Mage.Sets/src/mage/cards/f/ForceOfWill.java
index d875377dcf8..bcaee03a4f9 100644
--- a/Mage.Sets/src/mage/cards/f/ForceOfWill.java
+++ b/Mage.Sets/src/mage/cards/f/ForceOfWill.java
@@ -1,7 +1,5 @@
-
package mage.cards.f;
-import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.costs.AlternativeCostSourceAbility;
import mage.abilities.costs.common.ExileFromHandCost;
@@ -17,14 +15,15 @@ import mage.filter.predicate.mageobject.ColorPredicate;
import mage.target.TargetSpell;
import mage.target.common.TargetCardInHand;
+import java.util.UUID;
+
/**
- *
* @author Plopman
*/
public final class ForceOfWill extends CardImpl {
public ForceOfWill(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{U}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}{U}");
// You may pay 1 life and exile a blue card from your hand rather than pay Force of Will's mana cost.
FilterOwnedCard filter = new FilterOwnedCard("a blue card from your hand");
@@ -33,8 +32,8 @@ public final class ForceOfWill extends CardImpl {
AlternativeCostSourceAbility ability = new AlternativeCostSourceAbility(new PayLifeCost(1));
ability.addCost(new ExileFromHandCost(new TargetCardInHand(filter)));
- this.addAbility(ability);
-
+ this.addAbility(ability);
+
// Counter target spell.
this.getSpellAbility().addEffect(new CounterTargetEffect());
this.getSpellAbility().addTarget(new TargetSpell());
diff --git a/Mage.Sets/src/mage/cards/f/ForceTelepathy.java b/Mage.Sets/src/mage/cards/f/ForceTelepathy.java
index 44c666abf2f..51a8701616e 100644
--- a/Mage.Sets/src/mage/cards/f/ForceTelepathy.java
+++ b/Mage.Sets/src/mage/cards/f/ForceTelepathy.java
@@ -19,8 +19,8 @@ public final class ForceTelepathy extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U/B}");
- // Target player reveals his or her hand.
- this.getSpellAbility().addEffect(new RevealHandTargetEffect().setText("Target player reveals his or her hand"));
+ // Target player reveals their hand.
+ this.getSpellAbility().addEffect(new RevealHandTargetEffect().setText("Target player reveals their hand"));
this.getSpellAbility().addTarget(new TargetPlayer());
// Scry 2
diff --git a/Mage.Sets/src/mage/cards/f/ForebodingFruit.java b/Mage.Sets/src/mage/cards/f/ForebodingFruit.java
new file mode 100644
index 00000000000..14cf2f44166
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/ForebodingFruit.java
@@ -0,0 +1,46 @@
+package mage.cards.f;
+
+import mage.abilities.condition.common.AdamantCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DrawCardTargetEffect;
+import mage.abilities.effects.common.LoseLifeTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.game.permanent.token.FoodToken;
+import mage.target.TargetPlayer;
+import mage.watchers.common.ManaSpentToCastWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ForebodingFruit extends CardImpl {
+
+ public ForebodingFruit(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}");
+
+ // Target player draws two cards and loses 2 life.
+ this.getSpellAbility().addEffect(new DrawCardTargetEffect(2));
+ this.getSpellAbility().addEffect(new LoseLifeTargetEffect(2).setText("and loses 2 life"));
+ this.getSpellAbility().addTarget(new TargetPlayer());
+
+ // Adamant — If at least three black mana was spent to cast this spell, create a Food token.
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new CreateTokenEffect(new FoodToken()), AdamantCondition.BLACK, "
Adamant — " +
+ "If at least three black mana was spent to cast this spell, create a Food token."
+ ));
+ this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher());
+ }
+
+ private ForebodingFruit(final ForebodingFruit card) {
+ super(card);
+ }
+
+ @Override
+ public ForebodingFruit copy() {
+ return new ForebodingFruit(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/ForeverYoung.java b/Mage.Sets/src/mage/cards/f/ForeverYoung.java
new file mode 100644
index 00000000000..abfe7a967fe
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/ForeverYoung.java
@@ -0,0 +1,80 @@
+package mage.cards.f;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.cards.CardsImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.Target;
+import mage.target.common.TargetCardInYourGraveyard;
+
+import java.util.Collection;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * @author TheElk801
+ */
+public final class ForeverYoung extends CardImpl {
+
+ public ForeverYoung(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}");
+
+ // Put any number of target creature cards from your graveyard on top of your library.
+ this.getSpellAbility().addEffect(new ForeverYoungEffect());
+ this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(
+ 0, Integer.MAX_VALUE, StaticFilters.FILTER_CARD_CREATURES_YOUR_GRAVEYARD
+ ));
+
+ // Draw a card.
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
+ }
+
+ private ForeverYoung(final ForeverYoung card) {
+ super(card);
+ }
+
+ @Override
+ public ForeverYoung copy() {
+ return new ForeverYoung(this);
+ }
+}
+
+class ForeverYoungEffect extends OneShotEffect {
+
+ ForeverYoungEffect() {
+ super(Outcome.Benefit);
+ staticText = "Put any number of target creature cards from your graveyard on top of your library.";
+ }
+
+ private ForeverYoungEffect(final ForeverYoungEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ForeverYoungEffect copy() {
+ return new ForeverYoungEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ return player.putCardsOnTopOfLibrary(new CardsImpl(
+ source.getTargets()
+ .stream()
+ .map(Target::getTargets)
+ .flatMap(Collection::stream)
+ .map(game::getCard)
+ .collect(Collectors.toSet())
+ ), game, source, true);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/f/Forget.java b/Mage.Sets/src/mage/cards/f/Forget.java
index f5191726576..eb1030c7da0 100644
--- a/Mage.Sets/src/mage/cards/f/Forget.java
+++ b/Mage.Sets/src/mage/cards/f/Forget.java
@@ -22,7 +22,7 @@ public final class Forget extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{U}{U}");
- // Target player discards two cards, then draws as many cards as he or she discarded this way.
+ // Target player discards two cards, then draws as many cards as they discarded this way.
this.getSpellAbility().addEffect(new ForgetEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
}
@@ -41,7 +41,7 @@ class ForgetEffect extends OneShotEffect {
public ForgetEffect() {
super(Outcome.DrawCard);
- this.staticText = "Target player discards two cards, then draws as many cards as he or she discarded this way";
+ this.staticText = "Target player discards two cards, then draws as many cards as they discarded this way";
}
public ForgetEffect(final ForgetEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/f/ForkedLightning.java b/Mage.Sets/src/mage/cards/f/ForkedLightning.java
new file mode 100644
index 00000000000..0d14651ab6a
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/ForkedLightning.java
@@ -0,0 +1,35 @@
+package mage.cards.f;
+
+import java.util.UUID;
+
+import mage.abilities.effects.common.DamageMultiEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.target.Target;
+import mage.target.common.TargetCreaturePermanentAmount;
+
+/**
+ *
+ * @author TheElk801
+ */
+public final class ForkedLightning extends CardImpl {
+
+ public ForkedLightning(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}");
+
+ // Forked Lightning deals 4 damage divided as you choose among one, two, or three target creatures.
+ this.getSpellAbility().addEffect(new DamageMultiEffect(4)
+ .setText("{this} deals 4 damage divided as you choose among one, two, or three target creatures"));
+ Target target=new TargetCreaturePermanentAmount(4);target.setMaxNumberOfTargets(3);this.getSpellAbility().addTarget(target);
+ }
+
+ private ForkedLightning(final ForkedLightning card) {
+ super(card);
+ }
+
+ @Override
+ public ForkedLightning copy() {
+ return new ForkedLightning(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FortifyingProvisions.java b/Mage.Sets/src/mage/cards/f/FortifyingProvisions.java
new file mode 100644
index 00000000000..61f6c41034d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FortifyingProvisions.java
@@ -0,0 +1,38 @@
+package mage.cards.f;
+
+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.game.permanent.token.FoodToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class FortifyingProvisions extends CardImpl {
+
+ public FortifyingProvisions(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
+
+ // Creatures you control get +0/+1.
+ this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(0, 1, Duration.WhileOnBattlefield)));
+
+ // When Fortifying Provisions enters the battlefield, create a Food token.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new FoodToken())));
+ }
+
+ private FortifyingProvisions(final FortifyingProvisions card) {
+ super(card);
+ }
+
+ @Override
+ public FortifyingProvisions copy() {
+ return new FortifyingProvisions(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FortunateFew.java b/Mage.Sets/src/mage/cards/f/FortunateFew.java
index e881ac315c1..2a47202d4c6 100644
--- a/Mage.Sets/src/mage/cards/f/FortunateFew.java
+++ b/Mage.Sets/src/mage/cards/f/FortunateFew.java
@@ -29,7 +29,7 @@ public final class FortunateFew extends CardImpl {
public FortunateFew(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{W}{W}");
- // Choose a nonland permanent you don't control, then each other player chooses a nonland permanent he or she doesn't control that hasn't been chosen this way. Destroy all other nonland permanents.
+ // Choose a nonland permanent you don't control, then each other player chooses a nonland permanent they don't control that hasn't been chosen this way. Destroy all other nonland permanents.
this.getSpellAbility().addEffect(new FortunateFewEffect());
}
@@ -47,7 +47,7 @@ class FortunateFewEffect extends OneShotEffect {
public FortunateFewEffect() {
super(Outcome.DestroyPermanent);
- staticText = "Choose a nonland permanent you don't control, then each other player chooses a nonland permanent he or she doesn't control that hasn't been chosen this way. Destroy all other nonland permanents";
+ staticText = "Choose a nonland permanent you don't control, then each other player chooses a nonland permanent they don't control that hasn't been chosen this way. Destroy all other nonland permanents";
}
public FortunateFewEffect(FortunateFewEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/f/Foster.java b/Mage.Sets/src/mage/cards/f/Foster.java
index 25c43c743df..eb9d42cd26c 100644
--- a/Mage.Sets/src/mage/cards/f/Foster.java
+++ b/Mage.Sets/src/mage/cards/f/Foster.java
@@ -1,4 +1,3 @@
-
package mage.cards.f;
import java.util.UUID;
@@ -10,11 +9,8 @@ import mage.abilities.effects.common.RevealCardsFromLibraryUntilEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.TargetController;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
-import mage.filter.common.FilterCreaturePermanent;
-import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.filter.StaticFilters;
/**
*
@@ -22,19 +18,13 @@ import mage.filter.predicate.permanent.ControllerPredicate;
*/
public final class Foster extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature you control");
-
- static {
- filter.add(new ControllerPredicate(TargetController.YOU));
- }
-
public Foster(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}{G}");
// Whenever a creature you control dies, you may pay {1}. If you do, reveal cards from the top of your library until you reveal a creature card. Put that card into your hand and the rest into your graveyard.
Ability ability = new DiesCreatureTriggeredAbility(
- new DoIfCostPaid(new RevealCardsFromLibraryUntilEffect(new FilterCreatureCard(), Zone.HAND, Zone.GRAVEYARD), new GenericManaCost(1)),
- false, filter);
+ new DoIfCostPaid(new RevealCardsFromLibraryUntilEffect(StaticFilters.FILTER_CARD_CREATURE, Zone.HAND, Zone.GRAVEYARD), new GenericManaCost(1)),
+ false, StaticFilters.FILTER_CONTROLLED_A_CREATURE);
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/f/FoulmireKnight.java b/Mage.Sets/src/mage/cards/f/FoulmireKnight.java
new file mode 100644
index 00000000000..0e4756fb470
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FoulmireKnight.java
@@ -0,0 +1,44 @@
+package mage.cards.f;
+
+import mage.MageInt;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
+import mage.abilities.keyword.DeathtouchAbility;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class FoulmireKnight extends AdventureCard {
+
+ public FoulmireKnight(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.INSTANT}, "{B}", "Profane Insight", "{2}{B}");
+
+ this.subtype.add(SubType.ZOMBIE);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Deathtouch
+ this.addAbility(DeathtouchAbility.getInstance());
+
+ // Profane Insight
+ // You draw a card and you lose 1 life.
+ this.getSpellCard().getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("You draw a card and"));
+ this.getSpellCard().getSpellAbility().addEffect(new LoseLifeSourceControllerEffect(1));
+ }
+
+ private FoulmireKnight(final FoulmireKnight card) {
+ super(card);
+ }
+
+ @Override
+ public FoulmireKnight copy() {
+ return new FoulmireKnight(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FreyalisesWinds.java b/Mage.Sets/src/mage/cards/f/FreyalisesWinds.java
index 1c5b0a09220..3065e087af8 100644
--- a/Mage.Sets/src/mage/cards/f/FreyalisesWinds.java
+++ b/Mage.Sets/src/mage/cards/f/FreyalisesWinds.java
@@ -1,6 +1,5 @@
package mage.cards.f;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BecomesTappedTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@@ -9,19 +8,16 @@ import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
+import java.util.UUID;
+
/**
- *
* @author jeffwadsworth
*/
public final class FreyalisesWinds extends CardImpl {
@@ -73,8 +69,11 @@ class FreyalisesWindsReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Permanent permanentUntapping = game.getPermanent(event.getTargetId());
- permanentUntapping.removeCounters(CounterType.WIND.createInstance(), game);
- return true;
+ if (permanentUntapping != null) {
+ permanentUntapping.removeCounters(CounterType.WIND.createInstance(), game);
+ return true;
+ }
+ return false;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/f/Frogify.java b/Mage.Sets/src/mage/cards/f/Frogify.java
new file mode 100644
index 00000000000..154aca2fda5
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/Frogify.java
@@ -0,0 +1,56 @@
+package mage.cards.f;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.continuous.BecomesCreatureAttachedEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.game.permanent.token.custom.CreatureToken;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+import mage.abilities.effects.Effect;
+
+/**
+ * @author TheElk801
+ */
+public final class Frogify extends CardImpl {
+
+ public Frogify(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}");
+
+ this.subtype.add(SubType.AURA);
+
+ // Enchant creature
+ TargetPermanent auraTarget = new TargetCreaturePermanent();
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // Enchanted creature loses all abilities and is a blue Frog creature with base power and toughness 1/1.
+ Effect effect = new BecomesCreatureAttachedEffect(
+ new CreatureToken(1, 1, "", SubType.FROG).withColor("U"),
+ "Enchanted creature loses all abilities and is a blue Frog creature with base power and toughness 1/1",
+ Duration.WhileOnBattlefield, BecomesCreatureAttachedEffect.LoseType.ALL
+ );
+ effect.setOutcome(Outcome.Detriment);
+ this.addAbility(new SimpleStaticAbility(effect));
+
+ }
+
+ private Frogify(final Frogify card) {
+ super(card);
+ }
+
+ @Override
+ public Frogify copy() {
+ return new Frogify(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GOTOJAIL.java b/Mage.Sets/src/mage/cards/g/GOTOJAIL.java
index acfb52eb170..9eaf8923b56 100644
--- a/Mage.Sets/src/mage/cards/g/GOTOJAIL.java
+++ b/Mage.Sets/src/mage/cards/g/GOTOJAIL.java
@@ -48,7 +48,7 @@ public final class GOTOJAIL extends CardImpl {
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(ability);
- // At the beginning of the upkeep of the exiled card's owner, that player rolls two six-sided dice. If he or she rolls doubles, sacrifice GO TO JAIL.
+ // At the beginning of the upkeep of the exiled card's owner, that player rolls two six-sided dice. If they roll doubles, sacrifice GO TO JAIL.
this.addAbility(new GoToJailTriggeredAbility());
}
@@ -131,7 +131,7 @@ class GoToJailUpkeepEffect extends OneShotEffect {
public GoToJailUpkeepEffect() {
super(Outcome.Sacrifice);
- this.staticText = "that player rolls two six-sided dice. If he or she rolls doubles, sacrifice {this}";
+ this.staticText = "that player rolls two six-sided dice. If they roll doubles, sacrifice {this}";
}
public GoToJailUpkeepEffect(final GoToJailUpkeepEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/g/GadwickTheWizened.java b/Mage.Sets/src/mage/cards/g/GadwickTheWizened.java
new file mode 100644
index 00000000000..cfdece046c4
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GadwickTheWizened.java
@@ -0,0 +1,145 @@
+package mage.cards.g;
+
+import mage.MageInt;
+import mage.MageObjectReference;
+import mage.ObjectColor;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SpellCastControllerTriggeredAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.TapTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterPermanent;
+import mage.filter.FilterSpell;
+import mage.filter.common.FilterNonlandPermanent;
+import mage.filter.predicate.mageobject.ColorPredicate;
+import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.stack.Spell;
+import mage.target.TargetPermanent;
+import mage.watchers.Watcher;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GadwickTheWizened extends CardImpl {
+
+ private static final FilterSpell filter
+ = new FilterSpell("a blue spell");
+ private static final FilterPermanent filter2
+ = new FilterNonlandPermanent("nonland permanent an opponent controls");
+
+ static {
+ filter.add(new ColorPredicate(ObjectColor.BLUE));
+ filter2.add(new ControllerPredicate(TargetController.OPPONENT));
+ }
+
+ public GadwickTheWizened(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{X}{U}{U}{U}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.WIZARD);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // When Gadwick, the Wizened enters the battlefield, draw X cards.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(
+ new DrawCardSourceControllerEffect(GadwickTheWizenedValue.instance)
+ ), new GadwickTheWizenedWatcher());
+
+ // Whenever you cast a blue spell, tap target nonland permanent an opponent controls.
+ Ability ability = new SpellCastControllerTriggeredAbility(new TapTargetEffect(), filter, false);
+ ability.addTarget(new TargetPermanent(filter2));
+ this.addAbility(ability);
+ }
+
+ private GadwickTheWizened(final GadwickTheWizened card) {
+ super(card);
+ }
+
+ @Override
+ public GadwickTheWizened copy() {
+ return new GadwickTheWizened(this);
+ }
+}
+
+enum GadwickTheWizenedValue implements DynamicValue {
+ instance;
+
+ @Override
+ public int calculate(Game game, Ability sourceAbility, Effect effect) {
+ GadwickTheWizenedWatcher watcher = game.getState().getWatcher(GadwickTheWizenedWatcher.class);
+ if (watcher == null) {
+ return 0;
+ }
+ return watcher.getX(new MageObjectReference(sourceAbility.getSourceId(), game));
+ }
+
+ @Override
+ public DynamicValue copy() {
+ return instance;
+ }
+
+ @Override
+ public String toString() {
+ return "X";
+ }
+
+ @Override
+ public String getMessage() {
+ return "";
+ }
+}
+
+class GadwickTheWizenedWatcher extends Watcher {
+
+ private final Map xMap = new HashMap();
+
+ GadwickTheWizenedWatcher() {
+ super(WatcherScope.GAME);
+ }
+
+ private GadwickTheWizenedWatcher(final GadwickTheWizenedWatcher watcher) {
+ super(watcher);
+ this.xMap.putAll(watcher.xMap);
+ }
+
+ @Override
+ public void watch(GameEvent event, Game game) {
+ if (event.getType() != GameEvent.EventType.SPELL_CAST) {
+ return;
+ }
+ Spell spell = game.getSpellOrLKIStack(event.getTargetId());
+ if (spell == null) {
+ return;
+ }
+ xMap.put(new MageObjectReference(
+ spell.getSourceId(), spell.getZoneChangeCounter(game) + 1, game
+ ), spell.getSpellAbility().getManaCostsToPay().getX());
+ }
+
+ @Override
+ public GadwickTheWizenedWatcher copy() {
+ return new GadwickTheWizenedWatcher(this);
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ xMap.clear();
+ }
+
+ public int getX(MageObjectReference mageObjectReference) {
+ return xMap.getOrDefault(mageObjectReference, 0);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GaeasBalance.java b/Mage.Sets/src/mage/cards/g/GaeasBalance.java
new file mode 100644
index 00000000000..178cdcee8fa
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GaeasBalance.java
@@ -0,0 +1,104 @@
+package mage.cards.g;
+
+import mage.abilities.Ability;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.effects.OneShotEffect;
+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.constants.Zone;
+import mage.filter.FilterCard;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterLandCard;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.common.TargetCardInLibrary;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GaeasBalance extends CardImpl {
+
+ public GaeasBalance(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}");
+
+ // As an additional cost to cast Gaea's Balance, sacrifice five lands.
+ this.getSpellAbility().addCost(new SacrificeTargetCost(
+ new TargetControlledPermanent(5, StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)
+ ));
+
+ // Search your library for a land card of each basic land type and put them onto the battlefield. Then shuffle your library.
+ this.getSpellAbility().addEffect(new GaeasBalanceEffect());
+ }
+
+ private GaeasBalance(final GaeasBalance card) {
+ super(card);
+ }
+
+ @Override
+ public GaeasBalance copy() {
+ return new GaeasBalance(this);
+ }
+}
+
+class GaeasBalanceEffect extends OneShotEffect {
+
+ private static final FilterCard plainsFilter = new FilterLandCard("a Plains land card");
+ private static final FilterCard islandFilter = new FilterLandCard("an Island land card");
+ private static final FilterCard swampFilter = new FilterLandCard("a Swamp land card");
+ private static final FilterCard mountainFilter = new FilterLandCard("a Mountain land card");
+ private static final FilterCard forestFilter = new FilterLandCard("a Forest land card");
+
+ static {
+ plainsFilter.add(new SubtypePredicate(SubType.PLAINS));
+ islandFilter.add(new SubtypePredicate(SubType.ISLAND));
+ swampFilter.add(new SubtypePredicate(SubType.SWAMP));
+ mountainFilter.add(new SubtypePredicate(SubType.MOUNTAIN));
+ forestFilter.add(new SubtypePredicate(SubType.FOREST));
+ }
+
+ private static final List filterList = Arrays.asList(
+ plainsFilter, islandFilter, swampFilter, mountainFilter, forestFilter
+ );
+
+ GaeasBalanceEffect() {
+ super(Outcome.Benefit);
+ staticText = "Search your library for a land card of each basic land type " +
+ "and put them onto the battlefield. Then shuffle your library.";
+ }
+
+ private GaeasBalanceEffect(final GaeasBalanceEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public GaeasBalanceEffect copy() {
+ return new GaeasBalanceEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ Cards cards = new CardsImpl();
+ filterList.stream().map(TargetCardInLibrary::new).forEachOrdered(target -> {
+ player.searchLibrary(target, source, game, target.getFilter().getMessage().contains("Forest"));
+ cards.add(target.getFirstTarget());
+ });
+ player.moveCards(cards, Zone.BATTLEFIELD, source, game);
+ player.shuffleLibrary(source, game);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/g/GaeasProtector.java b/Mage.Sets/src/mage/cards/g/GaeasProtector.java
index 60e9adb41f8..4cd88df8832 100644
--- a/Mage.Sets/src/mage/cards/g/GaeasProtector.java
+++ b/Mage.Sets/src/mage/cards/g/GaeasProtector.java
@@ -5,6 +5,7 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneSourceEffect;
+import mage.abilities.effects.Effect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
diff --git a/Mage.Sets/src/mage/cards/g/GalliaOfTheEndlessDance.java b/Mage.Sets/src/mage/cards/g/GalliaOfTheEndlessDance.java
new file mode 100644
index 00000000000..2776531eafc
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GalliaOfTheEndlessDance.java
@@ -0,0 +1,63 @@
+package mage.cards.g;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.DiscardCardCost;
+import mage.abilities.effects.common.DoIfCostPaid;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.continuous.BoostControlledEffect;
+import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
+import mage.abilities.keyword.HasteAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.filter.common.FilterCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GalliaOfTheEndlessDance extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.SATYR, "");
+
+ public GalliaOfTheEndlessDance(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{G}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.SATYR);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Haste
+ this.addAbility(HasteAbility.getInstance());
+
+ // Other Satyrs you control get +1/+1 and have haste.
+ Ability ability = new SimpleStaticAbility(new BoostControlledEffect(
+ 1, 1, Duration.WhileOnBattlefield, filter, true
+ ).setText("other Satyrs you control get +1/+1"));
+ ability.addEffect(new GainAbilityControlledEffect(
+ HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter, true
+ ).setText("and have haste"));
+
+ // Whenever you attack with three or more creatures, you may discard a card at random. If you do, draw two cards.
+ this.addAbility(new AttacksWithCreaturesTriggeredAbility(new DoIfCostPaid(
+ new DrawCardSourceControllerEffect(2), new DiscardCardCost(true)
+ ), 3));
+ }
+
+ private GalliaOfTheEndlessDance(final GalliaOfTheEndlessDance card) {
+ super(card);
+ }
+
+ @Override
+ public GalliaOfTheEndlessDance copy() {
+ return new GalliaOfTheEndlessDance(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GalvanicBlast.java b/Mage.Sets/src/mage/cards/g/GalvanicBlast.java
index 6c696f13df9..5c49d145473 100644
--- a/Mage.Sets/src/mage/cards/g/GalvanicBlast.java
+++ b/Mage.Sets/src/mage/cards/g/GalvanicBlast.java
@@ -1,7 +1,5 @@
-
package mage.cards.g;
-import java.util.UUID;
import mage.abilities.condition.common.MetalcraftCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
@@ -10,13 +8,15 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetAnyTarget;
+import java.util.UUID;
+
/**
- *
* @author North
*/
public final class GalvanicBlast extends CardImpl {
- private static final String effectText = "{this} deals 2 damage to anytarget.
Metalcraft — {this} deals 4 damage to that permanent or player instead if you control three or more artifacts";
+ private static final String effectText = "{this} deals 2 damage to any target." +
+ "
Metalcraft — {this} deals 4 damage instead if you control three or more artifacts";
public GalvanicBlast(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}");
@@ -24,7 +24,10 @@ public final class GalvanicBlast extends CardImpl {
// Galvanic Blast deals 2 damage to any target.
// Metalcraft — Galvanic Blast deals 4 damage to that creature or player instead if you control three or more artifacts.
- this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new DamageTargetEffect(4), new DamageTargetEffect(2), MetalcraftCondition.instance, effectText));
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new DamageTargetEffect(4), new DamageTargetEffect(2),
+ MetalcraftCondition.instance, effectText
+ ));
this.getSpellAbility().addTarget(new TargetAnyTarget());
}
diff --git a/Mage.Sets/src/mage/cards/g/Galvanoth.java b/Mage.Sets/src/mage/cards/g/Galvanoth.java
index 51eb7fcd3a7..a17270fa6ec 100644
--- a/Mage.Sets/src/mage/cards/g/Galvanoth.java
+++ b/Mage.Sets/src/mage/cards/g/Galvanoth.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.UUID;
@@ -27,7 +26,8 @@ public final class Galvanoth extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(3);
- // At the beginning of your upkeep, you may look at the top card of your library. If it's an instant or sorcery card, you may cast it without paying its mana cost.
+ // At the beginning of your upkeep, you may look at the top card of your library.
+ // If it's an instant or sorcery card, you may cast it without paying its mana cost.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new GalvanothEffect(), TargetController.YOU, true));
}
@@ -45,7 +45,8 @@ class GalvanothEffect extends OneShotEffect {
public GalvanothEffect() {
super(Outcome.PlayForFree);
- staticText = "look at the top card of your library. If it's an instant or sorcery card, you may cast it without paying its mana cost";
+ staticText = "look at the top card of your library. If it's an instant or "
+ + "sorcery card, you may cast it without paying its mana cost";
}
public GalvanothEffect(final GalvanothEffect effect) {
@@ -61,7 +62,10 @@ class GalvanothEffect extends OneShotEffect {
controller.lookAtCards(source, null, new CardsImpl(card), game);
if (card.isInstant() || card.isSorcery()) {
if (controller.chooseUse(Outcome.PlayForFree, "Cast " + card.getName() + " without paying its mana cost?", source, game)) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
}
diff --git a/Mage.Sets/src/mage/cards/g/Gamekeeper.java b/Mage.Sets/src/mage/cards/g/Gamekeeper.java
index 9882f0b3206..d3e3ef3ab02 100644
--- a/Mage.Sets/src/mage/cards/g/Gamekeeper.java
+++ b/Mage.Sets/src/mage/cards/g/Gamekeeper.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.UUID;
@@ -13,7 +12,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -28,7 +27,7 @@ public final class Gamekeeper extends CardImpl {
this.toughness = new MageInt(2);
// When Gamekeeper dies, you may exile it. If you do, reveal cards from the top of your library until you reveal a creature card. Put that card onto the battlefield and put all other cards revealed this way into your graveyard.
- Ability ability = new DiesTriggeredAbility(new DoIfCostPaid(new RevealCardsFromLibraryUntilEffect(new FilterCreatureCard(), Zone.BATTLEFIELD, Zone.GRAVEYARD), new ExileSourceFromGraveCost(), "Exile to reveal cards from the top of your library until you reveal a creature card?"), false);
+ Ability ability = new DiesTriggeredAbility(new DoIfCostPaid(new RevealCardsFromLibraryUntilEffect(StaticFilters.FILTER_CARD_CREATURE, Zone.BATTLEFIELD, Zone.GRAVEYARD), new ExileSourceFromGraveCost(), "Exile to reveal cards from the top of your library until you reveal a creature card?"), false);
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/g/GarenbrigCarver.java b/Mage.Sets/src/mage/cards/g/GarenbrigCarver.java
new file mode 100644
index 00000000000..403e453f53e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GarenbrigCarver.java
@@ -0,0 +1,41 @@
+package mage.cards.g;
+
+import mage.MageInt;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GarenbrigCarver extends AdventureCard {
+
+ public GarenbrigCarver(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.INSTANT}, "{3}{G}", "Shield's Might", "{1}{G}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(2);
+
+ // Shield's Might
+ // Target creature gets +2/+2 until end of turn.
+ this.getSpellCard().getSpellAbility().addEffect(new BoostTargetEffect(2, 2, Duration.EndOfTurn));
+ this.getSpellCard().getSpellAbility().addTarget(new TargetCreaturePermanent());
+ }
+
+ private GarenbrigCarver(final GarenbrigCarver card) {
+ super(card);
+ }
+
+ @Override
+ public GarenbrigCarver copy() {
+ return new GarenbrigCarver(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GarenbrigPaladin.java b/Mage.Sets/src/mage/cards/g/GarenbrigPaladin.java
new file mode 100644
index 00000000000..59db6607070
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GarenbrigPaladin.java
@@ -0,0 +1,63 @@
+package mage.cards.g;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.common.SimpleEvasionAbility;
+import mage.abilities.condition.common.AdamantCondition;
+import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.PowerPredicate;
+import mage.watchers.common.ManaSpentToCastWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GarenbrigPaladin extends CardImpl {
+
+ private static final FilterCreaturePermanent filter
+ = new FilterCreaturePermanent("creatures with power 2 or less");
+
+ static {
+ filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 3));
+ }
+
+ public GarenbrigPaladin(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}");
+
+ this.subtype.add(SubType.GIANT);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(4);
+
+ // Adamant — If at least three green mana was spent to cast this spell, Garenbrig Paladin enters the battlefield with a +1/+1 counter on it.
+ this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(
+ CounterType.P1P1.createInstance()), AdamantCondition.GREEN,
+ "
Adamant — If at least three green mana was spent to cast this spell, " +
+ "{this} enters the battlefield with a +1/+1 counter on it.", ""
+ ), new ManaSpentToCastWatcher());
+
+ // Garenbrig Paladin can't be blocked by creatures with power 2 or less.
+ this.addAbility(new SimpleEvasionAbility(
+ new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield)
+ ));
+ }
+
+ private GarenbrigPaladin(final GarenbrigPaladin card) {
+ super(card);
+ }
+
+ @Override
+ public GarenbrigPaladin copy() {
+ return new GarenbrigPaladin(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GarenbrigSquire.java b/Mage.Sets/src/mage/cards/g/GarenbrigSquire.java
new file mode 100644
index 00000000000..29c9d887f34
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GarenbrigSquire.java
@@ -0,0 +1,51 @@
+package mage.cards.g;
+
+import mage.MageInt;
+import mage.abilities.common.SpellCastControllerTriggeredAbility;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.FilterSpell;
+import mage.filter.common.FilterCreatureSpell;
+import mage.filter.predicate.mageobject.AdventurePredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GarenbrigSquire extends CardImpl {
+
+ private static final FilterSpell filter
+ = new FilterCreatureSpell("a creature spell that has an Adventure");
+
+ static {
+ filter.add(AdventurePredicate.instance);
+ }
+
+ public GarenbrigSquire(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.SOLDIER);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Whenever you cast a creature spell that has an Adventure, Garenbrig Squire gets +1/+1 until end of turn.
+ this.addAbility(new SpellCastControllerTriggeredAbility(
+ new BoostSourceEffect(1, 1, Duration.EndOfTurn), filter, false
+ ));
+ }
+
+ private GarenbrigSquire(final GarenbrigSquire card) {
+ super(card);
+ }
+
+ @Override
+ public GarenbrigSquire copy() {
+ return new GarenbrigSquire(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GarrisonGriffin.java b/Mage.Sets/src/mage/cards/g/GarrisonGriffin.java
new file mode 100644
index 00000000000..5a1849faf3a
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GarrisonGriffin.java
@@ -0,0 +1,52 @@
+package mage.cards.g;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GarrisonGriffin extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledPermanent(SubType.KNIGHT);
+
+ public GarrisonGriffin(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
+
+ this.subtype.add(SubType.GRIFFIN);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Whenever Garrison Griffin attacks, target Knight you control gains flying until end of turn.
+ Ability ability = new AttacksTriggeredAbility(new GainAbilityTargetEffect(
+ FlyingAbility.getInstance(), Duration.EndOfTurn
+ ), false);
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(ability);
+ }
+
+ private GarrisonGriffin(final GarrisonGriffin card) {
+ super(card);
+ }
+
+ @Override
+ public GarrisonGriffin copy() {
+ return new GarrisonGriffin(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GarrukCursedHuntsman.java b/Mage.Sets/src/mage/cards/g/GarrukCursedHuntsman.java
new file mode 100644
index 00000000000..fbd0483c5a0
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GarrukCursedHuntsman.java
@@ -0,0 +1,54 @@
+package mage.cards.g;
+
+import mage.abilities.Ability;
+import mage.abilities.LoyaltyAbility;
+import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DestroyTargetEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.GetEmblemEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.game.command.emblems.GarrukCursedHuntsmanEmblem;
+import mage.game.permanent.token.GarrukCursedHuntsmanToken;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GarrukCursedHuntsman extends CardImpl {
+
+ public GarrukCursedHuntsman(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{B}{G}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.GARRUK);
+ this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+
+ // 0: Create two 2/2 black and green Wolf creature tokens with "When this creature dies, put a loyalty counter on each Garruk you control."
+ this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new GarrukCursedHuntsmanToken(), 2), 0));
+
+ // −3: Destroy target creature. Draw a card.
+ Ability ability = new LoyaltyAbility(new DestroyTargetEffect(), -3);
+ ability.addEffect(new DrawCardSourceControllerEffect(1).setText("Draw a card"));
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+
+ // −6: You get an emblem with "Creatures you control get +3/+3 and have trample."
+ this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new GarrukCursedHuntsmanEmblem()), -6));
+ }
+
+ private GarrukCursedHuntsman(final GarrukCursedHuntsman card) {
+ super(card);
+ }
+
+ @Override
+ public GarrukCursedHuntsman copy() {
+ return new GarrukCursedHuntsman(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GarrukTheVeilCursed.java b/Mage.Sets/src/mage/cards/g/GarrukTheVeilCursed.java
index 26c6b633b12..8a0cb276cdf 100644
--- a/Mage.Sets/src/mage/cards/g/GarrukTheVeilCursed.java
+++ b/Mage.Sets/src/mage/cards/g/GarrukTheVeilCursed.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.UUID;
@@ -19,8 +18,8 @@ import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.Zone;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledCreaturePermanent;
-import mage.filter.common.FilterCreatureCard;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
@@ -82,7 +81,7 @@ class GarrukTheVeilCursedValue implements DynamicValue {
public int calculate(Game game, Ability sourceAbility, Effect effect) {
Player player = game.getPlayer(sourceAbility.getControllerId());
if (player != null) {
- return player.getGraveyard().getCards(new FilterCreatureCard(), game).size();
+ return player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game).size();
}
return 0;
}
@@ -142,8 +141,7 @@ class GarrukTheVeilCursedEffect extends OneShotEffect {
if (sacrificed) {
// search
- FilterCreatureCard filter = new FilterCreatureCard();
- TargetCardInLibrary targetInLibrary = new TargetCardInLibrary(filter);
+ TargetCardInLibrary targetInLibrary = new TargetCardInLibrary(StaticFilters.FILTER_CARD_CREATURE);
Cards cards = new CardsImpl();
if (controller.searchLibrary(targetInLibrary, source, game)) {
for (UUID cardId : targetInLibrary.getTargets()) {
diff --git a/Mage.Sets/src/mage/cards/g/GarruksHorde.java b/Mage.Sets/src/mage/cards/g/GarruksHorde.java
index 5d1c085bbb6..7ac147eb188 100644
--- a/Mage.Sets/src/mage/cards/g/GarruksHorde.java
+++ b/Mage.Sets/src/mage/cards/g/GarruksHorde.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.UUID;
@@ -13,7 +12,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
* @author nantuko
@@ -21,7 +20,7 @@ import mage.filter.common.FilterCreatureCard;
public final class GarruksHorde extends CardImpl {
public GarruksHorde(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{G}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(7);
@@ -31,7 +30,7 @@ public final class GarruksHorde extends CardImpl {
// Play with the top card of your library revealed.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayWithTheTopCardRevealedEffect()));
// You may cast the top card of your library if it's a creature card.
- Effect effect = new PlayTheTopCardEffect(new FilterCreatureCard());
+ Effect effect = new PlayTheTopCardEffect(StaticFilters.FILTER_CARD_CREATURE);
effect.setText("You may cast the top card of your library if it's a creature card");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
}
diff --git a/Mage.Sets/src/mage/cards/g/GarzaZolPlagueQueen.java b/Mage.Sets/src/mage/cards/g/GarzaZolPlagueQueen.java
index 250468050cf..7e6971f6405 100644
--- a/Mage.Sets/src/mage/cards/g/GarzaZolPlagueQueen.java
+++ b/Mage.Sets/src/mage/cards/g/GarzaZolPlagueQueen.java
@@ -1,7 +1,5 @@
-
package mage.cards.g;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.common.DealtDamageAndDiedTriggeredAbility;
@@ -16,25 +14,26 @@ import mage.constants.SubType;
import mage.constants.SuperType;
import mage.counters.CounterType;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class GarzaZolPlagueQueen extends CardImpl {
public GarzaZolPlagueQueen(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{U}{B}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{B}{R}");
addSuperType(SuperType.LEGENDARY);
- this.subtype.add(SubType.VAMPIRE);
+ this.subtype.add(SubType.VAMPIRE, SubType.NOBLE);
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// Flying
this.addAbility(FlyingAbility.getInstance());
-
+
// Haste
this.addAbility(HasteAbility.getInstance());
-
+
// Whenever a creature dealt damage by Garza Zol, Plague Queen this turn dies, put a +1/+1 counter on Garza Zol.
this.addAbility(new DealtDamageAndDiedTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance())));
diff --git a/Mage.Sets/src/mage/cards/g/GateToTheAfterlife.java b/Mage.Sets/src/mage/cards/g/GateToTheAfterlife.java
index cd375ad4f53..b8c64ac3bd2 100644
--- a/Mage.Sets/src/mage/cards/g/GateToTheAfterlife.java
+++ b/Mage.Sets/src/mage/cards/g/GateToTheAfterlife.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.UUID;
@@ -21,7 +20,7 @@ import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterCard;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.NamePredicate;
@@ -58,7 +57,7 @@ public final class GateToTheAfterlife extends CardImpl {
// {2}, {T}, Sacrifice Gate to the Afterlife: Search your graveyard, hand, and/or library for a card named God-Pharaoh's Gift and put it onto the battlefield. If you seearch your library this way, shuffle it. Activate this ability only if there are six or more creature cards in your graveyard.
ability = new ConditionalActivatedAbility(
Zone.BATTLEFIELD, new GateToTheAfterlifeEffect(), new GenericManaCost(2),
- new CardsInControllerGraveCondition(6, new FilterCreatureCard())
+ new CardsInControllerGraveCondition(6, StaticFilters.FILTER_CARD_CREATURE)
);
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
diff --git a/Mage.Sets/src/mage/cards/g/GatherThePack.java b/Mage.Sets/src/mage/cards/g/GatherThePack.java
index 7f51389ac72..41a80002443 100644
--- a/Mage.Sets/src/mage/cards/g/GatherThePack.java
+++ b/Mage.Sets/src/mage/cards/g/GatherThePack.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.UUID;
@@ -13,6 +12,7 @@ import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.players.Player;
@@ -25,7 +25,7 @@ import mage.target.TargetCard;
public final class GatherThePack extends CardImpl {
public GatherThePack(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}");
// Reveal the top five cards of your library. You may put a creature card from among them into your hand. Put the rest into your graveyard.
// Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, put up to two creature cards from among the revealed cards into your hand instead of one.
@@ -64,7 +64,7 @@ class GatherThePackEffect extends OneShotEffect {
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
if (!cards.isEmpty()) {
controller.revealCards(sourceObject.getIdName(), cards, game);
- int creatures = cards.count(new FilterCreatureCard(), source.getSourceId(), source.getControllerId(), game);
+ int creatures = cards.count(StaticFilters.FILTER_CARD_CREATURE, source.getSourceId(), source.getControllerId(), game);
if (creatures > 0) {
int max = 1;
if (SpellMasteryCondition.instance.apply(game, source) && creatures > 1) {
diff --git a/Mage.Sets/src/mage/cards/g/GeodeGolem.java b/Mage.Sets/src/mage/cards/g/GeodeGolem.java
index 5ea4c7b7f59..01933e084a4 100644
--- a/Mage.Sets/src/mage/cards/g/GeodeGolem.java
+++ b/Mage.Sets/src/mage/cards/g/GeodeGolem.java
@@ -38,7 +38,8 @@ public final class GeodeGolem extends CardImpl {
// Trample
this.addAbility(TrampleAbility.getInstance());
- // Whenever Geode Golem deals combat damage to a player, you may cast your commander from the command zone without paying its mana cost.
+ // Whenever Geode Golem deals combat damage to a player, you may
+ // cast your commander from the command zone without paying its mana cost.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new GeodeGolemEffect(), true));
}
@@ -56,7 +57,8 @@ class GeodeGolemEffect extends OneShotEffect {
public GeodeGolemEffect() {
super(Outcome.PlayForFree);
- staticText = "you may cast your commander from the command zone without paying its mana cost";
+ staticText = "you may cast your commander from the command zone "
+ + "without paying its mana cost";
}
public GeodeGolemEffect(final GeodeGolemEffect effect) {
@@ -83,10 +85,12 @@ class GeodeGolemEffect extends OneShotEffect {
if (possibleCommanders.size() == 1) {
selectedCommanderId = possibleCommanders.iterator().next();
} else {
- TargetCard target = new TargetCard(Zone.COMMAND, new FilterCard("commander to cast without mana cost"));
+ TargetCard target = new TargetCard(Zone.COMMAND, new FilterCard(
+ "commander to cast without mana cost"));
Cards cards = new CardsImpl(possibleCommanders);
target.setNotTarget(true);
- if (controller.canRespond() && controller.choose(Outcome.Benefit, cards, target, game)) {
+ if (controller.canRespond()
+ && controller.choose(Outcome.PlayForFree, cards, target, game)) {
if (target.getFirstTarget() != null) {
selectedCommanderId = target.getFirstTarget();
}
@@ -99,7 +103,7 @@ class GeodeGolemEffect extends OneShotEffect {
}
// PAY
- // TODO: it's can be broken with commander cost reduction effect
+ // TODO: this is broken with the commander cost reduction effect
ManaCost cost = null;
CommanderPlaysCountWatcher watcher = game.getState().getWatcher(CommanderPlaysCountWatcher.class);
int castCount = watcher.getPlaysCount(commander.getId());
@@ -108,9 +112,14 @@ class GeodeGolemEffect extends OneShotEffect {
}
// CAST: as spell or as land
- if (cost == null || cost.pay(source, game, source.getSourceId(), controller.getId(), false, null)) {
+ if (cost == null
+ || cost.pay(source, game, source.getSourceId(), controller.getId(), false, null)) {
if (commander.getSpellAbility() != null) {
- return controller.cast(commander.getSpellAbility().copy(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + commander.getId(), Boolean.TRUE);
+ Boolean commanderWasCast = controller.cast(controller.chooseAbilityForCast(commander, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + commander.getId(), null);
+ return commanderWasCast;
} else {
return controller.playLand(commander, game, true);
}
diff --git a/Mage.Sets/src/mage/cards/g/GhastlyConscription.java b/Mage.Sets/src/mage/cards/g/GhastlyConscription.java
index 848d02483eb..bee1b65f554 100644
--- a/Mage.Sets/src/mage/cards/g/GhastlyConscription.java
+++ b/Mage.Sets/src/mage/cards/g/GhastlyConscription.java
@@ -1,6 +1,6 @@
-
package mage.cards.g;
+import java.util.*;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCosts;
@@ -15,13 +15,11 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
-import java.util.*;
-
/**
*
* @author LevelX2
@@ -29,7 +27,7 @@ import java.util.*;
public final class GhastlyConscription extends CardImpl {
public GhastlyConscription(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{B}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{B}{B}");
// Exile all creature cards from target player's graveyard in a face-down pile, shuffle that pile, then manifest those cards. (To manifest a card, put it onto the battlefield face down as a 2/2 creature. Turn it face up at any time for its mana cost if it's a creature card.)
this.getSpellAbility().addEffect(new GhastlyConscriptionEffect());
@@ -68,7 +66,7 @@ class GhastlyConscriptionEffect extends OneShotEffect {
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
if (controller != null && targetPlayer != null) {
List cardsToManifest = new ArrayList<>();
- for (Card card : targetPlayer.getGraveyard().getCards(new FilterCreatureCard(), game)) {
+ for (Card card : targetPlayer.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game)) {
cardsToManifest.add(card);
controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.GRAVEYARD, true);
}
diff --git a/Mage.Sets/src/mage/cards/g/GhostlyPrison.java b/Mage.Sets/src/mage/cards/g/GhostlyPrison.java
index 70c3c79b92a..95cec698bcd 100644
--- a/Mage.Sets/src/mage/cards/g/GhostlyPrison.java
+++ b/Mage.Sets/src/mage/cards/g/GhostlyPrison.java
@@ -19,7 +19,7 @@ public final class GhostlyPrison extends CardImpl {
public GhostlyPrison(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}");
- // Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you
+ // Creatures can't attack you unless their controller pays {2} for each creature they control that's attacking you
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackYouUnlessPayManaAllEffect(new ManaCostsImpl("{2}"))));
}
diff --git a/Mage.Sets/src/mage/cards/g/GhostsOfTheInnocent.java b/Mage.Sets/src/mage/cards/g/GhostsOfTheInnocent.java
index 0794ca9b82e..46c1c582f2e 100644
--- a/Mage.Sets/src/mage/cards/g/GhostsOfTheInnocent.java
+++ b/Mage.Sets/src/mage/cards/g/GhostsOfTheInnocent.java
@@ -1,7 +1,5 @@
-
package mage.cards.g;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
@@ -9,17 +7,16 @@ import mage.abilities.effects.PreventionEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
+import mage.game.events.PreventDamageEvent;
+
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class GhostsOfTheInnocent extends CardImpl {
@@ -81,7 +78,7 @@ class GhostsOfTheInnocentPreventDamageEffect extends ReplacementEffectImpl imple
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
int amount = (int) Math.ceil(event.getAmount() / 2.0);
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, event.getTargetId(), source.getSourceId(), source.getControllerId(), amount, false);
+ GameEvent preventEvent = new PreventDamageEvent(event.getTargetId(), source.getSourceId(), source.getControllerId(), amount, ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
event.setAmount(event.getAmount() - amount);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, event.getTargetId(), source.getSourceId(), source.getControllerId(), amount));
diff --git a/Mage.Sets/src/mage/cards/g/GiantKiller.java b/Mage.Sets/src/mage/cards/g/GiantKiller.java
new file mode 100644
index 00000000000..07f05204659
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GiantKiller.java
@@ -0,0 +1,62 @@
+package mage.cards.g;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DestroyTargetEffect;
+import mage.abilities.effects.common.TapTargetEffect;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.PowerPredicate;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GiantKiller extends AdventureCard {
+
+ private static final FilterPermanent filter = new FilterCreaturePermanent("creature with power 4 or greater");
+
+ static {
+ filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 3));
+ }
+
+ public GiantKiller(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.INSTANT}, "{W}", "Chop Down", "{2}{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.PEASANT);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(2);
+
+ // {1}{W}, {T}: Tap target creature.
+ Ability ability = new SimpleActivatedAbility(new TapTargetEffect(), new ManaCostsImpl("{1}{W}"));
+ ability.addCost(new TapSourceCost());
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+
+ // Chop Down
+ // Destroy target creature with power 4 or greater.
+ this.getSpellCard().getSpellAbility().addEffect(new DestroyTargetEffect());
+ this.getSpellCard().getSpellAbility().addTarget(new TargetPermanent(filter));
+ }
+
+ private GiantKiller(final GiantKiller card) {
+ super(card);
+ }
+
+ @Override
+ public GiantKiller copy() {
+ return new GiantKiller(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GiantOpportunity.java b/Mage.Sets/src/mage/cards/g/GiantOpportunity.java
new file mode 100644
index 00000000000..0baf6ebb8b3
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GiantOpportunity.java
@@ -0,0 +1,44 @@
+package mage.cards.g;
+
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DoIfCostPaid;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.common.FilterControlledPermanent;
+import mage.game.permanent.token.FoodToken;
+import mage.game.permanent.token.GiantOpportunityToken;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GiantOpportunity extends CardImpl {
+
+ private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.FOOD, "Foods");
+
+ public GiantOpportunity(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}");
+
+ // You may sacrifice two Foods. If you do, create a 7/7 green Giant creature token. Otherwise, create three Food tokens.
+ this.getSpellAbility().addEffect(new DoIfCostPaid(
+ new CreateTokenEffect(new GiantOpportunityToken()),
+ new CreateTokenEffect(new FoodToken(), 3),
+ new SacrificeTargetCost(new TargetControlledPermanent(2, filter))
+ ).setText("You may sacrifice two Foods. If you do, create a 7/7 green Giant creature token. " +
+ "Otherwise, create three Food tokens."));
+ }
+
+ private GiantOpportunity(final GiantOpportunity card) {
+ super(card);
+ }
+
+ @Override
+ public GiantOpportunity copy() {
+ return new GiantOpportunity(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GiantsSkewer.java b/Mage.Sets/src/mage/cards/g/GiantsSkewer.java
new file mode 100644
index 00000000000..1baf34e5fa2
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GiantsSkewer.java
@@ -0,0 +1,84 @@
+package mage.cards.g;
+
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.continuous.BoostEquippedEffect;
+import mage.abilities.keyword.EquipAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.events.DamagedCreatureEvent;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.token.FoodToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GiantsSkewer extends CardImpl {
+
+ public GiantsSkewer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{B}");
+
+ this.subtype.add(SubType.EQUIPMENT);
+
+ // Equipped creature gets +2/+1.
+ this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(2, 1)));
+
+ // Whenever equipped creature deals combat damage to a creature, create a Food token.
+ this.addAbility(new GiantsSkewerTriggeredAbility());
+
+ // Equip {3}
+ this.addAbility(new EquipAbility(3));
+ }
+
+ private GiantsSkewer(final GiantsSkewer card) {
+ super(card);
+ }
+
+ @Override
+ public GiantsSkewer copy() {
+ return new GiantsSkewer(this);
+ }
+}
+
+class GiantsSkewerTriggeredAbility extends TriggeredAbilityImpl {
+
+ GiantsSkewerTriggeredAbility() {
+ super(Zone.BATTLEFIELD, new CreateTokenEffect(new FoodToken()));
+ }
+
+ private GiantsSkewerTriggeredAbility(final GiantsSkewerTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public GiantsSkewerTriggeredAbility copy() {
+ return new GiantsSkewerTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.DAMAGED_CREATURE;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ if (!((DamagedCreatureEvent) event).isCombatDamage()) {
+ return false;
+ }
+ Permanent permanent = game.getPermanent(event.getSourceId());
+ return permanent != null && permanent.getAttachments().contains(this.getSourceId());
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever equipped creature deals combat damage to a creature, create a Food token.";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GideonsIntervention.java b/Mage.Sets/src/mage/cards/g/GideonsIntervention.java
index 91e539b291e..9ab17cfb9b8 100644
--- a/Mage.Sets/src/mage/cards/g/GideonsIntervention.java
+++ b/Mage.Sets/src/mage/cards/g/GideonsIntervention.java
@@ -1,7 +1,5 @@
-
package mage.cards.g;
-import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
@@ -17,12 +15,15 @@ import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
+import mage.game.events.PreventDamageEvent;
import mage.game.permanent.Permanent;
+import java.util.UUID;
+
/**
- *
* @author spjspj
*/
public final class GideonsIntervention extends CardImpl {
@@ -88,9 +89,7 @@ class GideonsInterventionCantCastEffect extends ContinuousRuleModifyingEffectImp
String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY);
if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
MageObject object = game.getObject(event.getSourceId());
- if (object != null && object.getName().equals(cardName)) {
- return true;
- }
+ return object != null && object.getName().equals(cardName);
}
return false;
}
@@ -119,7 +118,7 @@ class GideonsInterventionPreventAllDamageEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
event.setAmount(0);
diff --git a/Mage.Sets/src/mage/cards/g/GiftOfDoom.java b/Mage.Sets/src/mage/cards/g/GiftOfDoom.java
index 5b5e37858e7..1a0c125d631 100644
--- a/Mage.Sets/src/mage/cards/g/GiftOfDoom.java
+++ b/Mage.Sets/src/mage/cards/g/GiftOfDoom.java
@@ -5,7 +5,6 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.AsTurnedFaceUpEffect;
import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.EnchantAbility;
@@ -17,23 +16,33 @@ import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
-import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledPermanent;
import mage.target.common.TargetCreaturePermanent;
-
import java.util.UUID;
-
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.AttachEffect;
import static mage.constants.Outcome.Benefit;
+import mage.constants.Zone;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.target.targetadjustment.TargetAdjuster;
/**
* @author TheElk801
*/
public final class GiftOfDoom extends CardImpl {
+ private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ }
+
public GiftOfDoom(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}");
@@ -42,26 +51,30 @@ public final class GiftOfDoom extends CardImpl {
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
- this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility));
+ this.getSpellAbility().setTargetAdjuster(GiftOfDoomAdjuster.instance); // to remove the target set if Morph casting cost is paid
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Enchanted creature has deathtouch and indestructible.
- ability = new SimpleStaticAbility(new GainAbilityAttachedEffect(
+ Ability ability2 = new SimpleStaticAbility(new GainAbilityAttachedEffect(
DeathtouchAbility.getInstance(), AttachmentType.AURA
));
- ability.addEffect(new GainAbilityAttachedEffect(
+ ability2.addEffect(new GainAbilityAttachedEffect(
IndestructibleAbility.getInstance(), AttachmentType.AURA
));
- this.addAbility(ability);
+ this.addAbility(ability2);
// Morph—Sacrifice another creature.
this.addAbility(new MorphAbility(this, new SacrificeTargetCost(
- new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)
+ new TargetControlledPermanent(filter)
)));
// As Gift of Doom is turned face up, you may attach it to a creature.
- this.addAbility(new SimpleStaticAbility(new AsTurnedFaceUpEffect(new GiftOfDoomEffect(), true)));
+ Effect effect = new AsTurnedFaceUpEffect(new GiftOfDoomEffect(), true);
+ Ability ability3 = new SimpleStaticAbility(effect);
+ ability3.setWorksFaceDown(true);
+ this.addAbility(ability3);
}
private GiftOfDoom(final GiftOfDoom card) {
@@ -74,8 +87,26 @@ public final class GiftOfDoom extends CardImpl {
}
}
+enum GiftOfDoomAdjuster implements TargetAdjuster {
+ instance;
+
+ @Override
+ public void adjustTargets(Ability ability, Game game) {
+ // if the Morph casting cost is paid, clear the target of Enchant Creature
+ if (game.getState().getValue("MorphAbility" + ability.getSourceId()) == "activated") {
+ ability.getTargets().clear();
+ }
+ }
+}
+
class GiftOfDoomEffect extends OneShotEffect {
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ }
+
GiftOfDoomEffect() {
super(Benefit);
staticText = "attach it to a creature";
@@ -93,16 +124,20 @@ class GiftOfDoomEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
- Permanent permanent = game.getPermanent(source.getSourceId());
- if (player == null || permanent == null) {
+ Permanent giftOfDoom = game.getPermanent(source.getSourceId());
+ if (player == null || giftOfDoom == null) {
return false;
}
- TargetCreaturePermanent target = new TargetCreaturePermanent(0, 1);
+ TargetCreaturePermanent target = new TargetCreaturePermanent(filter);
target.setNotTarget(true);
- if (!player.choose(outcome, target, source.getSourceId(), game)) {
- return false;
+ if (player.choose(outcome, target, source.getSourceId(), game)
+ && game.getPermanent(target.getFirstTarget()) != null
+ && !game.getPermanent(target.getFirstTarget()).cantBeAttachedBy(giftOfDoom, game)) {
+ game.getState().setValue("attachTo:" + giftOfDoom.getId(), target.getFirstTarget());
+ game.getPermanent(target.getFirstTarget()).addAttachment(giftOfDoom.getId(), game);
+ return true;
}
- permanent.attachTo(target.getFirstTarget(), game);
- return true;
+ player.moveCardToGraveyardWithInfo(giftOfDoom, source.getId(), game, Zone.BATTLEFIELD); //no legal target
+ return false;
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/g/GiftsUngiven.java b/Mage.Sets/src/mage/cards/g/GiftsUngiven.java
index c99f4c54f10..ea23326f71a 100644
--- a/Mage.Sets/src/mage/cards/g/GiftsUngiven.java
+++ b/Mage.Sets/src/mage/cards/g/GiftsUngiven.java
@@ -1,7 +1,5 @@
-
package mage.cards.g;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.*;
@@ -15,14 +13,15 @@ import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetOpponent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class GiftsUngiven extends CardImpl {
public GiftsUngiven(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}");
// Search your library for up to four cards with different names and reveal them. Target opponent chooses two of those cards. Put the chosen cards into your graveyard and the rest into your hand. Then shuffle your library.
this.getSpellAbility().addEffect(new GiftsUngivenEffect());
@@ -115,7 +114,7 @@ class GiftsUngivenTarget extends TargetCardInLibrary {
}
@Override
- public boolean canTarget(UUID id, Cards cards, Game game) {
+ public boolean canTarget(UUID playerId, UUID id, Ability source, Cards cards, Game game) {
Card card = cards.get(id, game);
if (card != null) {
for (UUID targetId : this.getTargets()) {
@@ -124,7 +123,7 @@ class GiftsUngivenTarget extends TargetCardInLibrary {
return false;
}
}
- return filter.match(card, game);
+ return filter.match(card, playerId, game);
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/g/GildedGoose.java b/Mage.Sets/src/mage/cards/g/GildedGoose.java
new file mode 100644
index 00000000000..d45b5dafb73
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GildedGoose.java
@@ -0,0 +1,70 @@
+package mage.cards.g;
+
+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.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.abilities.mana.ActivatedManaAbilityImpl;
+import mage.abilities.mana.AnyColorManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.game.permanent.token.FoodToken;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author jmharmon
+ */
+
+public final class GildedGoose extends CardImpl {
+
+ private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Food");
+
+ static {
+ filter.add(new SubtypePredicate(SubType.FOOD));
+ }
+
+ public GildedGoose(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}");
+ this.subtype.add(SubType.BIRD);
+
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(2);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // When Gilded Goose enters the battlefield, create a Food token. (It’s an artifact with “{2}, {T}, Sacrifice this artifact: You gain 3 life.”)
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new FoodToken()), false));
+
+ // {1}{G}, {T}: Create a Food token.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new FoodToken()), new ManaCostsImpl("{1}{G}"));
+ ability.addCost(new TapSourceCost());
+ this.addAbility(ability);
+
+ // {T}, Sacrifice a Food: Add one mana of any color.
+ ActivatedManaAbilityImpl ability1 = new AnyColorManaAbility(new TapSourceCost());
+ ability1.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter)));
+ this.addAbility(ability1);
+ }
+
+ public GildedGoose(final GildedGoose card) {
+ super(card);
+ }
+
+ @Override
+ public GildedGoose copy() {
+ return new GildedGoose(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GingerbreadCabin.java b/Mage.Sets/src/mage/cards/g/GingerbreadCabin.java
new file mode 100644
index 00000000000..a6d6295fbb6
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GingerbreadCabin.java
@@ -0,0 +1,64 @@
+package mage.cards.g;
+
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.common.EntersBattlefieldUntappedTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.TapSourceEffect;
+import mage.abilities.mana.GreenManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.game.permanent.token.FoodToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GingerbreadCabin extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterControlledPermanent(SubType.FOREST);
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ }
+
+ private static final Condition condition
+ = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.FEWER_THAN, 3);
+
+ public GingerbreadCabin(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ this.subtype.add(SubType.FOREST);
+
+ // ({T}: Add {G}.)
+ this.addAbility(new GreenManaAbility());
+
+ // Gingerbread Cabin enters the battlefield tapped unless you control three or more other Forests.
+ this.addAbility(new EntersBattlefieldAbility(
+ new ConditionalOneShotEffect(new TapSourceEffect(), condition),
+ "tapped unless you control three or more other Forests"
+ ));
+
+ // When Gingerbread Cabin enters the battlefield untapped, create a Food token.
+ this.addAbility(new EntersBattlefieldUntappedTriggeredAbility(new CreateTokenEffect(new FoodToken()), false));
+ }
+
+ private GingerbreadCabin(final GingerbreadCabin card) {
+ super(card);
+ }
+
+ @Override
+ public GingerbreadCabin copy() {
+ return new GingerbreadCabin(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/Gingerbrute.java b/Mage.Sets/src/mage/cards/g/Gingerbrute.java
new file mode 100644
index 00000000000..2d65b3cad6c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/Gingerbrute.java
@@ -0,0 +1,66 @@
+package mage.cards.g;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeSourceCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
+import mage.abilities.keyword.HasteAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.AbilityPredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class Gingerbrute extends CardImpl {
+
+ private static final FilterCreaturePermanent filter
+ = new FilterCreaturePermanent("except by creatures with haste");
+
+ static {
+ filter.add(Predicates.not(new AbilityPredicate(HasteAbility.class)));
+ }
+
+ public Gingerbrute(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}");
+
+ this.subtype.add(SubType.FOOD);
+ this.subtype.add(SubType.GOLEM);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Haste
+ this.addAbility(HasteAbility.getInstance());
+
+ // {1}: Gingerbrute can't be blocked this turn except by creatures with haste.
+ this.addAbility(new SimpleActivatedAbility(
+ new CantBeBlockedByCreaturesSourceEffect(filter, Duration.EndOfTurn), new GenericManaCost(1)
+ ));
+
+ // {2}, {T}, Sacrifice Gingerbrute: You gain 3 life.
+ Ability ability = new SimpleActivatedAbility(new GainLifeEffect(3), new GenericManaCost(2));
+ ability.addCost(new TapSourceCost());
+ ability.addCost(new SacrificeSourceCost());
+ this.addAbility(ability);
+ }
+
+ private Gingerbrute(final Gingerbrute card) {
+ super(card);
+ }
+
+ @Override
+ public Gingerbrute copy() {
+ return new Gingerbrute(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GlacialRevelation.java b/Mage.Sets/src/mage/cards/g/GlacialRevelation.java
index 1b18825a5c5..88213463011 100644
--- a/Mage.Sets/src/mage/cards/g/GlacialRevelation.java
+++ b/Mage.Sets/src/mage/cards/g/GlacialRevelation.java
@@ -16,7 +16,6 @@ import mage.filter.predicate.mageobject.SupertypePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
-import mage.target.common.TargetCardInHand;
import java.util.UUID;
@@ -73,7 +72,8 @@ class GlacialRevelationEffect extends OneShotEffect {
}
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 6));
player.revealCards(source, cards, game);
- TargetCard targetCard = new TargetCardInHand(0, Integer.MAX_VALUE, filter);
+ TargetCard targetCard = new TargetCard(0, Integer.MAX_VALUE, Zone.LIBRARY, filter);
+ targetCard.setNotTarget(true);
if (player.choose(outcome, cards, targetCard, game)) {
Cards toHand = new CardsImpl(targetCard.getTargets());
cards.removeAll(targetCard.getTargets());
diff --git a/Mage.Sets/src/mage/cards/g/GlassAsp.java b/Mage.Sets/src/mage/cards/g/GlassAsp.java
index 18b0062bc58..afef1484af2 100644
--- a/Mage.Sets/src/mage/cards/g/GlassAsp.java
+++ b/Mage.Sets/src/mage/cards/g/GlassAsp.java
@@ -25,10 +25,10 @@ public final class GlassAsp extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(1);
- // Whenever Glass Asp deals combat damage to a player, that player loses 2 life at the beginning of their next draw step unless he or she pays {2} before that step.
+ // Whenever Glass Asp deals combat damage to a player, that player loses 2 life at the beginning of their next draw step unless they pay {2} before that step.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new UnlessPaysDelayedEffect(
new ManaCostsImpl("{2}"), new LoseLifeTargetEffect(2), PhaseStep.DRAW, true,
- "that player loses 2 life at the beginning of their next draw step unless he or she pays {2} before that draw step."),
+ "that player loses 2 life at the beginning of their next draw step unless they pay {2} before that draw step."),
false, true));
}
diff --git a/Mage.Sets/src/mage/cards/g/GlassCasket.java b/Mage.Sets/src/mage/cards/g/GlassCasket.java
new file mode 100644
index 00000000000..a2267dcbb0f
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GlassCasket.java
@@ -0,0 +1,53 @@
+package mage.cards.g;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
+import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
+import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterOpponentsCreaturePermanent;
+import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GlassCasket extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterOpponentsCreaturePermanent("creature an opponent controls with converted mana cost 3 or less");
+
+ static {
+ filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 4));
+ }
+
+ public GlassCasket(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{W}");
+
+ // When Glass Casket enters the battlefield, exile target creature an opponent controls with converted mana cost 3 or less until Glass Casket leaves the battlefield.
+ Ability ability = new EntersBattlefieldTriggeredAbility(
+ new ExileUntilSourceLeavesEffect("")
+ .setText("exile target creature an opponent controls with converted mana cost 3 " +
+ "or less until {this} leaves the battlefield")
+ );
+ ability.addTarget(new TargetPermanent(filter));
+ ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
+ this.addAbility(ability);
+ }
+
+ private GlassCasket(final GlassCasket card) {
+ super(card);
+ }
+
+ @Override
+ public GlassCasket copy() {
+ return new GlassCasket(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GlobalRuin.java b/Mage.Sets/src/mage/cards/g/GlobalRuin.java
index 0f191c52182..c69fd8d5456 100644
--- a/Mage.Sets/src/mage/cards/g/GlobalRuin.java
+++ b/Mage.Sets/src/mage/cards/g/GlobalRuin.java
@@ -31,7 +31,7 @@ public final class GlobalRuin extends CardImpl {
public GlobalRuin(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{W}");
- // Each player chooses from the lands he or she controls a land of each basic land type, then sacrifices the rest.
+ // Each player chooses from the lands they control a land of each basic land type, then sacrifices the rest.
this.getSpellAbility().addEffect(new GlobalRuinDestroyLandEffect());
}
@@ -49,7 +49,7 @@ class GlobalRuinDestroyLandEffect extends OneShotEffect {
public GlobalRuinDestroyLandEffect() {
super(Outcome.DestroyPermanent);
- this.staticText = "Each player chooses from the lands he or she controls a land of each basic land type, then sacrifices the rest";
+ this.staticText = "Each player chooses from the lands they control a land of each basic land type, then sacrifices the rest";
}
public GlobalRuinDestroyLandEffect(final GlobalRuinDestroyLandEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/g/GloomSurgeon.java b/Mage.Sets/src/mage/cards/g/GloomSurgeon.java
index 6cc105ef460..cad1dd17230 100644
--- a/Mage.Sets/src/mage/cards/g/GloomSurgeon.java
+++ b/Mage.Sets/src/mage/cards/g/GloomSurgeon.java
@@ -1,30 +1,28 @@
-
package mage.cards.g;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.game.Game;
import mage.game.events.DamageCreatureEvent;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.players.Player;
+import java.util.UUID;
+
/**
* @author noxx
*/
public final class GloomSurgeon extends CardImpl {
public GloomSurgeon(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(2);
@@ -57,7 +55,7 @@ class GloomSurgeonEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int preventedDamage = event.getAmount();
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), preventedDamage));
@@ -79,9 +77,7 @@ class GloomSurgeonEffect extends ReplacementEffectImpl {
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getTargetId().equals(source.getSourceId())) {
DamageCreatureEvent damageEvent = (DamageCreatureEvent) event;
- if (damageEvent.isCombatDamage()) {
- return true;
- }
+ return damageEvent.isCombatDamage();
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/g/GluttonousTroll.java b/Mage.Sets/src/mage/cards/g/GluttonousTroll.java
new file mode 100644
index 00000000000..1e5ca339cde
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GluttonousTroll.java
@@ -0,0 +1,71 @@
+package mage.cards.g;
+
+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.common.OpponentsCount;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+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.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.game.permanent.token.FoodToken;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GluttonousTroll extends CardImpl {
+
+ private static final FilterControlledPermanent filter
+ = new FilterControlledPermanent("another nonland permanent");
+
+ static {
+ filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
+ filter.add(AnotherPredicate.instance);
+ }
+
+ public GluttonousTroll(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{G}");
+
+ this.subtype.add(SubType.TROLL);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Trample
+ this.addAbility(TrampleAbility.getInstance());
+
+ // When Gluttonous Troll enters the battlefield, create a number of Food tokens equal to the number of opponents you have.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(
+ new FoodToken(), OpponentsCount.instance
+ ).setText("create a number of Food tokens equal to the number of opponents you have")));
+
+ // {1}{G}, Sacrifice another nonland permanent: Gluttonous Troll gets +2/+2 until end of turn.
+ Ability ability = new SimpleActivatedAbility(
+ new BoostSourceEffect(2, 2, Duration.EndOfTurn), new ManaCostsImpl("{1}{G}")
+ );
+ ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter)));
+ this.addAbility(ability);
+ }
+
+ private GluttonousTroll(final GluttonousTroll card) {
+ super(card);
+ }
+
+ @Override
+ public GluttonousTroll copy() {
+ return new GluttonousTroll(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GnawToTheBone.java b/Mage.Sets/src/mage/cards/g/GnawToTheBone.java
index 2a381e8dc0c..104095026b7 100644
--- a/Mage.Sets/src/mage/cards/g/GnawToTheBone.java
+++ b/Mage.Sets/src/mage/cards/g/GnawToTheBone.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.UUID;
@@ -11,7 +10,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TimingRule;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -20,11 +19,10 @@ import mage.filter.common.FilterCreatureCard;
public final class GnawToTheBone extends CardImpl {
public GnawToTheBone(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{G}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}");
// You gain 2 life for each creature card in your graveyard.
- DynamicValue value = new CardsInControllerGraveyardCount(new FilterCreatureCard(), 2);
+ DynamicValue value = new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE, 2);
this.getSpellAbility().addEffect(new GainLifeEffect(value));
// Flashback {2}{G}
diff --git a/Mage.Sets/src/mage/cards/g/GoblinDarkDwellers.java b/Mage.Sets/src/mage/cards/g/GoblinDarkDwellers.java
index 88e02a3b8ec..c2fc8f74ee2 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinDarkDwellers.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinDarkDwellers.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.UUID;
@@ -34,7 +33,8 @@ import mage.target.targetpointer.FixedTarget;
*/
public final class GoblinDarkDwellers extends CardImpl {
- private static final FilterInstantOrSorceryCard filter = new FilterInstantOrSorceryCard("instant or sorcery card with converted mana cost 3 or less");
+ private static final FilterInstantOrSorceryCard filter
+ = new FilterInstantOrSorceryCard("instant or sorcery card with converted mana cost 3 or less");
static {
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 4));
@@ -69,8 +69,9 @@ public final class GoblinDarkDwellers extends CardImpl {
class GoblinDarkDwellersEffect extends OneShotEffect {
GoblinDarkDwellersEffect() {
- super(Outcome.Benefit);
- this.staticText = "you may cast target instant or sorcery card with converted mana cost 3 or less from your graveyard without paying its mana cost. "
+ super(Outcome.PlayForFree);
+ this.staticText = "you may cast target instant or sorcery card with "
+ + "converted mana cost 3 or less from your graveyard without paying its mana cost. "
+ "If that card would be put into your graveyard this turn, exile it instead";
}
@@ -89,8 +90,12 @@ class GoblinDarkDwellersEffect extends OneShotEffect {
if (controller != null) {
Card card = game.getCard(this.getTargetPointer().getFirst(game, source));
if (card != null) {
- if (controller.chooseUse(outcome, "Cast " + card.getLogName() + '?', source, game)) {
- if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
+ if (controller.chooseUse(Outcome.PlayForFree, "Cast " + card.getLogName() + '?', source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (cardWasCast) {
ContinuousEffect effect = new GoblinDarkDwellersReplacementEffect(card.getId());
effect.setTargetPointer(new FixedTarget(card.getId(), game.getState().getZoneChangeCounter(card.getId())));
game.addEffect(effect, source);
diff --git a/Mage.Sets/src/mage/cards/g/GoblinGame.java b/Mage.Sets/src/mage/cards/g/GoblinGame.java
index 2e7a7cc7629..e651eb5beb2 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinGame.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinGame.java
@@ -23,7 +23,7 @@ public final class GoblinGame extends CardImpl {
public GoblinGame(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{R}{R}");
- // Each player hides at least one item, then all players reveal them simultaneously. Each player loses life equal to the number of items he or she revealed. The player who revealed the fewest items then loses half their life, rounded up. If two or more players are tied for fewest, each loses half their life, rounded up.
+ // Each player hides at least one item, then all players reveal them simultaneously. Each player loses life equal to the number of items they revealed. The player who revealed the fewest items then loses half their life, rounded up. If two or more players are tied for fewest, each loses half their life, rounded up.
// Reinterpreted as: Each player secretly chooses a number greater than 0. Then those numbers are revealed. Each player loses life equal to their chosen number. The player who revealed the lowest number then loses half their life, rounded up. If two or more players are tied for lowest, each loses half their life, rounded up.
this.getSpellAbility().addEffect(new GoblinGameEffect());
@@ -43,7 +43,7 @@ class GoblinGameEffect extends OneShotEffect {
public GoblinGameEffect() {
super(Outcome.Detriment);
- this.staticText = "Each player hides at least one item, then all players reveal them simultaneously. Each player loses life equal to the number of items he or she revealed. The player who revealed the fewest items then loses half their life, rounded up. If two or more players are tied for fewest, each loses half their life, rounded up.";
+ this.staticText = "Each player hides at least one item, then all players reveal them simultaneously. Each player loses life equal to the number of items they revealed. The player who revealed the fewest items then loses half their life, rounded up. If two or more players are tied for fewest, each loses half their life, rounded up.";
}
public GoblinGameEffect(final GoblinGameEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/g/GoblinTutor.java b/Mage.Sets/src/mage/cards/g/GoblinTutor.java
index 9a65b040e36..9a01d83b644 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinTutor.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinTutor.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.UUID;
@@ -11,9 +10,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.filter.FilterCard;
-import mage.filter.common.FilterArtifactCard;
-import mage.filter.common.FilterCreatureCard;
-import mage.filter.common.FilterEnchantmentCard;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterInstantOrSorceryCard;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.game.Game;
@@ -72,19 +69,19 @@ class GoblinTutorEffect extends OneShotEffect {
int amount = controller.rollDice(game, 6);
Effect effect = null;
- // 2 - A card named Goblin Tutor
- // 3 - An enchantment card
- // 4 - An artifact card
- // 5 - A creature card
+ // 2 - A card named Goblin Tutor
+ // 3 - An enchantment card
+ // 4 - An artifact card
+ // 5 - A creature card
// 6 - An instant or sorcery card
if (amount == 2) {
effect = new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, filter), true);
} else if (amount == 3) {
- effect = new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, new FilterEnchantmentCard()), true);
+ effect = new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_ENTCHANTMENT), true);
} else if (amount == 4) {
- effect = new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, new FilterArtifactCard()), true);
+ effect = new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_ARTIFACT), true);
} else if (amount == 5) {
- effect = new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, new FilterCreatureCard()), true);
+ effect = new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_CREATURE), true);
} else if (amount == 6) {
effect = new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, new FilterInstantOrSorceryCard()), true);
}
diff --git a/Mage.Sets/src/mage/cards/g/GoblinWarCry.java b/Mage.Sets/src/mage/cards/g/GoblinWarCry.java
index 1c31bdcf43b..57cec6bf6df 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinWarCry.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinWarCry.java
@@ -27,7 +27,7 @@ public final class GoblinWarCry extends CardImpl {
public GoblinWarCry(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}");
- // Target opponent chooses a creature he or she controls. Other creatures he or she controls can't block this turn.
+ // Target opponent chooses a creature they control. Other creatures they control can't block this turn.
this.getSpellAbility().addEffect(new GoblinWarCryEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
}
@@ -46,7 +46,7 @@ class GoblinWarCryEffect extends OneShotEffect {
GoblinWarCryEffect() {
super(Outcome.Benefit);
- this.staticText = "Target opponent chooses a creature he or she controls. Other creatures he or she controls can't block this turn.";
+ this.staticText = "Target opponent chooses a creature they control. Other creatures they control can't block this turn.";
}
GoblinWarCryEffect(final GoblinWarCryEffect effect) {
@@ -73,7 +73,7 @@ class GoblinWarCryEffect extends OneShotEffect {
}
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
- game.informPlayers(player.getLogName() + " has chosen " + permanent.getLogName() + " as his only creature able to block this turn");
+ game.informPlayers(player.getLogName() + " has chosen " + permanent.getLogName() + " as their only creature able to block this turn");
}
}
game.addEffect(new GoblinWarCryRestrictionEffect(target.getFirstTarget()), source);
diff --git a/Mage.Sets/src/mage/cards/g/Godtoucher.java b/Mage.Sets/src/mage/cards/g/Godtoucher.java
index 5040f7f5197..3fcb348b950 100644
--- a/Mage.Sets/src/mage/cards/g/Godtoucher.java
+++ b/Mage.Sets/src/mage/cards/g/Godtoucher.java
@@ -1,7 +1,5 @@
-
package mage.cards.g;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -10,19 +8,18 @@ import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.PreventionEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.ComparisonType;
-import mage.constants.Duration;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.PowerPredicate;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author North
*/
public final class Godtoucher extends CardImpl {
@@ -34,7 +31,7 @@ public final class Godtoucher extends CardImpl {
}
public Godtoucher(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.subtype.add(SubType.ELF);
this.subtype.add(SubType.CLERIC);
@@ -82,7 +79,7 @@ class GodtoucherEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
event.setAmount(0);
diff --git a/Mage.Sets/src/mage/cards/g/GoldenEgg.java b/Mage.Sets/src/mage/cards/g/GoldenEgg.java
new file mode 100644
index 00000000000..55a7b8c6ad8
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GoldenEgg.java
@@ -0,0 +1,56 @@
+package mage.cards.g;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeSourceCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.mana.AnyColorManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+
+import java.util.UUID;
+
+/**
+ *
+ * @author jmharmon
+ */
+
+public final class GoldenEgg extends CardImpl {
+
+ public GoldenEgg(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
+ this.subtype.add(SubType.FOOD);
+
+ // When Golden Egg enters the battlefield, draw a card.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)));
+
+ // {1}, {T}: Sacrifice Golden Egg: Add one mana of any color.
+ Ability ability = new AnyColorManaAbility(new GenericManaCost(1));
+ ability.addCost(new TapSourceCost());
+ ability.addCost(new SacrificeSourceCost());
+ this.addAbility(ability);
+
+ // {2}, {T}, Sacrifice Golden Egg: You gain 3 life.
+ Ability ability1 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(3), new ManaCostsImpl("{2}"));
+ ability1.addCost(new TapSourceCost());
+ ability1.addCost(new SacrificeSourceCost());
+ this.addAbility(ability1);
+ }
+
+ public GoldenEgg(final GoldenEgg card) {
+ super(card);
+ }
+
+ @Override
+ public GoldenEgg copy() {
+ return new GoldenEgg(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GolgariGraveTroll.java b/Mage.Sets/src/mage/cards/g/GolgariGraveTroll.java
index 5d3083a2579..f886d07399c 100644
--- a/Mage.Sets/src/mage/cards/g/GolgariGraveTroll.java
+++ b/Mage.Sets/src/mage/cards/g/GolgariGraveTroll.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.UUID;
@@ -14,12 +13,11 @@ import mage.abilities.keyword.DredgeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType;
-import mage.filter.common.FilterCreatureCard;
-import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -31,7 +29,7 @@ import mage.players.Player;
public final class GolgariGraveTroll extends CardImpl {
public GolgariGraveTroll(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}");
this.subtype.add(SubType.TROLL);
this.subtype.add(SubType.SKELETON);
@@ -60,13 +58,6 @@ public final class GolgariGraveTroll extends CardImpl {
class GolgariGraveTrollEffect extends OneShotEffect {
- private static final FilterCreatureCard filter = new FilterCreatureCard();
-
- static {
-
- filter.add(new CardTypePredicate(CardType.CREATURE));
- }
-
public GolgariGraveTrollEffect() {
super(Outcome.BoostCreature);
}
@@ -80,7 +71,7 @@ class GolgariGraveTrollEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanentEntering(source.getSourceId());
if (permanent != null && player != null) {
- int amount = player.getGraveyard().count(filter, game);
+ int amount = player.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game);
if (amount > 0) {
permanent.addCounters(CounterType.P1P1.createInstance(amount), source, game);
}
diff --git a/Mage.Sets/src/mage/cards/g/GolosTirelessPilgrim.java b/Mage.Sets/src/mage/cards/g/GolosTirelessPilgrim.java
index cbbd4265202..1f4d3077e20 100644
--- a/Mage.Sets/src/mage/cards/g/GolosTirelessPilgrim.java
+++ b/Mage.Sets/src/mage/cards/g/GolosTirelessPilgrim.java
@@ -1,5 +1,7 @@
package mage.cards.g;
+import java.util.Set;
+import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -19,9 +21,6 @@ import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
import mage.target.targetpointer.FixedTarget;
-import java.util.Set;
-import java.util.UUID;
-
/**
* @author TheElk801
*/
@@ -61,8 +60,8 @@ class GolosTirelessPilgrimEffect extends OneShotEffect {
GolosTirelessPilgrimEffect() {
super(Outcome.Discard);
- staticText = "Exile the top three cards of your library. " +
- "You may play them this turn without paying their mana costs.";
+ staticText = "Exile the top three cards of your library. "
+ + "You may play them this turn without paying their mana costs.";
}
private GolosTirelessPilgrimEffect(final GolosTirelessPilgrimEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/g/GontiLordOfLuxury.java b/Mage.Sets/src/mage/cards/g/GontiLordOfLuxury.java
index 0755e3a2824..b4b5adf337b 100644
--- a/Mage.Sets/src/mage/cards/g/GontiLordOfLuxury.java
+++ b/Mage.Sets/src/mage/cards/g/GontiLordOfLuxury.java
@@ -1,8 +1,5 @@
package mage.cards.g;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
@@ -25,8 +22,11 @@ import mage.target.common.TargetOpponent;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class GontiLordOfLuxury extends CardImpl {
@@ -185,22 +185,18 @@ class GontiLordOfLuxurySpendAnyManaEffect extends AsThoughEffectImpl implements
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
Card theCard = game.getCard(objectId);
- if(theCard == null){
+ if (theCard == null) {
return false;
}
Card mainCard = theCard.getMainCard();
- if(mainCard == null){
+ if (mainCard == null) {
return false;
}
objectId = mainCard.getId(); // for split cards
if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget())
&& game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
- if (affectedControllerId.equals(source.getControllerId())) {
- // if the card moved from exile to spell the zone change counter is increased by 1
- if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
- return true;
- }
- }
+ // if the card moved from exile to spell the zone change counter is increased by 1 (effect must applies before and on stack, use isCheckPlayableMode?)
+ return affectedControllerId.equals(source.getControllerId());
} else if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
// object has moved zone so effect can be discarted
this.discard();
@@ -238,11 +234,11 @@ class GontiLordOfLuxuryLookEffect extends AsThoughEffectImpl {
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
Card theCard = game.getCard(objectId);
- if(theCard == null){
+ if (theCard == null) {
return false;
}
Card mainCard = theCard.getMainCard();
- if(mainCard == null){
+ if (mainCard == null) {
return false;
}
objectId = mainCard.getId(); // for split cards
diff --git a/Mage.Sets/src/mage/cards/g/GoryosVengeance.java b/Mage.Sets/src/mage/cards/g/GoryosVengeance.java
index d05257c9199..45b8fb87534 100644
--- a/Mage.Sets/src/mage/cards/g/GoryosVengeance.java
+++ b/Mage.Sets/src/mage/cards/g/GoryosVengeance.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import mage.abilities.Ability;
@@ -16,6 +15,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.SupertypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
@@ -26,19 +26,18 @@ import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class GoryosVengeance extends CardImpl {
- private static final FilterCard filter = new FilterCard("legendary creature card");
+ private static final FilterCard filter = new FilterCreatureCard("legendary creature card");
static {
filter.add(new SupertypePredicate(SuperType.LEGENDARY));
}
public GoryosVengeance(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}");
this.subtype.add(SubType.ARCANE);
// Return target legendary creature card from your graveyard to the battlefield. That creature gains haste. Exile it at the beginning of the next end step.
@@ -49,7 +48,7 @@ public final class GoryosVengeance extends CardImpl {
this.addAbility(new SpliceOntoArcaneAbility("{2}{B}"));
}
- public GoryosVengeance(final GoryosVengeance card) {
+ private GoryosVengeance(final GoryosVengeance card) {
super(card);
}
@@ -61,12 +60,12 @@ public final class GoryosVengeance extends CardImpl {
class GoryosVengeanceEffect extends OneShotEffect {
- public GoryosVengeanceEffect() {
+ GoryosVengeanceEffect() {
super(Outcome.PutCardInPlay);
this.staticText = "Return target legendary creature card from your graveyard to the battlefield. That creature gains haste. Exile it at the beginning of the next end step";
}
- public GoryosVengeanceEffect(final GoryosVengeanceEffect effect) {
+ private GoryosVengeanceEffect(final GoryosVengeanceEffect effect) {
super(effect);
}
@@ -78,27 +77,27 @@ class GoryosVengeanceEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- Card card = game.getCard(targetPointer.getFirst(game, source));
- if (card != null) {
- if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
- Permanent permanent = game.getPermanent(card.getId());
- if (permanent != null) {
- // Haste
- ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom);
- effect.setTargetPointer(new FixedTarget(permanent, game));
- game.addEffect(effect, source);
- // Exile it at end of turn
- Effect exileEffect = new ExileTargetEffect("Exile " + permanent.getName() + " at the beginning of the next end step");
- exileEffect.setTargetPointer(new FixedTarget(permanent, game));
- DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect);
- game.addDelayedTriggeredAbility(delayedAbility, source);
- return true;
-
- }
- }
- }
+ if (controller == null) {
+ return false;
}
- return false;
+ Card card = game.getCard(targetPointer.getFirst(game, source));
+ if (card == null || !controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
+ return false;
+ }
+ Permanent permanent = game.getPermanent(card.getId());
+ if (permanent == null) {
+ return false;
+ }
+ // Haste
+ ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom);
+ effect.setTargetPointer(new FixedTarget(permanent, game));
+ game.addEffect(effect, source);
+ // Exile it at end of turn
+ Effect exileEffect = new ExileTargetEffect("Exile " + permanent.getName() + " at the beginning of the next end step");
+ exileEffect.setTargetPointer(new FixedTarget(permanent, game));
+ DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect);
+ game.addDelayedTriggeredAbility(delayedAbility, source);
+ return true;
+
}
}
diff --git a/Mage.Sets/src/mage/cards/g/GraspingGiant.java b/Mage.Sets/src/mage/cards/g/GraspingGiant.java
new file mode 100644
index 00000000000..10e16726664
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GraspingGiant.java
@@ -0,0 +1,49 @@
+package mage.cards.g;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.BecomesBlockedByCreatureTriggeredAbility;
+import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
+import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
+import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GraspingGiant extends CardImpl {
+
+ public GraspingGiant(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}");
+
+ this.subtype.add(SubType.GIANT);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(7);
+
+ // Vigilance
+ this.addAbility(VigilanceAbility.getInstance());
+
+ // Whenever Grasping Giant becomes blocked by a creature, exile that creature until Grasping Giant leaves the battlefield.
+ Ability ability = new BecomesBlockedByCreatureTriggeredAbility(
+ new ExileUntilSourceLeavesEffect("")
+ .setText("exile that creature until {this} leaves the battlefield"), false
+ );
+ ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
+ this.addAbility(ability);
+ }
+
+ private GraspingGiant(final GraspingGiant card) {
+ super(card);
+ }
+
+ @Override
+ public GraspingGiant copy() {
+ return new GraspingGiant(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GraveStrength.java b/Mage.Sets/src/mage/cards/g/GraveStrength.java
index cc9108b39bc..229eef94cbb 100644
--- a/Mage.Sets/src/mage/cards/g/GraveStrength.java
+++ b/Mage.Sets/src/mage/cards/g/GraveStrength.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.UUID;
@@ -10,7 +9,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCreaturePermanent;
/**
@@ -20,14 +19,14 @@ import mage.target.common.TargetCreaturePermanent;
public final class GraveStrength extends CardImpl {
public GraveStrength(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}");
// Choose target creature. Put the top three cards of your library into your graveyard, then put a +1/+1 counter on that creature for each creature card in your graveyard.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
Effect effect = new PutTopCardOfLibraryIntoGraveControllerEffect(3);
effect.setText("Choose target creature. Put the top three cards of your library into your graveyard");
this.getSpellAbility().addEffect(effect);
- effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(0), new CardsInControllerGraveyardCount(new FilterCreatureCard()));
+ effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(0), new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE));
effect.setText(", then put a +1/+1 counter on that creature for each creature card in your graveyard");
this.getSpellAbility().addEffect(effect);
diff --git a/Mage.Sets/src/mage/cards/g/GraveUpheaval.java b/Mage.Sets/src/mage/cards/g/GraveUpheaval.java
index 94f5205e52f..f75d9f37890 100644
--- a/Mage.Sets/src/mage/cards/g/GraveUpheaval.java
+++ b/Mage.Sets/src/mage/cards/g/GraveUpheaval.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.UUID;
@@ -16,7 +15,7 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -34,7 +33,7 @@ public final class GraveUpheaval extends CardImpl {
// Put target creature card from a graveyard onto the battlefield under your control. It gains haste.
this.getSpellAbility().addEffect(new GraveUpheavalEffect());
- this.getSpellAbility().addTarget(new TargetCardInGraveyard(new FilterCreatureCard()));
+ this.getSpellAbility().addTarget(new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE));
// Basic landcycling {2}
this.addAbility(new BasicLandcyclingAbility(new ManaCostsImpl("{2}")));
diff --git a/Mage.Sets/src/mage/cards/g/GravebladeMarauder.java b/Mage.Sets/src/mage/cards/g/GravebladeMarauder.java
index 463f635dac4..1c901e6206e 100644
--- a/Mage.Sets/src/mage/cards/g/GravebladeMarauder.java
+++ b/Mage.Sets/src/mage/cards/g/GravebladeMarauder.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.UUID;
@@ -10,9 +9,9 @@ import mage.abilities.keyword.DeathtouchAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Outcome;
-import mage.filter.common.FilterCreatureCard;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
@@ -23,7 +22,7 @@ import mage.players.Player;
public final class GravebladeMarauder extends CardImpl {
public GravebladeMarauder(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(1);
@@ -67,7 +66,7 @@ class GravebladeMarauderEffect extends OneShotEffect {
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId());
if (targetPlayer != null && controller != null) {
- targetPlayer.loseLife(controller.getGraveyard().count(new FilterCreatureCard(), game), game, false);
+ targetPlayer.loseLife(controller.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game), game, false);
return true;
}
return false;
diff --git a/Mage.Sets/src/mage/cards/g/GrayMerchantOfAsphodel.java b/Mage.Sets/src/mage/cards/g/GrayMerchantOfAsphodel.java
index eac3532fb0e..c00f37401d6 100644
--- a/Mage.Sets/src/mage/cards/g/GrayMerchantOfAsphodel.java
+++ b/Mage.Sets/src/mage/cards/g/GrayMerchantOfAsphodel.java
@@ -1,7 +1,5 @@
-
package mage.cards.g;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -10,20 +8,21 @@ import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.ColoredManaSymbol;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.game.Game;
import mage.players.Player;
+import java.util.Objects;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class GrayMerchantOfAsphodel extends CardImpl {
public GrayMerchantOfAsphodel(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
this.subtype.add(SubType.ZOMBIE);
this.power = new MageInt(2);
@@ -31,11 +30,11 @@ public final class GrayMerchantOfAsphodel extends CardImpl {
// When Gray Merchant of Asphodel enters the battlefield, each opponent loses X life, where X is your devotion to black. You gain life equal to the life lost this way.
this.addAbility(new EntersBattlefieldTriggeredAbility(
- new GrayMerchantOfAsphodelEffect(),
- false));
+ new GrayMerchantOfAsphodelEffect(), false
+ ).addHint(DevotionCount.B.getHint()));
}
- public GrayMerchantOfAsphodel(final GrayMerchantOfAsphodel card) {
+ private GrayMerchantOfAsphodel(final GrayMerchantOfAsphodel card) {
super(card);
}
@@ -47,7 +46,7 @@ public final class GrayMerchantOfAsphodel extends CardImpl {
class GrayMerchantOfAsphodelEffect extends OneShotEffect {
- public GrayMerchantOfAsphodelEffect() {
+ GrayMerchantOfAsphodelEffect() {
super(Outcome.GainLife);
this.staticText = "each opponent loses X life, where X is your devotion to black. "
+ "You gain life equal to the life lost this way. "
@@ -55,7 +54,7 @@ class GrayMerchantOfAsphodelEffect extends OneShotEffect {
+ "counts towards your devotion to black.)";
}
- public GrayMerchantOfAsphodelEffect(final GrayMerchantOfAsphodelEffect effect) {
+ private GrayMerchantOfAsphodelEffect(final GrayMerchantOfAsphodelEffect effect) {
super(effect);
}
@@ -67,20 +66,20 @@ class GrayMerchantOfAsphodelEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- int totalLifeLost = 0;
- int lifeLost = new DevotionCount(ColoredManaSymbol.B).calculate(game, source, this);
- if (lifeLost > 0) {
- for (UUID playerId : game.getOpponents(source.getControllerId())) {
- Player opponent = game.getPlayer(playerId);
- if (opponent != null) {
- totalLifeLost += opponent.loseLife(lifeLost, game, false);
- }
- }
- }
- controller.gainLife(totalLifeLost, game, source);
+ if (controller == null) {
+ return false;
+ }
+ int lifeLost = DevotionCount.B.calculate(game, source, this);
+ if (lifeLost == 0) {
return true;
}
- return false;
+ int totalLifeLost = game
+ .getOpponents(source.getControllerId())
+ .stream()
+ .map(game::getPlayer)
+ .filter(Objects::nonNull)
+ .mapToInt(opponent -> opponent.loseLife(lifeLost, game, false))
+ .sum();
+ return controller.gainLife(totalLifeLost, game, source) > 0;
}
}
diff --git a/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java b/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java
index 478e2432a81..dc1fbbc254f 100644
--- a/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java
+++ b/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java
@@ -233,11 +233,12 @@ class GrenzoHavocRaiserSpendAnyManaEffect extends AsThoughEffectImpl implements
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
+ FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
return source.isControlledBy(affectedControllerId)
&& Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget())
- && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)
- && (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId))
- && game.getState().getZone(objectId) == Zone.STACK;
+ && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
+ && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/g/GrimFlowering.java b/Mage.Sets/src/mage/cards/g/GrimFlowering.java
index c8f8d46be06..236c10fe232 100644
--- a/Mage.Sets/src/mage/cards/g/GrimFlowering.java
+++ b/Mage.Sets/src/mage/cards/g/GrimFlowering.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.UUID;
@@ -7,7 +6,7 @@ import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -16,11 +15,10 @@ import mage.filter.common.FilterCreatureCard;
public final class GrimFlowering extends CardImpl {
public GrimFlowering(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{G}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{G}");
// Draw a card for each creature card in your graveyard.
- this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(new CardsInControllerGraveyardCount(new FilterCreatureCard())));
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE)));
}
public GrimFlowering(final GrimFlowering card) {
diff --git a/Mage.Sets/src/mage/cards/g/GrizzledWolverine.java b/Mage.Sets/src/mage/cards/g/GrizzledWolverine.java
new file mode 100644
index 00000000000..18712cb7dab
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GrizzledWolverine.java
@@ -0,0 +1,65 @@
+package mage.cards.g;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GrizzledWolverine extends CardImpl {
+
+ public GrizzledWolverine(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{R}");
+
+ this.subtype.add(SubType.WOLVERINE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // {R}: Grizzled Wolverine gets +2/+0 until end of turn. Activate this ability only during the declare blockers step, only if at least one creature is blocking Grizzled Wolverine, and only once each turn.
+ this.addAbility(new LimitedTimesPerTurnActivatedAbility(
+ Zone.BATTLEFIELD, new BoostSourceEffect(2, 0, Duration.EndOfTurn),
+ new ManaCostsImpl("{R}"), 1, GrizzledWolverineCondition.instance
+ ));
+ }
+
+ private GrizzledWolverine(final GrizzledWolverine card) {
+ super(card);
+ }
+
+ @Override
+ public GrizzledWolverine copy() {
+ return new GrizzledWolverine(this);
+ }
+}
+
+enum GrizzledWolverineCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ if (game.getPhase().getStep().getType() != PhaseStep.DECLARE_BLOCKERS) {
+ return false;
+ }
+ return game
+ .getCombat()
+ .getGroups()
+ .stream()
+ .anyMatch(combatGroup -> combatGroup.getAttackers().contains(source.getSourceId())
+ && !combatGroup.getBlockers().isEmpty());
+ }
+
+ @Override
+ public String toString() {
+ return "during the declare blockers step, only if at least one creature is blocking {this},";
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/g/GruesomeDiscovery.java b/Mage.Sets/src/mage/cards/g/GruesomeDiscovery.java
index 16df6e009e5..7e996c5a251 100644
--- a/Mage.Sets/src/mage/cards/g/GruesomeDiscovery.java
+++ b/Mage.Sets/src/mage/cards/g/GruesomeDiscovery.java
@@ -75,7 +75,7 @@ class GruesomeDiscoveryEffect extends OneShotEffect {
targetPlayer.revealCards("Gruesome Discovery", targetPlayer.getHand(), game);
if (targetPlayer.getHand().size() <= 2) {
- targetPlayer.discard(2, source, game);
+ targetPlayer.discard(2, false, source, game);
}
TargetCard target = new TargetCard(2, Zone.HAND, new FilterCard());
diff --git a/Mage.Sets/src/mage/cards/g/GrumgullyTheGenerous.java b/Mage.Sets/src/mage/cards/g/GrumgullyTheGenerous.java
new file mode 100644
index 00000000000..cd77305d739
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GrumgullyTheGenerous.java
@@ -0,0 +1,86 @@
+package mage.cards.g;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ReplacementEffectImpl;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.counters.CounterType;
+import mage.game.Game;
+import mage.game.events.EntersTheBattlefieldEvent;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class GrumgullyTheGenerous extends CardImpl {
+
+ public GrumgullyTheGenerous(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{G}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.GOBLIN);
+ this.subtype.add(SubType.SHAMAN);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Each other non-Human creature you controls enters the battlefield with an additional +1/+1 counter on it.
+ this.addAbility(new SimpleStaticAbility(new GrumgullyTheGenerousReplacementEffect()));
+ }
+
+ private GrumgullyTheGenerous(final GrumgullyTheGenerous card) {
+ super(card);
+ }
+
+ @Override
+ public GrumgullyTheGenerous copy() {
+ return new GrumgullyTheGenerous(this);
+ }
+}
+
+class GrumgullyTheGenerousReplacementEffect extends ReplacementEffectImpl {
+
+ GrumgullyTheGenerousReplacementEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.BoostCreature);
+ staticText = "Each other non-Human creature you controls " +
+ "enters the battlefield with an additional +1/+1 counter on it.";
+ }
+
+ private GrumgullyTheGenerousReplacementEffect(final GrumgullyTheGenerousReplacementEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget();
+ return creature != null
+ && creature.isCreature()
+ && !source.getSourceId().equals(creature.getId())
+ && creature.isControlledBy(source.getControllerId())
+ && !creature.hasSubtype(SubType.HUMAN, game);
+ }
+
+ @Override
+ public boolean replaceEvent(GameEvent event, Ability source, Game game) {
+ Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget();
+ if (creature != null) {
+ creature.addCounters(CounterType.P1P1.createInstance(), source, game, event.getAppliedEffects());
+ }
+ return false;
+ }
+
+ @Override
+ public GrumgullyTheGenerousReplacementEffect copy() {
+ return new GrumgullyTheGenerousReplacementEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GruulScrapper.java b/Mage.Sets/src/mage/cards/g/GruulScrapper.java
index e90188edbfe..591ab3071e4 100644
--- a/Mage.Sets/src/mage/cards/g/GruulScrapper.java
+++ b/Mage.Sets/src/mage/cards/g/GruulScrapper.java
@@ -31,7 +31,7 @@ public final class GruulScrapper extends CardImpl {
this.toughness = new MageInt(2);
//When Gruul Scrapper enters the battlefield, if Red was spent to cast Gruul Scrapper, it gains haste until end of turn.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new ConditionalContinuousEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.EndOfTurn), new ManaWasSpentCondition(ColoredManaSymbol.R), " if {R} was spent to cast {this}, it gains haste until end of turn")), new ManaSpentToCastWatcher());
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new ConditionalContinuousEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.EndOfTurn), new ManaWasSpentCondition(ColoredManaSymbol.R), " if {R} was spent to cast this spell, it gains haste until end of turn")), new ManaSpentToCastWatcher());
}
diff --git a/Mage.Sets/src/mage/cards/g/GuardianBeast.java b/Mage.Sets/src/mage/cards/g/GuardianBeast.java
index f7a10a65683..32885e40983 100644
--- a/Mage.Sets/src/mage/cards/g/GuardianBeast.java
+++ b/Mage.Sets/src/mage/cards/g/GuardianBeast.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.Objects;
@@ -18,6 +17,7 @@ import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterObject;
import mage.filter.FilterStackObject;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledArtifactPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
@@ -44,16 +44,20 @@ public final class GuardianBeast extends CardImpl {
}
public GuardianBeast(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(2);
this.toughness = new MageInt(4);
- // As long as Guardian Beast is untapped, noncreature artifacts you control can't be enchanted, they're indestructible, and other players can't gain control of them. This effect doesn't remove Auras already attached to those artifacts.
- Effect effect = new ConditionalContinuousEffect(new GainAbilityControlledEffect(IndestructibleAbility.getInstance(), Duration.WhileOnBattlefield, filter), new InvertCondition(SourceTappedCondition.instance), "noncreature artifacts you control can't be enchanted, they're indestructible, and other players can't gain control of them");
- GuardianBeastConditionalEffect effect2 = new GuardianBeastConditionalEffect(this.getId());
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect2));
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ // As long as Guardian Beast is untapped, noncreature artifacts you control can't be enchanted, they're indestructible, and other players can't gain control of them.
+ // This effect doesn't remove Auras already attached to those artifacts.
+ Effect effect = new ConditionalContinuousEffect(new GainAbilityControlledEffect(IndestructibleAbility.getInstance(), Duration.WhileOnBattlefield, filter),
+ new InvertCondition(SourceTappedCondition.instance),
+ "As long as Guardian Beast is untapped, noncreature artifacts you control can't be enchanted, they're indestructible");
+ Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
+ ability.addEffect(new GuardianBeastConditionalEffect(this.getId()));
+ this.addAbility(ability);
+
}
public GuardianBeast(final GuardianBeast card) {
@@ -68,16 +72,11 @@ public final class GuardianBeast extends CardImpl {
class GuardianBeastConditionalEffect extends ContinuousRuleModifyingEffectImpl {
- private static final FilterControlledArtifactPermanent filter = new FilterControlledArtifactPermanent("Noncreature artifacts");
- private UUID guardianBeastId;
-
- static {
- filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
- }
+ private final UUID guardianBeastId;
public GuardianBeastConditionalEffect(UUID guardianBeastId) {
super(Duration.WhileOnBattlefield, Outcome.Neutral);
- staticText = "Noncreature artifacts you control have they can't be enchanted, they're indestructible, and other players can't gain control of them";
+ staticText = ", and other players can't gain control of them. This effect doesn't remove Auras already attached to those artifacts";
this.guardianBeastId = guardianBeastId;
}
@@ -116,8 +115,11 @@ class GuardianBeastConditionalEffect extends ContinuousRuleModifyingEffectImpl {
}
StackObject spell = game.getStack().getStackObject(event.getSourceId());
- if (event.getType() == EventType.LOSE_CONTROL || event.getType() == EventType.ATTACH || event.getType() == EventType.TARGET && spell != null && spell.isEnchantment() && spell.hasSubtype(SubType.AURA, game)) {
- for (Permanent perm : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
+ if (event.getType() == EventType.GAIN_CONTROL
+ || ((event.getType() == EventType.ATTACH
+ || event.getType() == EventType.TARGET)
+ && spell != null && spell.isEnchantment() && spell.hasSubtype(SubType.AURA, game))) {
+ for (Permanent perm : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_ARTIFACTS_NON_CREATURE, source.getControllerId(), game)) {
if (perm != null && Objects.equals(perm.getId(), targetPermanent.getId()) && !perm.isCreature()) {
return true;
}
diff --git a/Mage.Sets/src/mage/cards/g/GuidedPassage.java b/Mage.Sets/src/mage/cards/g/GuidedPassage.java
index 0e5998cbf8d..e5b4f412639 100644
--- a/Mage.Sets/src/mage/cards/g/GuidedPassage.java
+++ b/Mage.Sets/src/mage/cards/g/GuidedPassage.java
@@ -1,4 +1,3 @@
-
package mage.cards.g;
import java.util.Set;
@@ -15,8 +14,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
-import mage.filter.common.FilterCreatureCard;
-import mage.filter.common.FilterLandCard;
+import mage.filter.StaticFilters;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
@@ -96,8 +94,8 @@ class GuidedPassageEffect extends OneShotEffect {
controller.chooseTarget(Outcome.Detriment, target, source, game);
opponent = game.getPlayer(target.getFirstTarget());
}
- TargetCard target1 = new TargetCard(1, Zone.LIBRARY, new FilterCreatureCard());
- TargetCard target2 = new TargetCard(1, Zone.LIBRARY, new FilterLandCard());
+ TargetCard target1 = new TargetCard(1, Zone.LIBRARY, StaticFilters.FILTER_CARD_CREATURE);
+ TargetCard target2 = new TargetCard(1, Zone.LIBRARY, StaticFilters.FILTER_CARD_LAND);
TargetCard target3 = new TargetCard(1, Zone.LIBRARY, new FilterCard(filter));
opponent.chooseTarget(Outcome.Detriment, cards, target1, source, game);
opponent.chooseTarget(Outcome.Detriment, cards, target2, source, game);
diff --git a/Mage.Sets/src/mage/cards/h/HappilyEverAfter.java b/Mage.Sets/src/mage/cards/h/HappilyEverAfter.java
new file mode 100644
index 00000000000..c1f1b476a15
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/h/HappilyEverAfter.java
@@ -0,0 +1,125 @@
+package mage.cards.h;
+
+import mage.ObjectColor;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.WinGameSourceControllerEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.TargetController;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class HappilyEverAfter extends CardImpl {
+
+ public HappilyEverAfter(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
+
+ // When Happily Ever After enters the battlefield, each player gains 5 life and draws a card.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new HappilyEverAfterEffect()));
+
+ // At the beginning of your upkeep, if there are five colors among permanents you control, there are six or more card types among permanents you control and/or cards in your graveyard, and your life total is greater than or equal to your starting life total, you win the game.
+ this.addAbility(new ConditionalInterveningIfTriggeredAbility(
+ new BeginningOfUpkeepTriggeredAbility(
+ new WinGameSourceControllerEffect(), TargetController.YOU, false
+ ), HappilyEverAfterCondition.instance, "At the beginning of your upkeep, " +
+ "if there are five colors among permanents you control, there are six or more card types " +
+ "among permanents you control and/or cards in your graveyard, and your life total is " +
+ "greater than or equal to your starting life total, you win the game."
+ ));
+ }
+
+ private HappilyEverAfter(final HappilyEverAfter card) {
+ super(card);
+ }
+
+ @Override
+ public HappilyEverAfter copy() {
+ return new HappilyEverAfter(this);
+ }
+}
+
+class HappilyEverAfterEffect extends OneShotEffect {
+
+ HappilyEverAfterEffect() {
+ super(Outcome.GainLife);
+ staticText = "each player gains 5 life and draws a card";
+ }
+
+ private HappilyEverAfterEffect(final HappilyEverAfterEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public HappilyEverAfterEffect copy() {
+ return new HappilyEverAfterEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ game.getState()
+ .getPlayersInRange(source.getControllerId(), game)
+ .stream()
+ .map(game::getPlayer)
+ .filter(Objects::nonNull)
+ .forEachOrdered(player -> {
+ player.gainLife(5, game, source);
+ player.drawCards(1, game);
+ });
+ return true;
+ }
+}
+
+enum HappilyEverAfterCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null || player.getLife() < game.getLife()) {
+ return false;
+ }
+ ObjectColor color = new ObjectColor("");
+ game.getBattlefield()
+ .getAllActivePermanents(source.getControllerId())
+ .stream()
+ .map(permanent -> permanent.getColor(game))
+ .forEach(color::addColor);
+ if (color.getColorCount() < 5) {
+ return false;
+ }
+ EnumSet cardTypeEnumSet = EnumSet.noneOf(CardType.class);
+ game.getBattlefield()
+ .getAllActivePermanents(source.getControllerId())
+ .stream()
+ .map(Permanent::getCardType)
+ .flatMap(Collection::stream)
+ .forEach(cardTypeEnumSet::add);
+ if (cardTypeEnumSet.size() >= 6) {
+ return true;
+ }
+ player.getGraveyard()
+ .getCards(game)
+ .stream()
+ .map(Card::getCardType)
+ .flatMap(Collection::stream)
+ .forEach(cardTypeEnumSet::add);
+ return cardTypeEnumSet.size() >= 6;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/h/HarmoniousArchon.java b/Mage.Sets/src/mage/cards/h/HarmoniousArchon.java
new file mode 100644
index 00000000000..71150b769b1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/h/HarmoniousArchon.java
@@ -0,0 +1,59 @@
+package mage.cards.h;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.continuous.SetPowerToughnessAllEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.game.permanent.token.HumanToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class HarmoniousArchon extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Archon creatures");
+
+ static {
+ filter.add(Predicates.not(new SubtypePredicate(SubType.ARCHON)));
+ }
+
+ public HarmoniousArchon(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}");
+
+ this.subtype.add(SubType.ARCHON);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(5);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Non-Archon creatures have base power and toughness 3/3.
+ this.addAbility(new SimpleStaticAbility(new SetPowerToughnessAllEffect(
+ 3, 3, Duration.WhileOnBattlefield, filter, true
+ )));
+
+ // When Harmonious Archon enters the battlefield, create two 1/1 white Human creature tokens.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new HumanToken(), 2)));
+ }
+
+ private HarmoniousArchon(final HarmoniousArchon card) {
+ super(card);
+ }
+
+ @Override
+ public HarmoniousArchon copy() {
+ return new HarmoniousArchon(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/h/HarnessTheStorm.java b/Mage.Sets/src/mage/cards/h/HarnessTheStorm.java
index d7eb201d296..1700cae76a8 100644
--- a/Mage.Sets/src/mage/cards/h/HarnessTheStorm.java
+++ b/Mage.Sets/src/mage/cards/h/HarnessTheStorm.java
@@ -1,4 +1,3 @@
-
package mage.cards.h;
import java.util.UUID;
@@ -32,9 +31,11 @@ public final class HarnessTheStorm extends CardImpl {
public HarnessTheStorm(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
- // Whenever you cast an instant or sorcery spell from your hand, you may cast target card with the same name as that spell from your graveyard.
+ // Whenever you cast an instant or sorcery spell from your hand, you may cast
+ // target card with the same name as that spell from your graveyard.
this.addAbility(new HarnessTheStormTriggeredAbility(new HarnessTheStormEffect(),
- new FilterInstantOrSorcerySpell("an instant or sorcery spell from your hand"), false), new CastFromHandWatcher());
+ new FilterInstantOrSorcerySpell("an instant or sorcery spell from your hand"),
+ false), new CastFromHandWatcher());
}
public HarnessTheStorm(final HarnessTheStorm card) {
@@ -87,7 +88,8 @@ class HarnessTheStormEffect extends OneShotEffect {
public HarnessTheStormEffect() {
super(Outcome.Benefit);
- this.staticText = "you may cast target card with the same name as that spell from your graveyard. (you still pay its costs.)";
+ this.staticText = "you may cast target card with the same name as that "
+ + "spell from your graveyard. (you still pay its costs.)";
}
public HarnessTheStormEffect(final HarnessTheStormEffect effect) {
@@ -106,8 +108,11 @@ class HarnessTheStormEffect extends OneShotEffect {
if (controller != null) {
Card card = controller.getGraveyard().get(getTargetPointer().getFirst(game, source), game);
if (card != null) {
- if (controller.chooseUse(outcome, "Cast " + card.getIdName() + " from your graveyard?", source, game)) {
- controller.cast(card.getSpellAbility(), game, false, new MageObjectReference(source.getSourceObject(game), game));
+ if (controller.chooseUse(outcome.Benefit, "Cast " + card.getIdName() + " from your graveyard?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(card, game, false),
+ game, false, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
return true;
diff --git a/Mage.Sets/src/mage/cards/h/HateMirage.java b/Mage.Sets/src/mage/cards/h/HateMirage.java
index 54c78fa2314..15ca94ff068 100644
--- a/Mage.Sets/src/mage/cards/h/HateMirage.java
+++ b/Mage.Sets/src/mage/cards/h/HateMirage.java
@@ -74,7 +74,7 @@ class HateMirageEffect extends OneShotEffect {
.flatMap(Collection::stream)
.forEach(uuid -> {
CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(
- source.getId(), null, true
+ source.getControllerId(), null, true
);
effect.setTargetPointer(new FixedTarget(uuid, game));
effect.apply(game, source);
diff --git a/Mage.Sets/src/mage/cards/h/HauntedFengraf.java b/Mage.Sets/src/mage/cards/h/HauntedFengraf.java
index 6631acd1ee5..527fa63fa86 100644
--- a/Mage.Sets/src/mage/cards/h/HauntedFengraf.java
+++ b/Mage.Sets/src/mage/cards/h/HauntedFengraf.java
@@ -1,4 +1,3 @@
-
package mage.cards.h;
import java.util.UUID;
@@ -15,7 +14,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.util.RandomUtil;
@@ -27,7 +26,7 @@ import mage.util.RandomUtil;
public final class HauntedFengraf extends CardImpl {
public HauntedFengraf(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
// {tap}: Add {C}.
this.addAbility(new ColorlessManaAbility());
@@ -68,7 +67,7 @@ class HauntedFengrafEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- Card[] cards = player.getGraveyard().getCards(new FilterCreatureCard(), game).toArray(new Card[0]);
+ Card[] cards = player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game).toArray(new Card[0]);
if (cards.length > 0) {
Card card = cards[RandomUtil.nextInt(cards.length)];
card.moveToZone(Zone.HAND, source.getSourceId(), game, true);
diff --git a/Mage.Sets/src/mage/cards/h/HauntingMisery.java b/Mage.Sets/src/mage/cards/h/HauntingMisery.java
index a6a2d25197f..e7a0726f7c9 100644
--- a/Mage.Sets/src/mage/cards/h/HauntingMisery.java
+++ b/Mage.Sets/src/mage/cards/h/HauntingMisery.java
@@ -1,4 +1,3 @@
-
package mage.cards.h;
import java.util.UUID;
@@ -8,7 +7,7 @@ import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetPlayerOrPlaneswalker;
/**
@@ -21,7 +20,7 @@ public final class HauntingMisery extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}{B}");
// As an additional cost to cast Haunting Misery, exile X creature cards from your graveyard.
- this.getSpellAbility().addCost(new ExileXFromYourGraveCost(new FilterCreatureCard()));
+ this.getSpellAbility().addCost(new ExileXFromYourGraveCost(StaticFilters.FILTER_CARD_CREATURE));
// Haunting Misery deals X damage to target player.
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
this.getSpellAbility().addEffect(new DamageTargetEffect(GetXValue.instance));
diff --git a/Mage.Sets/src/mage/cards/h/Havoc.java b/Mage.Sets/src/mage/cards/h/Havoc.java
index 705d130dfd7..c76de157d41 100644
--- a/Mage.Sets/src/mage/cards/h/Havoc.java
+++ b/Mage.Sets/src/mage/cards/h/Havoc.java
@@ -29,9 +29,9 @@ public final class Havoc extends CardImpl {
public Havoc(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}");
- // Whenever an opponent casts a white spell, he or she loses 2 life.
+ // Whenever an opponent casts a white spell, they lose 2 life.
Effect effect = new LoseLifeTargetEffect(2);
- effect.setText("he or she loses 2 life");
+ effect.setText("they lose 2 life");
this.addAbility(new SpellCastOpponentTriggeredAbility(Zone.BATTLEFIELD, effect, filter, false, SetTargetPointer.PLAYER));
}
diff --git a/Mage.Sets/src/mage/cards/h/HazeFrog.java b/Mage.Sets/src/mage/cards/h/HazeFrog.java
index 7c8cb06c7b2..27c439dfcc1 100644
--- a/Mage.Sets/src/mage/cards/h/HazeFrog.java
+++ b/Mage.Sets/src/mage/cards/h/HazeFrog.java
@@ -1,7 +1,5 @@
-
package mage.cards.h;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -10,21 +8,23 @@ import mage.abilities.keyword.FlashAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
+import mage.constants.SubType;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.game.permanent.Permanent;
+import java.util.UUID;
+
/**
- *
* @author jeffwadsworth
*/
public final class HazeFrog extends CardImpl {
public HazeFrog(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}");
this.subtype.add(SubType.FROG);
this.power = new MageInt(2);
@@ -70,7 +70,7 @@ class HazeFrogEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
Permanent permanent = game.getPermanent(event.getSourceId());
@@ -90,9 +90,7 @@ class HazeFrogEffect extends PreventionEffectImpl {
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game) && event instanceof DamageEvent) {
DamageEvent damageEvent = (DamageEvent) event;
- if (damageEvent.isCombatDamage() && !damageEvent.getSourceId().equals(source.getSourceId())) {
- return true;
- }
+ return damageEvent.isCombatDamage() && !damageEvent.getSourceId().equals(source.getSourceId());
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/h/HazoretsUndyingFury.java b/Mage.Sets/src/mage/cards/h/HazoretsUndyingFury.java
index 9c6f84ce5bc..21f2fd8efbc 100644
--- a/Mage.Sets/src/mage/cards/h/HazoretsUndyingFury.java
+++ b/Mage.Sets/src/mage/cards/h/HazoretsUndyingFury.java
@@ -1,4 +1,3 @@
-
package mage.cards.h;
import java.util.UUID;
@@ -44,7 +43,8 @@ public final class HazoretsUndyingFury extends CardImpl {
//Land you control don't untap during your next untap step.
this.getSpellAbility().addEffect(new DontUntapInControllersUntapStepAllEffect(
- Duration.UntilYourNextTurn, TargetController.YOU, new FilterControlledLandPermanent("Lands you control"))
+ Duration.UntilYourNextTurn, TargetController.YOU,
+ new FilterControlledLandPermanent("Lands you control"))
.setText("Lands you control don't untap during your next untap phase"));
}
@@ -60,7 +60,8 @@ public final class HazoretsUndyingFury extends CardImpl {
class HazoretsUndyingFuryEffect extends OneShotEffect {
- private static final FilterCard filter = new FilterCard("nonland cards with converted mana cost 5 or less");
+ private static final FilterCard filter = new FilterCard(
+ "nonland cards with converted mana cost 5 or less");
static {
filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
@@ -68,8 +69,10 @@ class HazoretsUndyingFuryEffect extends OneShotEffect {
}
public HazoretsUndyingFuryEffect() {
- super(Outcome.Benefit);
- this.staticText = "Shuffle your library, then exile the top four cards. You may cast any number of nonland cards with converted mana cost 5 or less from among them without paying their mana costs";
+ super(Outcome.PlayForFree);
+ this.staticText = "Shuffle your library, then exile the top four cards. "
+ + "You may cast any number of nonland cards with converted mana "
+ + "cost 5 or less from among them without paying their mana costs";
}
public HazoretsUndyingFuryEffect(final HazoretsUndyingFuryEffect effect) {
@@ -85,29 +88,40 @@ class HazoretsUndyingFuryEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
- if (controller != null && sourceObject != null) {
+ if (controller != null
+ && sourceObject != null) {
controller.shuffleLibrary(source, game);
// move cards from library to exile
- controller.moveCardsToExile(controller.getLibrary().getTopCards(game, 4), source, game, true, source.getSourceId(), sourceObject.getIdName());
+ controller.moveCardsToExile(controller.getLibrary().getTopCards(game, 4),
+ source, game, true, source.getSourceId(), sourceObject.getIdName());
// cast the possible cards without paying the mana
ExileZone hazoretsUndyingFuryExileZone = game.getExile().getExileZone(source.getSourceId());
Cards cardsToCast = new CardsImpl();
if (hazoretsUndyingFuryExileZone == null) {
return true;
}
- cardsToCast.addAll(hazoretsUndyingFuryExileZone.getCards(filter, source.getSourceId(), source.getControllerId(), game));
+ cardsToCast.addAll(hazoretsUndyingFuryExileZone.getCards(filter,
+ source.getSourceId(), source.getControllerId(), game));
while (!cardsToCast.isEmpty()) {
- if (!controller.chooseUse(Outcome.PlayForFree, "Cast (another) a card exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
+ if (!controller.chooseUse(Outcome.PlayForFree,
+ "Cast (another) a card exiled with "
+ + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
break;
}
- TargetCard targetCard = new TargetCard(1, Zone.EXILED, new FilterCard("nonland card to cast for free"));
+ TargetCard targetCard = new TargetCard(1, Zone.EXILED,
+ new FilterCard("nonland card to cast for free"));
if (controller.choose(Outcome.PlayForFree, cardsToCast, targetCard, game)) {
Card card = game.getCard(targetCard.getFirstTarget());
if (card != null) {
- if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (cardWasCast) {
cardsToCast.remove(card);
} else {
- game.informPlayer(controller, "You're not able to cast " + card.getIdName() + " or you canceled the casting.");
+ game.informPlayer(controller, "You're not able to cast "
+ + card.getIdName() + " or you canceled the casting.");
}
}
}
diff --git a/Mage.Sets/src/mage/cards/h/HeartOfBogardan.java b/Mage.Sets/src/mage/cards/h/HeartOfBogardan.java
index 77562d849d3..a775fabb645 100644
--- a/Mage.Sets/src/mage/cards/h/HeartOfBogardan.java
+++ b/Mage.Sets/src/mage/cards/h/HeartOfBogardan.java
@@ -33,7 +33,7 @@ public final class HeartOfBogardan extends CardImpl {
// Cumulative upkeep-Pay {2}.
this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{2}")));
- // When a player doesn't pay Heart of Bogardan's cumulative upkeep, Heart of Bogardan deals X damage to target player and each creature he or she controls, where X is twice the number of age counters on Heart of Bogardan minus 2.
+ // When a player doesn't pay Heart of Bogardan's cumulative upkeep, Heart of Bogardan deals X damage to target player and each creature they control, where X is twice the number of age counters on Heart of Bogardan minus 2.
this.addAbility(new HeartOfBogardanTriggeredAbility());
}
diff --git a/Mage.Sets/src/mage/cards/h/HeartOfLight.java b/Mage.Sets/src/mage/cards/h/HeartOfLight.java
index 394934b599b..1522a9fd0f3 100644
--- a/Mage.Sets/src/mage/cards/h/HeartOfLight.java
+++ b/Mage.Sets/src/mage/cards/h/HeartOfLight.java
@@ -1,7 +1,5 @@
-
package mage.cards.h;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.PreventionEffectImpl;
@@ -9,25 +7,24 @@ import mage.abilities.effects.common.AttachEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
* @author LevelX2
*/
public final class HeartOfLight extends CardImpl {
public HeartOfLight(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
this.subtype.add(SubType.AURA);
@@ -75,7 +72,7 @@ class HeartOfLightEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
event.setAmount(0);
@@ -89,9 +86,7 @@ class HeartOfLightEffect extends PreventionEffectImpl {
if (super.applies(event, source, game) && event instanceof DamageEvent) {
Permanent aura = game.getPermanent(source.getSourceId());
if (aura != null && aura.getAttachedTo() != null) {
- if (event.getSourceId().equals(aura.getAttachedTo()) || event.getTargetId().equals(aura.getAttachedTo())) {
- return true;
- }
+ return event.getSourceId().equals(aura.getAttachedTo()) || event.getTargetId().equals(aura.getAttachedTo());
}
}
return false;
diff --git a/Mage.Sets/src/mage/cards/h/HedonistsTrove.java b/Mage.Sets/src/mage/cards/h/HedonistsTrove.java
index 02501fcb4e2..bc2f842486a 100644
--- a/Mage.Sets/src/mage/cards/h/HedonistsTrove.java
+++ b/Mage.Sets/src/mage/cards/h/HedonistsTrove.java
@@ -163,7 +163,7 @@ class HedonistsTroveCastNonlandCardsEffect extends AsThoughEffectImpl {
if (!exileZone.contains(cardId)) {
// last checked card this turn is no longer exiled, so you can't cast another with this effect
// TODO: Handle if card was cast/removed from exile with effect from another card.
- // If so, this effect could prevent player from casting although he should be able to use it
+ // If so, this effect could prevent player from casting although they should be able to use it
return false;
}
}
diff --git a/Mage.Sets/src/mage/cards/h/HeliodGodOfTheSun.java b/Mage.Sets/src/mage/cards/h/HeliodGodOfTheSun.java
index 2765e74497d..a31c8d8c4bd 100644
--- a/Mage.Sets/src/mage/cards/h/HeliodGodOfTheSun.java
+++ b/Mage.Sets/src/mage/cards/h/HeliodGodOfTheSun.java
@@ -1,13 +1,10 @@
-
package mage.cards.h;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.DevotionCount;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
@@ -15,12 +12,16 @@ import mage.abilities.keyword.IndestructibleAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.game.permanent.token.HeliodGodOfTheSunToken;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class HeliodGodOfTheSun extends CardImpl {
@@ -37,19 +38,23 @@ public final class HeliodGodOfTheSun extends CardImpl {
this.addAbility(IndestructibleAbility.getInstance());
// As long as your devotion to white is less than five, Heliod isn't a creature.(Each {W} in the mana costs of permanents you control counts towards your devotion to white.)
- Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.W), 5);
- effect.setText("As long as your devotion to white is less than five, Heliod isn't a creature.(Each {W} in the mana costs of permanents you control counts towards your devotion to white.)");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.W, 5))
+ .addHint(DevotionCount.W.getHint()));
// Other creatures you control have vigilance.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(VigilanceAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE, true)));
+ this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
+ VigilanceAbility.getInstance(), Duration.WhileOnBattlefield,
+ StaticFilters.FILTER_PERMANENT_CREATURE, true
+ )));
// {2}{W}{W}: Create a 2/1 white Cleric enchantment creature token.
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new HeliodGodOfTheSunToken()), new ManaCostsImpl("{2}{W}{W}")));
+ this.addAbility(new SimpleActivatedAbility(
+ new CreateTokenEffect(new HeliodGodOfTheSunToken()), new ManaCostsImpl("{2}{W}{W}")
+ ));
}
- public HeliodGodOfTheSun(final HeliodGodOfTheSun card) {
+ private HeliodGodOfTheSun(final HeliodGodOfTheSun card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/h/HellcarverDemon.java b/Mage.Sets/src/mage/cards/h/HellcarverDemon.java
index 8290d30a688..5ec523596ff 100644
--- a/Mage.Sets/src/mage/cards/h/HellcarverDemon.java
+++ b/Mage.Sets/src/mage/cards/h/HellcarverDemon.java
@@ -1,4 +1,3 @@
-
package mage.cards.h;
import java.util.HashSet;
@@ -20,7 +19,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.FilterCard;
+import mage.filter.common.FilterNonlandCard;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -41,7 +40,9 @@ public final class HellcarverDemon extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
- // Whenever Hellcarver Demon deals combat damage to a player, sacrifice all other permanents you control and discard your hand. Exile the top six cards of your library. You may cast any number of nonland cards exiled this way without paying their mana costs.
+ // Whenever Hellcarver Demon deals combat damage to a player, sacrifice all other permanents you
+ // control and discard your hand. Exile the top six cards of your library. You may cast any number
+ // of nonland cards exiled this way without paying their mana costs.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new HellcarverDemonEffect(), false));
}
@@ -59,7 +60,9 @@ class HellcarverDemonEffect extends OneShotEffect {
public HellcarverDemonEffect() {
super(Outcome.PlayForFree);
- staticText = "sacrifice all other permanents you control and discard your hand. Exile the top six cards of your library. You may cast any number of nonland cards exiled this way without paying their mana costs.";
+ staticText = "sacrifice all other permanents you control and discard your hand. "
+ + "Exile the top six cards of your library. You may cast any number of "
+ + "nonland cards exiled this way without paying their mana costs.";
}
public HellcarverDemonEffect(final HellcarverDemonEffect effect) {
@@ -83,7 +86,8 @@ class HellcarverDemonEffect extends OneShotEffect {
// move cards from library to exile
Set currentExiledCards = new HashSet<>();
currentExiledCards.addAll(controller.getLibrary().getTopCards(game, 6));
- controller.moveCardsToExile(currentExiledCards, source, game, true, source.getSourceId(), sourceObject.getIdName());
+ controller.moveCardsToExile(currentExiledCards, source, game, true,
+ source.getSourceId(), sourceObject.getIdName());
// cast the possible cards without paying the mana
Cards cardsToCast = new CardsImpl();
@@ -91,18 +95,26 @@ class HellcarverDemonEffect extends OneShotEffect {
boolean alreadyCast = false;
while (!cardsToCast.isEmpty()
&& controller.canRespond()) {
- if (!controller.chooseUse(outcome, "Cast a" + (alreadyCast ? "nother" : "") + " card exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
+ if (!controller.chooseUse(outcome, "Cast a" + (alreadyCast ? "another" : "")
+ + " card exiled with " + sourceObject.getLogName()
+ + " without paying its mana cost?", source, game)) {
break;
}
- TargetCard targetCard = new TargetCard(1, Zone.EXILED, new FilterCard("nonland card to cast for free"));
+ TargetCard targetCard = new TargetCard(1, Zone.EXILED,
+ new FilterNonlandCard("nonland card to cast for free"));
if (controller.choose(Outcome.PlayForFree, cardsToCast, targetCard, game)) {
alreadyCast = true;
Card card = game.getCard(targetCard.getFirstTarget());
if (card != null) {
- if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (cardWasCast) {
cardsToCast.remove(card);
} else {
- game.informPlayer(controller, "You're not able to cast " + card.getIdName() + " or you canceled the casting.");
+ game.informPlayer(controller, "You're not able to cast "
+ + card.getIdName() + " or you canceled the casting.");
}
}
}
diff --git a/Mage.Sets/src/mage/cards/h/HellfireMongrel.java b/Mage.Sets/src/mage/cards/h/HellfireMongrel.java
index b28d4e75f6c..125442d401c 100644
--- a/Mage.Sets/src/mage/cards/h/HellfireMongrel.java
+++ b/Mage.Sets/src/mage/cards/h/HellfireMongrel.java
@@ -30,11 +30,11 @@ public final class HellfireMongrel extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- // At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, Hellfire Mongrel deals 2 damage to him or her.
+ // At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, Hellfire Mongrel deals 2 damage to that player.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), TargetController.OPPONENT, false, true),
(Condition)new CardsInHandCondition(ComparisonType.FEWER_THAN, 3, null, TargetController.ACTIVE),
- "At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, {this} deals 2 damage to him or her."
+ "At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, {this} deals 2 damage to that player."
));
}
diff --git a/Mage.Sets/src/mage/cards/h/HengeWalker.java b/Mage.Sets/src/mage/cards/h/HengeWalker.java
new file mode 100644
index 00000000000..1550201d9ce
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/h/HengeWalker.java
@@ -0,0 +1,45 @@
+package mage.cards.h;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.condition.common.AdamantCondition;
+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.watchers.common.ManaSpentToCastWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class HengeWalker extends CardImpl {
+
+ public HengeWalker(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}");
+
+ this.subtype.add(SubType.GOLEM);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Adamant — If at least three mana of the same color was spent to cast this spell, Henge Walker enters the battlefield with a +1/+1 counter on it.
+ this.addAbility(new EntersBattlefieldAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
+ AdamantCondition.ANY, "
Adamant — " +
+ "If at least three mana of the same color was spent to cast this spell, " +
+ "{this} enters the battlefield with a +1/+1 counter on it.", ""
+ ), new ManaSpentToCastWatcher());
+ }
+
+ private HengeWalker(final HengeWalker card) {
+ super(card);
+ }
+
+ @Override
+ public HengeWalker copy() {
+ return new HengeWalker(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/h/HeraldOfLeshrac.java b/Mage.Sets/src/mage/cards/h/HeraldOfLeshrac.java
index 87d221f7deb..6a5f91566ec 100644
--- a/Mage.Sets/src/mage/cards/h/HeraldOfLeshrac.java
+++ b/Mage.Sets/src/mage/cards/h/HeraldOfLeshrac.java
@@ -63,7 +63,7 @@ public final class HeraldOfLeshrac extends CardImpl {
// Herald of Leshrac gets +1/+1 for each land you control but don't own.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(new PermanentsOnBattlefieldCount(filter), new PermanentsOnBattlefieldCount(filter), Duration.WhileOnBattlefield)));
- // When Herald of Leshrac leaves the battlefield, each player gains control of each land he or she owns that you control.
+ // When Herald of Leshrac leaves the battlefield, each player gains control of each land they own that you control.
this.addAbility(new LeavesBattlefieldTriggeredAbility(new HeraldOfLeshracLeavesEffect(), false));
}
@@ -120,7 +120,7 @@ class HeraldOfLeshracLeavesEffect extends OneShotEffect {
HeraldOfLeshracLeavesEffect() {
super(Outcome.Detriment);
- this.staticText = "each player gains control of each land he or she owns that you control";
+ this.staticText = "each player gains control of each land they own that you control";
}
HeraldOfLeshracLeavesEffect(final HeraldOfLeshracLeavesEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/h/HeraldicBanner.java b/Mage.Sets/src/mage/cards/h/HeraldicBanner.java
new file mode 100644
index 00000000000..4171169e3f8
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/h/HeraldicBanner.java
@@ -0,0 +1,85 @@
+package mage.cards.h;
+
+import mage.ObjectColor;
+import mage.abilities.Ability;
+import mage.abilities.common.AsEntersBattlefieldAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.ContinuousEffectImpl;
+import mage.abilities.effects.common.ChooseColorEffect;
+import mage.abilities.effects.mana.AddManaChosenColorEffect;
+import mage.abilities.mana.SimpleManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+
+import java.util.UUID;
+
+/**
+ * @author jmharmon
+ */
+
+public final class HeraldicBanner extends CardImpl {
+
+ public HeraldicBanner(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
+
+ // As Heraldic Banner enters the battlefield, choose a color.
+ this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Benefit)));
+
+ // Creatures you control of the chosen color get +1/+0.
+ this.addAbility(new SimpleStaticAbility(new HeraldicBannerEffect()));
+
+ // {T}: Add one mana of the chosen color.
+ this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaChosenColorEffect(), new TapSourceCost()));
+ }
+
+ private HeraldicBanner(final HeraldicBanner card) {
+ super(card);
+ }
+
+ @Override
+ public HeraldicBanner copy() {
+ return new HeraldicBanner(this);
+ }
+}
+
+class HeraldicBannerEffect extends ContinuousEffectImpl {
+
+ HeraldicBannerEffect() {
+ super(Duration.WhileOnBattlefield, Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, Outcome.BoostCreature);
+ staticText = "Creatures you control of the chosen color get +1/+0";
+ }
+
+ private HeraldicBannerEffect(final HeraldicBannerEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public HeraldicBannerEffect copy() {
+ return new HeraldicBannerEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = game.getPermanent(source.getSourceId());
+ if (permanent == null) {
+ return false;
+ }
+ ObjectColor color = (ObjectColor) game.getState().getValue(permanent.getId() + "_color");
+ if (color == null) {
+ return false;
+ }
+ for (Permanent perm : game.getBattlefield().getActivePermanents(
+ StaticFilters.FILTER_CONTROLLED_CREATURE, source.getControllerId(), source.getSourceId(), game
+ )) {
+ if (perm.getColor(game).contains(color)) {
+ perm.addPower(1);
+ }
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/h/HeroOfTheWinds.java b/Mage.Sets/src/mage/cards/h/HeroOfTheWinds.java
new file mode 100644
index 00000000000..24a396a8bb3
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/h/HeroOfTheWinds.java
@@ -0,0 +1,45 @@
+package mage.cards.h;
+
+import mage.MageInt;
+import mage.abilities.effects.common.continuous.BoostControlledEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.abilities.keyword.HeroicAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class HeroOfTheWinds extends CardImpl {
+
+ public HeroOfTheWinds(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.SOLDIER);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(4);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Whenever you cast a spell that targets Hero of the Winds, creatures you control get +1/+0 until end of turn.
+ this.addAbility(new HeroicAbility(new BoostControlledEffect(
+ 1, 0, Duration.EndOfTurn
+ ), false, false));
+ }
+
+ private HeroOfTheWinds(final HeroOfTheWinds card) {
+ super(card);
+ }
+
+ @Override
+ public HeroOfTheWinds copy() {
+ return new HeroOfTheWinds(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/h/HexplateGolem.java b/Mage.Sets/src/mage/cards/h/HexplateGolem.java
index 34b9e6a5c81..ff6ec9671b5 100644
--- a/Mage.Sets/src/mage/cards/h/HexplateGolem.java
+++ b/Mage.Sets/src/mage/cards/h/HexplateGolem.java
@@ -1,28 +1,27 @@
-
-
package mage.cards.h;
-import java.util.UUID;
import mage.MageInt;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
+import java.util.UUID;
+
/**
- *
* @author Loki
*/
public final class HexplateGolem extends CardImpl {
- public HexplateGolem (UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{7}");
+ public HexplateGolem(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{7}");
+
this.subtype.add(SubType.GOLEM);
this.power = new MageInt(5);
this.toughness = new MageInt(7);
}
- public HexplateGolem (final HexplateGolem card) {
+ private HexplateGolem(final HexplateGolem card) {
super(card);
}
@@ -30,5 +29,4 @@ public final class HexplateGolem extends CardImpl {
public HexplateGolem copy() {
return new HexplateGolem(this);
}
-
}
diff --git a/Mage.Sets/src/mage/cards/h/HighcliffFelidar.java b/Mage.Sets/src/mage/cards/h/HighcliffFelidar.java
new file mode 100644
index 00000000000..38a85db3643
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/h/HighcliffFelidar.java
@@ -0,0 +1,162 @@
+package mage.cards.h;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.PowerPredicate;
+import mage.filter.predicate.permanent.ControllerIdPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.TargetPermanent;
+
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class HighcliffFelidar extends CardImpl {
+
+ public HighcliffFelidar(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}{W}");
+
+ this.subtype.add(SubType.CAT);
+ this.subtype.add(SubType.BEAST);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(5);
+
+ // Vigilance
+ this.addAbility(VigilanceAbility.getInstance());
+
+ // When Highcliff Felidar enters the battlefield, for each opponent, choose a creature with the greatest power among creatures that player controls. Destroy those creatures.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new HighcliffFelidarEffect()));
+ }
+
+ private HighcliffFelidar(final HighcliffFelidar card) {
+ super(card);
+ }
+
+ @Override
+ public HighcliffFelidar copy() {
+ return new HighcliffFelidar(this);
+ }
+}
+
+class HighcliffFelidarEffect extends OneShotEffect {
+
+ HighcliffFelidarEffect() {
+ super(Outcome.Benefit);
+ staticText = "for each opponent, choose a creature with the greatest power " +
+ "among creatures that player controls. Destroy those creatures.";
+ }
+
+ private HighcliffFelidarEffect(final HighcliffFelidarEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public HighcliffFelidarEffect copy() {
+ return new HighcliffFelidarEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ Set toDestroy = new HashSet();
+ game.getOpponents(source.getControllerId())
+ .stream()
+ .map(game::getPlayer)
+ .filter(Objects::nonNull)
+ .forEachOrdered(opponent -> {
+ int maxPower = game
+ .getBattlefield()
+ .getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, opponent.getId(), game)
+ .stream()
+ .map(Permanent::getPower)
+ .mapToInt(MageInt::getValue)
+ .max()
+ .orElse(Integer.MIN_VALUE);
+ if (maxPower == Integer.MIN_VALUE) {
+ return;
+ }
+ FilterPermanent filter = new FilterCreaturePermanent(
+ "creature with the greatest power controlled by " + opponent.getName()
+ );
+ filter.add(new ControllerIdPredicate(opponent.getId()));
+ filter.add(new PowerPredicate(ComparisonType.EQUAL_TO, maxPower));
+ TargetPermanent target = new TargetPermanent(filter);
+ target.setNotTarget(true);
+ if (player.choose(outcome, target, source.getSourceId(), game)) {
+ toDestroy.add(target.getFirstTarget());
+ }
+ });
+ toDestroy.stream()
+ .map(game::getPermanent)
+ .filter(Objects::nonNull)
+ .forEachOrdered(permanent -> permanent.destroy(source.getSourceId(), game, false));
+ return true;
+ }
+}
+
+// I realized after writing all this that the ability doesn't target but I like this code too much to erase it
+
+//enum HighcliffFelidarAdjuster implements TargetAdjuster {
+// instance;
+//
+// private static class HighcliffFelidarPredicate implements Predicate {
+// private final UUID controllerId;
+//
+// private HighcliffFelidarPredicate(UUID controllerId) {
+// this.controllerId = controllerId;
+// }
+//
+// @Override
+// public boolean apply(Permanent input, Game game) {
+// if (input == null || !input.isControlledBy(controllerId) || !input.isCreature()) {
+// return false;
+// }
+// int maxPower = game.getBattlefield()
+// .getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, controllerId, game)
+// .stream()
+// .map(Permanent::getPower)
+// .mapToInt(MageInt::getValue)
+// .max()
+// .orElse(Integer.MIN_VALUE);
+// return input.getPower().getValue() >= maxPower;
+// }
+//
+// private static TargetPermanent getTarget(Player player) {
+// FilterPermanent filter = new FilterPermanent("creature with the greatest power controlled by " + player.getName());
+// filter.add(new HighcliffFelidarPredicate(player.getId()));
+// return new TargetPermanent(filter);
+// }
+// }
+//
+// @Override
+// public void adjustTargets(Ability ability, Game game) {
+// ability.getTargets().clear();
+// game.getOpponents(ability.getControllerId())
+// .stream()
+// .map(game::getPlayer)
+// .filter(Objects::nonNull)
+// .map(HighcliffFelidarPredicate::getTarget)
+// .forEachOrdered(ability::addTarget);
+// }
+//}
diff --git a/Mage.Sets/src/mage/cards/h/HokoriDustDrinker.java b/Mage.Sets/src/mage/cards/h/HokoriDustDrinker.java
index 31f0b5a2cd4..2344a9fa8e6 100644
--- a/Mage.Sets/src/mage/cards/h/HokoriDustDrinker.java
+++ b/Mage.Sets/src/mage/cards/h/HokoriDustDrinker.java
@@ -36,7 +36,7 @@ public final class HokoriDustDrinker extends CardImpl {
// Lands don't untap during their controllers' untap steps.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepAllEffect(Duration.WhileOnBattlefield, TargetController.ANY, StaticFilters.FILTER_LANDS)));
- // At the beginning of each player's upkeep, that player untaps a land he or she controls.
+ // At the beginning of each player's upkeep, that player untaps a land they control.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new HokoriDustDrinkerUntapEffect(), TargetController.ANY, false));
@@ -56,7 +56,7 @@ class HokoriDustDrinkerUntapEffect extends OneShotEffect {
public HokoriDustDrinkerUntapEffect() {
super(Outcome.Untap);
- this.staticText = "that player untaps a land he or she controls";
+ this.staticText = "that player untaps a land they control";
}
public HokoriDustDrinkerUntapEffect(final HokoriDustDrinkerUntapEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/h/HollowbornBarghest.java b/Mage.Sets/src/mage/cards/h/HollowbornBarghest.java
index d278fc3e990..21a5fe789f7 100644
--- a/Mage.Sets/src/mage/cards/h/HollowbornBarghest.java
+++ b/Mage.Sets/src/mage/cards/h/HollowbornBarghest.java
@@ -52,7 +52,7 @@ public final class HollowbornBarghest extends CardImpl {
condition,
rule));
- // At the beginning of each opponent's upkeep, if that player has no cards in hand, he or she loses 2 life.
+ // At the beginning of each opponent's upkeep, if that player has no cards in hand, they lose 2 life.
this.addAbility(new HollowbornBarghestTriggeredAbility());
}
@@ -129,6 +129,6 @@ class HollowbornBarghestTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
- return "At the beginning of each opponent's upkeep, if that player has no cards in hand, he or she loses 2 life.";
+ return "At the beginning of each opponent's upkeep, if that player has no cards in hand, they lose 2 life.";
}
}
diff --git a/Mage.Sets/src/mage/cards/h/HomewardPath.java b/Mage.Sets/src/mage/cards/h/HomewardPath.java
index f6773fe9638..623a5f533a0 100644
--- a/Mage.Sets/src/mage/cards/h/HomewardPath.java
+++ b/Mage.Sets/src/mage/cards/h/HomewardPath.java
@@ -35,7 +35,7 @@ public final class HomewardPath extends CardImpl {
// {tap}: Add {C}.
this.addAbility(new ColorlessManaAbility());
- // {tap}: Each player gains control of all creatures he or she owns.
+ // {tap}: Each player gains control of all creatures they own.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new HomewardPathControlEffect(), new TapSourceCost()));
}
@@ -56,7 +56,7 @@ class HomewardPathControlEffect extends ContinuousEffectImpl {
public HomewardPathControlEffect() {
super(Duration.EndOfGame, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
- this.staticText = "Each player gains control of all creatures he or she owns";
+ this.staticText = "Each player gains control of all creatures they own";
}
public HomewardPathControlEffect(final HomewardPathControlEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/h/HonorTheFallen.java b/Mage.Sets/src/mage/cards/h/HonorTheFallen.java
index 1a66ba98909..afffbdb2eca 100644
--- a/Mage.Sets/src/mage/cards/h/HonorTheFallen.java
+++ b/Mage.Sets/src/mage/cards/h/HonorTheFallen.java
@@ -1,5 +1,3 @@
-
-
package mage.cards.h;
import java.util.UUID;
@@ -10,6 +8,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.players.Player;
@@ -18,11 +17,10 @@ import mage.players.Player;
*
* @author L_J
*/
-
public final class HonorTheFallen extends CardImpl {
public HonorTheFallen(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");
// Exile all creature cards from all graveyards. You gain 1 life for each card exiled this way.
this.getSpellAbility().addEffect(new HonorTheFallenEffect());
@@ -60,8 +58,8 @@ class HonorTheFallenEffect extends OneShotEffect {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
- for (Card card: player.getGraveyard().getCards(game)) {
- if (filter.match(card, game)) {
+ for (Card card : player.getGraveyard().getCards(game)) {
+ if (StaticFilters.FILTER_CARD_CREATURE.match(card, source.getSourceId(), controller.getId(), game)) {
if (card.moveToExile(null, "", source.getSourceId(), game)) {
exiledCards++;
}
diff --git a/Mage.Sets/src/mage/cards/h/HornOfPlenty.java b/Mage.Sets/src/mage/cards/h/HornOfPlenty.java
index 0854b5f70c2..fb2b603d9be 100644
--- a/Mage.Sets/src/mage/cards/h/HornOfPlenty.java
+++ b/Mage.Sets/src/mage/cards/h/HornOfPlenty.java
@@ -29,7 +29,7 @@ public final class HornOfPlenty extends CardImpl {
public HornOfPlenty(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{6}");
- // Whenever a player casts a spell, he or she may pay {1}. If that player does, he or she draws a card at the beginning of the next end step.
+ // Whenever a player casts a spell, they may pay {1}. If that player does, they draw a card at the beginning of the next end step.
this.addAbility(new SpellCastAllTriggeredAbility(new HornOfPlentyEffect(), new FilterSpell("a spell"), false, SetTargetPointer.PLAYER));
}
@@ -47,7 +47,7 @@ class HornOfPlentyEffect extends OneShotEffect {
public HornOfPlentyEffect() {
super(Outcome.Detriment);
- this.staticText = "he or she may pay {1}. If that player does, he or she draws a card at the beginning of the next end step";
+ this.staticText = "they may pay {1}. If that player does, they draw a card at the beginning of the next end step";
}
public HornOfPlentyEffect(final HornOfPlentyEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/h/HostageTaker.java b/Mage.Sets/src/mage/cards/h/HostageTaker.java
index fd608034642..3ef3f60d88c 100644
--- a/Mage.Sets/src/mage/cards/h/HostageTaker.java
+++ b/Mage.Sets/src/mage/cards/h/HostageTaker.java
@@ -1,6 +1,5 @@
package mage.cards.h;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -12,17 +11,12 @@ import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.AsThoughEffectType;
-import mage.constants.CardType;
-import mage.constants.Duration;
-import mage.constants.ManaType;
-import mage.constants.Outcome;
-import mage.constants.SubType;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.game.ExileZone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.ManaPoolItem;
@@ -31,8 +25,10 @@ import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
+import java.util.Objects;
+import java.util.UUID;
+
/**
- *
* @author TheElk801
*/
public final class HostageTaker extends CardImpl {
@@ -43,7 +39,8 @@ public final class HostageTaker extends CardImpl {
filter.add(AnotherPredicate.instance);
filter.add(Predicates.or(
new CardTypePredicate(CardType.ARTIFACT),
- new CardTypePredicate(CardType.CREATURE)));
+ new CardTypePredicate(CardType.CREATURE)
+ ));
}
public HostageTaker(UUID ownerId, CardSetInfo setInfo) {
@@ -55,13 +52,13 @@ public final class HostageTaker extends CardImpl {
this.toughness = new MageInt(3);
// When Hostage Taker enters the battlefield, exile another target artifact or creature until Hostage Taker leaves the battlefield. You may cast that card as long as it remains exiled, and you may spend mana as though it were mana of any type to cast that spell.
- Ability ability = new EntersBattlefieldTriggeredAbility(new HostageTakerExileEffect(filter.getMessage()));
+ Ability ability = new EntersBattlefieldTriggeredAbility(new HostageTakerExileEffect());
ability.addTarget(new TargetPermanent(filter));
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(ability);
}
- public HostageTaker(final HostageTaker card) {
+ private HostageTaker(final HostageTaker card) {
super(card);
}
@@ -73,14 +70,14 @@ public final class HostageTaker extends CardImpl {
class HostageTakerExileEffect extends OneShotEffect {
- public HostageTakerExileEffect(String targetName) {
+ HostageTakerExileEffect() {
super(Outcome.Benefit);
this.staticText = "exile another target artifact or creature until {this} leaves the battlefield. "
+ "You may cast that card as long as it remains exiled, "
+ "and you may spend mana as though it were mana of any type to cast that spell";
}
- public HostageTakerExileEffect(final HostageTakerExileEffect effect) {
+ private HostageTakerExileEffect(final HostageTakerExileEffect effect) {
super(effect);
}
@@ -93,35 +90,41 @@ class HostageTakerExileEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Permanent card = game.getPermanent(getTargetPointer().getFirst(game, source));
Permanent permanent = game.getPermanent(source.getSourceId());
- if (permanent != null && card != null) {
- Player controller = game.getPlayer(card.getControllerId());
- if (controller != null) {
- // move card to exile
- UUID exileId = CardUtil.getCardExileZoneId(game, source);
- controller.moveCardToExileWithInfo(card, exileId, permanent.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true);
- // allow to cast the card
- ContinuousEffect effect = new HostageTakerCastFromExileEffect();
- effect.setTargetPointer(new FixedTarget(card.getId()));
- game.addEffect(effect, source);
- // and you may spend mana as though it were mana of any color to cast it
- effect = new HostageTakerSpendAnyManaEffect();
- effect.setTargetPointer(new FixedTarget(card.getId()));
- game.addEffect(effect, source);
- }
+ if (permanent == null || card == null) {
+ return false;
}
- return false;
+ Player controller = game.getPlayer(card.getControllerId());
+ if (controller == null) {
+ return false;
+ }
+ // move card to exile
+ UUID exileId = CardUtil.getCardExileZoneId(game, source);
+ controller.moveCardToExileWithInfo(card, exileId, permanent.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true);
+ // allow to cast the card
+ game.addEffect(new HostageTakerCastFromExileEffect(card.getId(), exileId), source);
+ // and you may spend mana as though it were mana of any color to cast it
+ ContinuousEffect effect = new HostageTakerSpendAnyManaEffect();
+ effect.setTargetPointer(new FixedTarget(card.getId(), game));
+ game.addEffect(effect, source);
+ return true;
}
}
class HostageTakerCastFromExileEffect extends AsThoughEffectImpl {
- public HostageTakerCastFromExileEffect() {
+ private UUID cardId;
+ private UUID exileId;
+
+ HostageTakerCastFromExileEffect(UUID cardId, UUID exileId) {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit);
- staticText = "You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell";
+ this.cardId = cardId;
+ this.exileId = exileId;
}
- public HostageTakerCastFromExileEffect(final HostageTakerCastFromExileEffect effect) {
+ private HostageTakerCastFromExileEffect(final HostageTakerCastFromExileEffect effect) {
super(effect);
+ this.cardId = effect.cardId;
+ this.exileId = effect.exileId;
}
@Override
@@ -135,29 +138,26 @@ class HostageTakerCastFromExileEffect extends AsThoughEffectImpl {
}
@Override
- public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
- if (objectId.equals(getTargetPointer().getFirst(game, source))) {
- if (affectedControllerId.equals(source.getControllerId())) {
- return true;
- }
- } else {
- if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
- // object has moved zone so effect can be discarted
- this.discard();
- }
+ public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
+ if (!sourceId.equals(cardId) || !source.isControlledBy(affectedControllerId)) {
+ return false;
}
+ ExileZone exileZone = game.getState().getExile().getExileZone(exileId);
+ if (exileZone != null && exileZone.contains(cardId)) {
+ return true;
+ }
+ discard();
return false;
}
}
class HostageTakerSpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect {
- public HostageTakerSpendAnyManaEffect() {
+ HostageTakerSpendAnyManaEffect() {
super(AsThoughEffectType.SPEND_OTHER_MANA, Duration.Custom, Outcome.Benefit);
- staticText = "you may spend mana as though it were mana of any color to cast it";
}
- public HostageTakerSpendAnyManaEffect(final HostageTakerSpendAnyManaEffect effect) {
+ private HostageTakerSpendAnyManaEffect(final HostageTakerSpendAnyManaEffect effect) {
super(effect);
}
@@ -173,22 +173,12 @@ class HostageTakerSpendAnyManaEffect extends AsThoughEffectImpl implements AsTho
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
- objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
- if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget())
- && game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
- if (affectedControllerId.equals(source.getControllerId())) {
- // if the card moved from exile to spell the zone change counter is increased by 1
- if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
- return true;
- }
- }
- } else {
- if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
- // object has moved zone so effect can be discarted
- this.discard();
- }
- }
- return false;
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
+ FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
+ return source.isControlledBy(affectedControllerId)
+ && Objects.equals(objectId, fixedTarget.getTarget())
+ && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
+ && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/h/Hushbringer.java b/Mage.Sets/src/mage/cards/h/Hushbringer.java
new file mode 100644
index 00000000000..76e83933fbe
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/h/Hushbringer.java
@@ -0,0 +1,119 @@
+package mage.cards.h;
+
+import mage.MageInt;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.TriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
+import mage.abilities.keyword.FlyingAbility;
+import mage.abilities.keyword.LifelinkAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.game.events.EntersTheBattlefieldEvent;
+import mage.game.events.GameEvent;
+import mage.game.events.ZoneChangeEvent;
+import mage.game.permanent.Permanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class Hushbringer extends CardImpl {
+
+ public Hushbringer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
+
+ this.subtype.add(SubType.FAERIE);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(2);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Lifelink
+ this.addAbility(LifelinkAbility.getInstance());
+
+ // Creatures entering the battlefield or dying don't cause abilities to trigger.
+ this.addAbility(new SimpleStaticAbility(new HushbringerEffect()));
+ }
+
+ private Hushbringer(final Hushbringer card) {
+ super(card);
+ }
+
+ @Override
+ public Hushbringer copy() {
+ return new Hushbringer(this);
+ }
+}
+
+class HushbringerEffect extends ContinuousRuleModifyingEffectImpl {
+
+ HushbringerEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.Detriment, false, false);
+ staticText = "Creatures entering the battlefield or dying don't cause abilities to trigger";
+ }
+
+ private HushbringerEffect(final HushbringerEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD
+ || event.getType() == GameEvent.EventType.ZONE_CHANGE;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ Ability ability = (Ability) getValue("targetAbility");
+ if (ability == null || ability.getAbilityType() != AbilityType.TRIGGERED) {
+ return false;
+ }
+ Permanent permanent;
+ switch (event.getType()) {
+ case ENTERS_THE_BATTLEFIELD:
+ permanent = ((EntersTheBattlefieldEvent) event).getTarget();
+ break;
+ case ZONE_CHANGE:
+ ZoneChangeEvent zEvent = ((ZoneChangeEvent) event);
+ if (!zEvent.isDiesEvent()) {
+ return false;
+ }
+ permanent = zEvent.getTarget();
+ break;
+ default:
+ return false;
+ }
+
+ if (permanent == null || !permanent.isCreature()) {
+ return false;
+ }
+ return (((TriggeredAbility) ability).checkTrigger(event, game));
+ }
+
+ @Override
+ public String getInfoMessage(Ability source, GameEvent event, Game game) {
+ MageObject enteringObject = game.getObject(event.getSourceId());
+ MageObject sourceObject = game.getObject(source.getSourceId());
+ Ability ability = (Ability) getValue("targetAbility");
+ if (enteringObject == null || sourceObject == null || ability == null) {
+ return null;
+ }
+ MageObject abilitObject = game.getObject(ability.getSourceId());
+ if (abilitObject == null) {
+ return null;
+ }
+ return sourceObject.getLogName() + " prevented ability of "
+ + abilitObject.getLogName() + " from triggering.";
+ }
+
+ @Override
+ public HushbringerEffect copy() {
+ return new HushbringerEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/h/HypnoticSprite.java b/Mage.Sets/src/mage/cards/h/HypnoticSprite.java
new file mode 100644
index 00000000000..89b51318570
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/h/HypnoticSprite.java
@@ -0,0 +1,52 @@
+package mage.cards.h;
+
+import mage.MageInt;
+import mage.abilities.effects.common.CounterTargetEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.filter.FilterSpell;
+import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
+import mage.target.TargetSpell;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class HypnoticSprite extends AdventureCard {
+
+ private static final FilterSpell filter = new FilterSpell("spell with converted mana cost 3 or less");
+
+ static {
+ filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 4));
+ }
+
+ public HypnoticSprite(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.INSTANT}, "{U}{U}", "Mesmeric Glare", "{2}{U}");
+
+ this.subtype.add(SubType.FAERIE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(1);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Mesmeric Glare
+ // Counter target spell with converted mana cost 3 or less.
+ this.getSpellCard().getSpellAbility().addEffect(new CounterTargetEffect());
+ this.getSpellCard().getSpellAbility().addTarget(new TargetSpell(filter));
+ }
+
+ private HypnoticSprite(final HypnoticSprite card) {
+ super(card);
+ }
+
+ @Override
+ public HypnoticSprite copy() {
+ return new HypnoticSprite(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/i/IG88B.java b/Mage.Sets/src/mage/cards/i/IG88B.java
index 4259b5043b6..47c98c58d71 100644
--- a/Mage.Sets/src/mage/cards/i/IG88B.java
+++ b/Mage.Sets/src/mage/cards/i/IG88B.java
@@ -37,11 +37,11 @@ public final class IG88B extends CardImpl {
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
- // Bounty — Whenever IF-88B deals combat damage to a player, that player loses life equal to the number of bounty counters on creatures he or she controls.
+ // Bounty — Whenever IF-88B deals combat damage to a player, that player loses life equal to the number of bounty counters on creatures they control.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(
new LoseLifeTargetEffect(new CountersOnDefendingPlayerCreaturesCount(CounterType.BOUNTY)),
false,
- "Bounty — Whenever {this} deals combat damage to a player, that player loses life equal to the number of bounty counters on creatures he or she controls",
+ "Bounty — Whenever {this} deals combat damage to a player, that player loses life equal to the number of bounty counters on creatures they control",
true)
);
@@ -84,6 +84,6 @@ class CountersOnDefendingPlayerCreaturesCount implements DynamicValue {
@Override
public String getMessage() {
- return "the number of " + counterType.getName() + " counters on creatures he or she controls";
+ return "the number of " + counterType.getName() + " counters on creatures they control";
}
}
diff --git a/Mage.Sets/src/mage/cards/i/IconOfAncestry.java b/Mage.Sets/src/mage/cards/i/IconOfAncestry.java
index 11259f39db7..c042a30edf2 100644
--- a/Mage.Sets/src/mage/cards/i/IconOfAncestry.java
+++ b/Mage.Sets/src/mage/cards/i/IconOfAncestry.java
@@ -1,24 +1,30 @@
package mage.cards.i;
+import java.util.Set;
import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.TapSourceCost;
-import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.ChooseCreatureTypeEffect;
-import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.abilities.effects.common.continuous.BoostAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
-import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ChosenSubtypePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
-
import java.util.UUID;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.Card;
+import mage.cards.Cards;
+import mage.cards.CardsImpl;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.TargetCard;
/**
* @author TheElk801
@@ -27,13 +33,10 @@ public final class IconOfAncestry extends CardImpl {
private static final FilterCreaturePermanent filter
= new FilterCreaturePermanent("creatures you control of the chosen type");
- private static final FilterCard filter2
- = new FilterCreatureCard("creature card of the chosen type");
static {
filter.add(ChosenSubtypePredicate.instance);
filter.add(new ControllerPredicate(TargetController.YOU));
- filter2.add(ChosenSubtypePredicate.instance);
}
public IconOfAncestry(UUID ownerId, CardSetInfo setInfo) {
@@ -47,11 +50,9 @@ public final class IconOfAncestry extends CardImpl {
new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, false)
));
- // {3}, {T}: Look at the top three cards of your library. You may reveal a creature card of the chosen type from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
- Ability ability = new SimpleActivatedAbility(new LookLibraryAndPickControllerEffect(
- 3, 1, filter2,
- true, false, Zone.HAND, true
- ).setBackInRandomOrder(true), new GenericManaCost(3));
+ // {3}, {T}: Look at the top three cards of your library. You may reveal a creature card of the
+ // chosen type from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
+ Ability ability = new SimpleActivatedAbility(new IconOfAncestryEffect(), new ManaCostsImpl("{3}"));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
@@ -65,3 +66,58 @@ public final class IconOfAncestry extends CardImpl {
return new IconOfAncestry(this);
}
}
+
+class IconOfAncestryEffect extends OneShotEffect {
+
+ public IconOfAncestryEffect() {
+ super(Outcome.AIDontUseIt);
+ this.staticText = "Look at the top three cards of your library. "
+ + "You may reveal a creature card of the "
+ + "chosen type from among them and put it into your hand. "
+ + "Put the rest on the bottom of your library in a random order";
+ }
+
+ public IconOfAncestryEffect(final IconOfAncestryEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public IconOfAncestryEffect copy() {
+ return new IconOfAncestryEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null
+ || !controller.getLibrary().hasCards()) {
+ return false;
+ }
+ Set cardsFromTopOfLibrary = controller.getLibrary().getTopCards(game, 3);
+ Cards cardsFromLibrary = new CardsImpl();
+ Cards revealedCard = new CardsImpl();
+ cardsFromLibrary.addAll(cardsFromTopOfLibrary);
+ if (cardsFromTopOfLibrary.isEmpty()) {
+ return false;
+ }
+ FilterCreatureCard filter = new FilterCreatureCard("creature card that matches the chosen subtype");
+ SubType subtype = (SubType) game.getState().getValue(source.getSourceId() + "_type");
+ if (subtype != null) {
+ filter.add(new SubtypePredicate(subtype));
+ }
+ TargetCard target = new TargetCard(Zone.LIBRARY, filter);
+ if (target.canChoose(controller.getId(), game)
+ && controller.chooseUse(outcome, "Do you wish to use Icon of Ancestry's effect?", source, game)
+ && controller.choose(Outcome.Benefit, cardsFromLibrary, target, game)) {
+ Card chosenCard = game.getCard(target.getFirstTarget());
+ if (chosenCard != null) {
+ revealedCard.add(chosenCard);
+ controller.revealCards(source, revealedCard, game);
+ controller.putInHand(chosenCard, game);
+ cardsFromLibrary.remove(chosenCard);
+ }
+ }
+ controller.putCardsOnBottomOfLibrary(cardsFromLibrary, game, source, true);
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/i/IdentityThief.java b/Mage.Sets/src/mage/cards/i/IdentityThief.java
index 0f8c589fb5b..bcd8f21f659 100644
--- a/Mage.Sets/src/mage/cards/i/IdentityThief.java
+++ b/Mage.Sets/src/mage/cards/i/IdentityThief.java
@@ -6,7 +6,6 @@ import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.CopyEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -105,21 +104,21 @@ class IdentityThiefEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- Permanent permanent = game.getPermanent(source.getFirstTarget());
+ Permanent permanent = game.getPermanentOrLKIBattlefield(source.getFirstTarget());
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
- if (controller != null && permanent != null && sourcePermanent != null) {
- CopyEffect copyEffect = new CopyEffect(Duration.EndOfTurn, permanent, source.getSourceId());
- if (controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true)) {
- // Copy exiled permanent
- game.addEffect(copyEffect, source);
- // Create delayed triggered ability
+ if (controller != null
+ && permanent != null
+ && sourcePermanent != null) {
+ game.copyPermanent(permanent, sourcePermanent.getId(), source, null);
+ if (controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourcePermanent.getIdName(),
+ source.getSourceId(), game, Zone.BATTLEFIELD, true)) {
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect();
effect.setText("Return the exiled card to the battlefield under its owner's control at the beginning of the next end step");
effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
- return true;
}
+ return true;
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/i/IdyllicGrange.java b/Mage.Sets/src/mage/cards/i/IdyllicGrange.java
new file mode 100644
index 00000000000..50b1d4bfc63
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/i/IdyllicGrange.java
@@ -0,0 +1,69 @@
+package mage.cards.i;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.common.EntersBattlefieldUntappedTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.TapSourceEffect;
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.abilities.mana.WhiteManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.target.common.TargetControlledCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class IdyllicGrange extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterControlledPermanent(SubType.PLAINS);
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ }
+ private static final Condition condition
+ = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.FEWER_THAN, 3);
+
+ public IdyllicGrange(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ this.subtype.add(SubType.PLAINS);
+
+ // ({T}: Add {W}.)
+ this.addAbility(new WhiteManaAbility());
+
+ // Idyllic Grange enters the battlefield tapped unless you control three or more other Plains.
+ this.addAbility(new EntersBattlefieldAbility(
+ new ConditionalOneShotEffect(new TapSourceEffect(), condition),
+ "tapped unless you control three or more other Plains"
+ ));
+
+ // When Idyllic Grange enters the battlefield untapped, put a +1/+1 counter on target creature you control.
+ Ability ability = new EntersBattlefieldUntappedTriggeredAbility(
+ new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false
+ );
+ ability.addTarget(new TargetControlledCreaturePermanent());
+ this.addAbility(ability);
+ }
+
+ private IdyllicGrange(final IdyllicGrange card) {
+ super(card);
+ }
+
+ @Override
+ public IdyllicGrange copy() {
+ return new IdyllicGrange(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/i/IllicitAuction.java b/Mage.Sets/src/mage/cards/i/IllicitAuction.java
index 08a4a981ebd..3791eac67b9 100644
--- a/Mage.Sets/src/mage/cards/i/IllicitAuction.java
+++ b/Mage.Sets/src/mage/cards/i/IllicitAuction.java
@@ -1,10 +1,6 @@
package mage.cards.i;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.abilities.keyword.DoubleStrikeAbility;
@@ -21,8 +17,12 @@ import mage.players.Player;
import mage.players.PlayerList;
import mage.target.common.TargetCreaturePermanent;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+
/**
- *
* @author Quercitron
*/
public final class IllicitAuction extends CardImpl {
@@ -66,18 +66,17 @@ class IllicitAuctionEffect extends GainControlTargetEffect {
public void init(Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId());
Permanent targetCreature = game.getPermanent(source.getFirstTarget());
- if (controller != null
- && targetCreature != null) {
- PlayerList playerList = game.getPlayerList().copy();
- playerList.setCurrent(game.getActivePlayerId());
-
- Player winner = game.getPlayer(game.getActivePlayerId());
+ if (controller != null && targetCreature != null) {
+ PlayerList playerList = game.getState().getPlayersInRange(controller.getId(), game);
+ Player winner = game.getPlayer(controller.getId());
int highBid = 0;
game.informPlayers(winner.getLogName() + " has bet 0 lifes");
- Player currentPlayer = playerList.getNextInRange(controller, game);
- while (!Objects.equals(currentPlayer, winner)) {
+
+ Player currentPlayer = playerList.getNext(game, false);
+ while (currentPlayer != null && !Objects.equals(currentPlayer, winner)) {
String text = winner.getLogName() + " has bet " + highBid + " life" + (highBid > 1 ? "s" : "") + ". Top the bid?";
- if (currentPlayer.chooseUse(Outcome.GainControl, text, source, game)) {
+ if (currentPlayer.canRespond()
+ && currentPlayer.chooseUse(Outcome.GainControl, text, source, game)) {
int newBid = 0;
if (!currentPlayer.isHuman()) {//AI will evaluate the creature and bid
CreatureEvaluator eval = new CreatureEvaluator();
@@ -85,7 +84,9 @@ class IllicitAuctionEffect extends GainControlTargetEffect {
int creatureValue = eval.evaluate(targetCreature, game);
newBid = Math.max(creatureValue % 2, computerLife - 100);
} else {
- newBid = currentPlayer.getAmount(highBid + 1, Integer.MAX_VALUE, "Choose bid", game);
+ if (currentPlayer.canRespond()) {
+ newBid = currentPlayer.getAmount(highBid + 1, Integer.MAX_VALUE, "Choose bid", game);
+ }
}
if (newBid > highBid) {
highBid = newBid;
@@ -93,7 +94,12 @@ class IllicitAuctionEffect extends GainControlTargetEffect {
game.informPlayers(currentPlayer.getLogName() + " bet " + newBid + " life" + (newBid > 1 ? "s" : ""));
}
}
- currentPlayer = playerList.getNextInRange(controller, game);
+ currentPlayer = playerList.getNext(game, false);
+
+ // stops loop on all players quite
+ if (game.getState().getPlayersInRange(controller.getId(), game).isEmpty()) {
+ break;
+ }
}
game.informPlayers(winner.getLogName() + " won the auction with a bid of " + highBid + " life" + (highBid > 1 ? "s" : ""));
diff --git a/Mage.Sets/src/mage/cards/i/ImaginaryThreats.java b/Mage.Sets/src/mage/cards/i/ImaginaryThreats.java
index 8b88a30a5b4..75a5c5c538f 100644
--- a/Mage.Sets/src/mage/cards/i/ImaginaryThreats.java
+++ b/Mage.Sets/src/mage/cards/i/ImaginaryThreats.java
@@ -30,12 +30,12 @@ public final class ImaginaryThreats extends CardImpl {
public ImaginaryThreats(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{U}");
- // Creatures target opponent controls attack this turn if able. During that player's next untap step, creatures he or she controls don't untap.
+ // Creatures target opponent controls attack this turn if able. During that player's next untap step, creatures they control don't untap.
getSpellAbility().addEffect(new ImaginaryThreatsEffect());
getSpellAbility().addWatcher(new AttackedThisTurnWatcher());
getSpellAbility().addTarget(new TargetOpponent());
getSpellAbility().addEffect(new DontUntapInPlayersNextUntapStepAllEffect(new FilterCreaturePermanent())
- .setText("During that player's next untap step, creatures he or she controls don't untap"));
+ .setText("During that player's next untap step, creatures they control don't untap"));
// Cycling {2}
this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}")));
diff --git a/Mage.Sets/src/mage/cards/i/ImmortalCoil.java b/Mage.Sets/src/mage/cards/i/ImmortalCoil.java
index bbee2875fe1..6c52b2592ab 100644
--- a/Mage.Sets/src/mage/cards/i/ImmortalCoil.java
+++ b/Mage.Sets/src/mage/cards/i/ImmortalCoil.java
@@ -1,7 +1,5 @@
-
package mage.cards.i;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.StateTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
@@ -21,18 +19,21 @@ import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
+import java.util.UUID;
+
/**
- *
* @author Plopman
*/
public final class ImmortalCoil extends CardImpl {
public ImmortalCoil(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}{B}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{B}{B}");
// {tap}, Exile two cards from your graveyard: Draw a card.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new TapSourceCost());
@@ -133,7 +134,7 @@ class PreventAllDamageToControllerEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
Player player = game.getPlayer(source.getControllerId());
@@ -157,9 +158,7 @@ class PreventAllDamageToControllerEffect extends PreventionEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
- if (event.getTargetId().equals(source.getControllerId())) {
- return true;
- }
+ return event.getTargetId().equals(source.getControllerId());
}
return false;
diff --git a/Mage.Sets/src/mage/cards/i/ImmortalServitude.java b/Mage.Sets/src/mage/cards/i/ImmortalServitude.java
index 80b4e97c1f4..448f825cf6c 100644
--- a/Mage.Sets/src/mage/cards/i/ImmortalServitude.java
+++ b/Mage.Sets/src/mage/cards/i/ImmortalServitude.java
@@ -1,4 +1,3 @@
-
package mage.cards.i;
import java.util.Set;
@@ -11,7 +10,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
@@ -58,7 +57,7 @@ class ImmortalServitudeEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId());
int count = source.getManaCostsToPay().getX();
- Set cards = you.getGraveyard().getCards(new FilterCreatureCard(), game);
+ Set cards = you.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game);
for (Card card : cards) {
if (card != null && card.getConvertedManaCost() == count) {
card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false);
diff --git a/Mage.Sets/src/mage/cards/i/Impatience.java b/Mage.Sets/src/mage/cards/i/Impatience.java
index 6b15719662d..86505fc12ec 100644
--- a/Mage.Sets/src/mage/cards/i/Impatience.java
+++ b/Mage.Sets/src/mage/cards/i/Impatience.java
@@ -25,9 +25,9 @@ public final class Impatience extends CardImpl {
public Impatience(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}");
- // At the beginning of each player's end step, if that player didn't cast a spell this turn, Impatience deals 2 damage to him or her.
+ // At the beginning of each player's end step, if that player didn't cast a spell this turn, Impatience deals 2 damage to that player.
Effect effect = new DamageTargetEffect(2);
- effect.setText("{this} deals 2 damage to him or her.");
+ effect.setText("{this} deals 2 damage to that player.");
this.addAbility(new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.ANY,
new ImpatienceCondition(), false));
}
diff --git a/Mage.Sets/src/mage/cards/i/ImperialEdict.java b/Mage.Sets/src/mage/cards/i/ImperialEdict.java
index c6fcaf6f704..5c18c393236 100644
--- a/Mage.Sets/src/mage/cards/i/ImperialEdict.java
+++ b/Mage.Sets/src/mage/cards/i/ImperialEdict.java
@@ -26,7 +26,7 @@ public final class ImperialEdict extends CardImpl {
public ImperialEdict(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}");
- // Target opponent chooses a creature he or she controls. Destroy it.
+ // Target opponent chooses a creature they control. Destroy it.
this.getSpellAbility().addEffect(new ImperialEdictEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
}
@@ -45,7 +45,7 @@ class ImperialEdictEffect extends OneShotEffect {
ImperialEdictEffect() {
super(Outcome.Benefit);
- this.staticText = "Target opponent chooses a creature he or she controls. Destroy it.";
+ this.staticText = "Target opponent chooses a creature they control. Destroy it.";
}
ImperialEdictEffect(final ImperialEdictEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/i/ImposingSovereign.java b/Mage.Sets/src/mage/cards/i/ImposingSovereign.java
index e46be3e1bc2..9a38f667039 100644
--- a/Mage.Sets/src/mage/cards/i/ImposingSovereign.java
+++ b/Mage.Sets/src/mage/cards/i/ImposingSovereign.java
@@ -1,32 +1,27 @@
-
package mage.cards.i;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.game.Game;
import mage.game.events.EntersTheBattlefieldEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
+import java.util.UUID;
+
/**
- *
* @author jeffwadsworth
*/
public final class ImposingSovereign extends CardImpl {
public ImposingSovereign(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}");
- this.subtype.add(SubType.HUMAN);
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
+ this.subtype.add(SubType.HUMAN, SubType.NOBLE);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
@@ -36,7 +31,7 @@ public final class ImposingSovereign extends CardImpl {
}
- public ImposingSovereign(final ImposingSovereign card) {
+ private ImposingSovereign(final ImposingSovereign card) {
super(card);
}
@@ -53,7 +48,7 @@ class ImposingSovereignEffect extends ReplacementEffectImpl {
staticText = "Creatures your opponents control enter the battlefield tapped";
}
- ImposingSovereignEffect(final ImposingSovereignEffect effect) {
+ private ImposingSovereignEffect(final ImposingSovereignEffect effect) {
super(effect);
}
@@ -73,13 +68,11 @@ class ImposingSovereignEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
- if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
- Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget();
- if (permanent != null && permanent.isCreature()) {
- return true;
- }
+ if (!game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
+ return false;
}
- return false;
+ Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget();
+ return permanent != null && permanent.isCreature();
}
@Override
diff --git a/Mage.Sets/src/mage/cards/i/ImprobableAlliance.java b/Mage.Sets/src/mage/cards/i/ImprobableAlliance.java
new file mode 100644
index 00000000000..85c917a1978
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/i/ImprobableAlliance.java
@@ -0,0 +1,40 @@
+package mage.cards.i;
+
+import mage.abilities.common.DrawSecondCardTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DrawDiscardControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.game.permanent.token.FaerieToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ImprobableAlliance extends CardImpl {
+
+ public ImprobableAlliance(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{R}");
+
+ // Whenever you draw your second card each turn, create a 1/1 blue Faerie creature token with flying.
+ this.addAbility(new DrawSecondCardTriggeredAbility(new CreateTokenEffect(new FaerieToken()), false));
+
+ // {4}{U}{R}: Draw a card, then discard a card.
+ this.addAbility(new SimpleActivatedAbility(
+ new DrawDiscardControllerEffect(1, 1), new ManaCostsImpl("{4}{U}{R}")
+ ));
+ }
+
+ private ImprobableAlliance(final ImprobableAlliance card) {
+ super(card);
+ }
+
+ @Override
+ public ImprobableAlliance copy() {
+ return new ImprobableAlliance(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/i/InciteRebellion.java b/Mage.Sets/src/mage/cards/i/InciteRebellion.java
index 1e01d080bed..b328aaf4a29 100644
--- a/Mage.Sets/src/mage/cards/i/InciteRebellion.java
+++ b/Mage.Sets/src/mage/cards/i/InciteRebellion.java
@@ -23,7 +23,7 @@ public final class InciteRebellion extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{R}{R}");
- // For each player, Incite Rebellion deals damage to that player and each creature that player controls equal to the number of creatures he or she controls.
+ // For each player, Incite Rebellion deals damage to that player and each creature that player controls equal to the number of creatures they control.
this.getSpellAbility().addEffect(new InciteRebellionEffect());
}
@@ -43,7 +43,7 @@ class InciteRebellionEffect extends OneShotEffect {
public InciteRebellionEffect() {
super(Outcome.Detriment);
- this.staticText = "For each player, {this} deals damage to that player and each creature that player controls equal to the number of creatures he or she controls";
+ this.staticText = "For each player, {this} deals damage to that player and each creature that player controls equal to the number of creatures they control";
}
public InciteRebellionEffect(final InciteRebellionEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/i/InduceParanoia.java b/Mage.Sets/src/mage/cards/i/InduceParanoia.java
index d4b4a8d37c4..d8862fa168b 100644
--- a/Mage.Sets/src/mage/cards/i/InduceParanoia.java
+++ b/Mage.Sets/src/mage/cards/i/InduceParanoia.java
@@ -31,7 +31,7 @@ public final class InduceParanoia extends CardImpl {
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new InduceParanoiaEffect(),
new CounterTargetEffect(),
- new ManaWasSpentCondition(ColoredManaSymbol.B), "Counter target spell. If {B} was spent to cast {this}, that spell's controller puts the top X cards of their library into their graveyard, where X is the spell's converted mana cost."));
+ new ManaWasSpentCondition(ColoredManaSymbol.B), "Counter target spell. If {B} was spent to cast this spell, that spell's controller puts the top X cards of their library into their graveyard, where X is the spell's converted mana cost."));
// Counter target spell.
this.getSpellAbility().addTarget(new TargetSpell());
@@ -51,7 +51,7 @@ class InduceParanoiaEffect extends OneShotEffect {
InduceParanoiaEffect() {
super(Outcome.Detriment);
- this.staticText = "Counter target spell. If {B} was spent to cast {this}, that spell's controller puts the top X cards of their library into their graveyard, where X is the spell's converted mana cost.";
+ this.staticText = "Counter target spell. If {B} was spent to cast this spell, that spell's controller puts the top X cards of their library into their graveyard, where X is the spell's converted mana cost.";
}
InduceParanoiaEffect(final InduceParanoiaEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/i/IndulgentAristocrat.java b/Mage.Sets/src/mage/cards/i/IndulgentAristocrat.java
index 3379c1dc353..ec6c93cdd64 100644
--- a/Mage.Sets/src/mage/cards/i/IndulgentAristocrat.java
+++ b/Mage.Sets/src/mage/cards/i/IndulgentAristocrat.java
@@ -1,7 +1,5 @@
-
package mage.cards.i;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -15,13 +13,15 @@ import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType;
-import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.common.TargetControlledCreaturePermanent;
+import java.util.UUID;
+
+import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
+
/**
- *
* @author fireshoes
*/
public final class IndulgentAristocrat extends CardImpl {
@@ -34,7 +34,7 @@ public final class IndulgentAristocrat extends CardImpl {
public IndulgentAristocrat(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}");
- this.subtype.add(SubType.VAMPIRE);
+ this.subtype.add(SubType.VAMPIRE, SubType.NOBLE);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
@@ -47,7 +47,7 @@ public final class IndulgentAristocrat extends CardImpl {
this.addAbility(ability);
}
- public IndulgentAristocrat(final IndulgentAristocrat card) {
+ private IndulgentAristocrat(final IndulgentAristocrat card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/i/InevitableEnd.java b/Mage.Sets/src/mage/cards/i/InevitableEnd.java
new file mode 100644
index 00000000000..f05ef549b7d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/i/InevitableEnd.java
@@ -0,0 +1,52 @@
+package mage.cards.i;
+
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.SacrificeControllerEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.StaticFilters;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class InevitableEnd extends CardImpl {
+
+ public InevitableEnd(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}");
+
+ this.subtype.add(SubType.AURA);
+
+ // Enchant creature
+ TargetPermanent auraTarget = new TargetCreaturePermanent();
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // Enchanted creature has "At the beginning of your upkeep, sacrifice a creature."
+ this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect(
+ new BeginningOfUpkeepTriggeredAbility(new SacrificeControllerEffect(
+ StaticFilters.FILTER_PERMANENT_CREATURE, 1, null
+ ), TargetController.YOU, false), AttachmentType.AURA
+ )));
+ }
+
+ private InevitableEnd(final InevitableEnd card) {
+ super(card);
+ }
+
+ @Override
+ public InevitableEnd copy() {
+ return new InevitableEnd(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/i/InfernalGenesis.java b/Mage.Sets/src/mage/cards/i/InfernalGenesis.java
index ae5a7af8061..daa9e51bfd3 100644
--- a/Mage.Sets/src/mage/cards/i/InfernalGenesis.java
+++ b/Mage.Sets/src/mage/cards/i/InfernalGenesis.java
@@ -23,7 +23,7 @@ public final class InfernalGenesis extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}{B}");
// At the beginning of each player's upkeep, that player puts the top card of their library into their graveyard.
- // Then he or she creates X 1/1 black Minion creature tokens, where X is that card's converted mana cost.
+ // Then they create X 1/1 black Minion creature tokens, where X is that card's converted mana cost.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new InfernalGenesisEffect(), TargetController.ANY, false));
}
@@ -42,7 +42,7 @@ class InfernalGenesisEffect extends OneShotEffect {
InfernalGenesisEffect() {
super(Outcome.PutCreatureInPlay);
staticText = "that player puts the top card of their library into their graveyard. " +
- "Then he or she creates X 1/1 black Minion creature tokens, where X is that card's converted mana cost";
+ "Then they create X 1/1 black Minion creature tokens, where X is that card's converted mana cost";
}
InfernalGenesisEffect(final InfernalGenesisEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/i/InfernalHarvest.java b/Mage.Sets/src/mage/cards/i/InfernalHarvest.java
new file mode 100644
index 00000000000..74f128ab3ef
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/i/InfernalHarvest.java
@@ -0,0 +1,127 @@
+package mage.cards.i;
+
+import mage.abilities.Ability;
+import mage.abilities.costs.Cost;
+import mage.abilities.costs.CostImpl;
+import mage.abilities.costs.VariableCostImpl;
+import mage.abilities.dynamicvalue.common.GetXValue;
+import mage.abilities.effects.common.DamageMultiEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.common.FilterControlledPermanent;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.Target;
+import mage.target.common.TargetControlledPermanent;
+import mage.target.common.TargetCreaturePermanentAmount;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * @author TheElk801
+ */
+public final class InfernalHarvest extends CardImpl {
+
+ public InfernalHarvest(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}");
+
+ // As an additional cost to cast Infernal Harvest, return X Swamps you control to their owner's hand.
+ this.getSpellAbility().addCost(new InfernalHarvestVariableCost());
+
+ // Infernal Harvest deals X damage divided as you choose among any number of target creatures.
+ this.getSpellAbility().addEffect(new DamageMultiEffect(GetXValue.instance));
+ this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(GetXValue.instance));
+ }
+
+ private InfernalHarvest(final InfernalHarvest card) {
+ super(card);
+ }
+
+ @Override
+ public InfernalHarvest copy() {
+ return new InfernalHarvest(this);
+ }
+}
+
+class InfernalHarvestVariableCost extends VariableCostImpl {
+
+ private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.SWAMP);
+
+ InfernalHarvestVariableCost() {
+ super("Swamps to return");
+ this.text = "return " + xText + " Swamps you control to their owner's hand";
+ }
+
+ private InfernalHarvestVariableCost(final InfernalHarvestVariableCost cost) {
+ super(cost);
+ }
+
+ @Override
+ public InfernalHarvestVariableCost copy() {
+ return new InfernalHarvestVariableCost(this);
+ }
+
+ @Override
+ public int getMaxValue(Ability source, Game game) {
+ return game.getBattlefield().countAll(filter, source.getControllerId(), game);
+ }
+
+ @Override
+ public Cost getFixedCostsFromAnnouncedValue(int xValue) {
+ return new InfernalHarvestCost(xValue);
+ }
+
+ private static final class InfernalHarvestCost extends CostImpl {
+
+ private final int xValue;
+
+ private InfernalHarvestCost(int xValue) {
+ super();
+ this.xValue = xValue;
+ this.text = "return " + xValue + " Swamps you control to their owner's hand";
+ this.addTarget(new TargetControlledPermanent(xValue, xValue, filter, true));
+ }
+
+ private InfernalHarvestCost(final InfernalHarvestCost cost) {
+ super(cost);
+ this.xValue = cost.xValue;
+ }
+
+ @Override
+ public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
+ return game.getBattlefield().countAll(filter, controllerId, game) >= xValue;
+ }
+
+ @Override
+ public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
+ if (!this.canPay(ability, sourceId, controllerId, game)) {
+ return false;
+ }
+ Player player = game.getPlayer(controllerId);
+ if (player == null || !targets.choose(Outcome.ReturnToHand, controllerId, sourceId, game)) {
+ return false;
+ }
+ return paid = player.moveCards(
+ targets.stream()
+ .map(Target::getTargets)
+ .flatMap(Collection::stream)
+ .map(game::getCard)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet()),
+ Zone.HAND, ability, game
+ );
+ }
+
+ @Override
+ public Cost copy() {
+ return new InfernalHarvestCost(this);
+ }
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/i/InnerSanctum.java b/Mage.Sets/src/mage/cards/i/InnerSanctum.java
index 0e73a30da6b..390d41ac7fc 100644
--- a/Mage.Sets/src/mage/cards/i/InnerSanctum.java
+++ b/Mage.Sets/src/mage/cards/i/InnerSanctum.java
@@ -1,7 +1,5 @@
-
package mage.cards.i;
-import java.util.UUID;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.PayLifeCost;
import mage.abilities.effects.common.PreventAllDamageToAllEffect;
@@ -11,10 +9,11 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
-import mage.filter.common.FilterControlledCreatureInPlay;
+import mage.filter.StaticFilters;
+
+import java.util.UUID;
/**
- *
* @author TheElk801
*/
public final class InnerSanctum extends CardImpl {
@@ -27,7 +26,7 @@ public final class InnerSanctum extends CardImpl {
// Prevent all damage that would be dealt to creatures you control.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
- new PreventAllDamageToAllEffect(Duration.WhileOnBattlefield, new FilterControlledCreatureInPlay("creatures you control"))
+ new PreventAllDamageToAllEffect(Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES_CONTROLLED)
));
}
diff --git a/Mage.Sets/src/mage/cards/i/InquisitivePuppet.java b/Mage.Sets/src/mage/cards/i/InquisitivePuppet.java
new file mode 100644
index 00000000000..9de9edf129a
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/i/InquisitivePuppet.java
@@ -0,0 +1,44 @@
+package mage.cards.i;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.ExileSourceCost;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.keyword.ScryEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.game.permanent.token.HumanToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class InquisitivePuppet extends CardImpl {
+
+ public InquisitivePuppet(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}");
+
+ this.subtype.add(SubType.CONSTRUCT);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(2);
+
+ // When Inquisitive Puppet enters the battlefield, scry 1.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new ScryEffect(1)));
+
+ // Exile Inquisitive Puppet: Create a 1/1 white Human creature token.
+ this.addAbility(new SimpleActivatedAbility(new CreateTokenEffect(new HumanToken()), new ExileSourceCost()));
+ }
+
+ private InquisitivePuppet(final InquisitivePuppet card) {
+ super(card);
+ }
+
+ @Override
+ public InquisitivePuppet copy() {
+ return new InquisitivePuppet(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/i/InsatiableAppetite.java b/Mage.Sets/src/mage/cards/i/InsatiableAppetite.java
new file mode 100644
index 00000000000..60bc2bfaadd
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/i/InsatiableAppetite.java
@@ -0,0 +1,45 @@
+package mage.cards.i;
+
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.effects.common.DoIfCostPaid;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.common.FilterControlledPermanent;
+import mage.target.common.TargetControlledPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class InsatiableAppetite extends CardImpl {
+
+ private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.FOOD, "a Food");
+
+ public InsatiableAppetite(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}");
+
+ // You may sacrifice a Food. If you do, target creature gets +5/+5 until end of turn. Otherwise, that creature gets +3/+3 until end of turn.
+ this.getSpellAbility().addEffect(new DoIfCostPaid(
+ new BoostTargetEffect(5, 5, Duration.EndOfTurn),
+ new BoostTargetEffect(3, 3, Duration.EndOfTurn),
+ new SacrificeTargetCost(new TargetControlledPermanent(filter))
+ ).setText("You may sacrifice a Food. If you do, target creature gets +5/+5 until end of turn. " +
+ "Otherwise, that creature gets +3/+3 until end of turn."));
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent());
+ }
+
+ private InsatiableAppetite(final InsatiableAppetite card) {
+ super(card);
+ }
+
+ @Override
+ public InsatiableAppetite copy() {
+ return new InsatiableAppetite(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/i/InspiringVeteran.java b/Mage.Sets/src/mage/cards/i/InspiringVeteran.java
new file mode 100644
index 00000000000..6bd8f7e88a4
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/i/InspiringVeteran.java
@@ -0,0 +1,45 @@
+package mage.cards.i;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.continuous.BoostControlledEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.common.FilterCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class InspiringVeteran extends CardImpl {
+
+ private static final FilterCreaturePermanent filter
+ = new FilterCreaturePermanent(SubType.KNIGHT, "Knights");
+
+ public InspiringVeteran(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Other Knights you control get +1/+1.
+ this.addAbility(new SimpleStaticAbility(
+ new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter, true)
+ ));
+ }
+
+ private InspiringVeteran(final InspiringVeteran card) {
+ super(card);
+ }
+
+ @Override
+ public InspiringVeteran copy() {
+ return new InspiringVeteran(this);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/i/Interrogation.java b/Mage.Sets/src/mage/cards/i/Interrogation.java
index 0aedd44b33f..0d74de0131e 100644
--- a/Mage.Sets/src/mage/cards/i/Interrogation.java
+++ b/Mage.Sets/src/mage/cards/i/Interrogation.java
@@ -24,7 +24,7 @@ public final class Interrogation extends CardImpl {
public Interrogation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{B}");
- // Target player discards a card. Then that player discards another card unless he or she pays 3 life.
+ // Target player discards a card. Then that player discards another card unless they pay 3 life.
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new DiscardTargetEffect(1));
this.getSpellAbility().addEffect(new InterrogationEffect());
@@ -44,7 +44,7 @@ class InterrogationEffect extends OneShotEffect {
InterrogationEffect() {
super(Outcome.Discard);
- this.staticText = "Then that player discards another card unless he or she pays 3 life";
+ this.staticText = "Then that player discards another card unless they pay 3 life";
}
InterrogationEffect(final InterrogationEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/i/IntoTheStory.java b/Mage.Sets/src/mage/cards/i/IntoTheStory.java
new file mode 100644
index 00000000000..e48ef7bf07e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/i/IntoTheStory.java
@@ -0,0 +1,63 @@
+package mage.cards.i;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.Graveyard;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class IntoTheStory extends CardImpl {
+
+ public IntoTheStory(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{5}{U}{U}");
+
+ // This spell costs {3} less to cast if an opponent has seven or more cards in their graveyard.
+ this.addAbility(new SimpleStaticAbility(
+ Zone.STACK, new SpellCostReductionSourceEffect(3, IntoTheStoryCondition.instance)
+ ).setRuleAtTheTop(true));
+
+ // Draw four cards.
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(4));
+ }
+
+ private IntoTheStory(final IntoTheStory card) {
+ super(card);
+ }
+
+ @Override
+ public IntoTheStory copy() {
+ return new IntoTheStory(this);
+ }
+}
+
+enum IntoTheStoryCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return game
+ .getOpponents(source.getControllerId())
+ .stream()
+ .map(game::getPlayer)
+ .map(Player::getGraveyard)
+ .mapToInt(Graveyard::size)
+ .anyMatch(i -> i >= 7);
+ }
+
+ @Override
+ public String toString() {
+ return "an opponent has seven or more cards in their graveyard";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/i/InvertTheSkies.java b/Mage.Sets/src/mage/cards/i/InvertTheSkies.java
index 6d7daa38369..23ef03b4eb1 100644
--- a/Mage.Sets/src/mage/cards/i/InvertTheSkies.java
+++ b/Mage.Sets/src/mage/cards/i/InvertTheSkies.java
@@ -43,7 +43,7 @@ public final class InvertTheSkies extends CardImpl {
this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
new LoseAbilityAllEffect(FlyingAbility.getInstance(), Duration.EndOfTurn, filter),
new LockedInCondition(new ManaWasSpentCondition(ColoredManaSymbol.G)),
- "Creatures your opponents control lose flying until end of turn if {G} was spent to cast {this},"));
+ "Creatures your opponents control lose flying until end of turn if {G} was spent to cast this spell,"));
this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
new GainAbilityControlledEffect(FlyingAbility.getInstance(), Duration.EndOfTurn),
diff --git a/Mage.Sets/src/mage/cards/i/InvigoratingFalls.java b/Mage.Sets/src/mage/cards/i/InvigoratingFalls.java
index 4e7747a8619..0b0bd79d2c0 100644
--- a/Mage.Sets/src/mage/cards/i/InvigoratingFalls.java
+++ b/Mage.Sets/src/mage/cards/i/InvigoratingFalls.java
@@ -1,4 +1,3 @@
-
package mage.cards.i;
import java.util.UUID;
@@ -8,7 +7,7 @@ import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -17,10 +16,10 @@ import mage.filter.common.FilterCreatureCard;
public final class InvigoratingFalls extends CardImpl {
public InvigoratingFalls(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{G}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}{G}");
// You gain life equal to the number of creature cards in all graveyards.
- Effect effect = new GainLifeEffect(new CardsInAllGraveyardsCount(new FilterCreatureCard()));
+ Effect effect = new GainLifeEffect(new CardsInAllGraveyardsCount(StaticFilters.FILTER_CARD_CREATURE));
effect.setText("You gain life equal to the number of creature cards in all graveyards.");
this.getSpellAbility().addEffect(effect);
}
diff --git a/Mage.Sets/src/mage/cards/i/IrencragFeat.java b/Mage.Sets/src/mage/cards/i/IrencragFeat.java
new file mode 100644
index 00000000000..022811c4afd
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/i/IrencragFeat.java
@@ -0,0 +1,102 @@
+package mage.cards.i;
+
+import mage.Mana;
+import mage.abilities.Ability;
+import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.mana.BasicManaEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.watchers.common.CastSpellLastTurnWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class IrencragFeat extends CardImpl {
+
+ public IrencragFeat(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}{R}{R}");
+
+ // Add seven {R}. You can cast only one more spell this turn.
+ this.getSpellAbility().addEffect(new IrencragFeatEffect());
+ }
+
+ private IrencragFeat(final IrencragFeat card) {
+ super(card);
+ }
+
+ @Override
+ public IrencragFeat copy() {
+ return new IrencragFeat(this);
+ }
+}
+
+class IrencragFeatEffect extends OneShotEffect {
+
+ private static final Effect effect = new BasicManaEffect(Mana.RedMana(7));
+
+ IrencragFeatEffect() {
+ super(Outcome.Benefit);
+ staticText = "Add seven {R}. You can cast only one more spell this turn.";
+ }
+
+ private IrencragFeatEffect(final IrencragFeatEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public IrencragFeatEffect copy() {
+ return new IrencragFeatEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ CastSpellLastTurnWatcher watcher = game.getState().getWatcher(CastSpellLastTurnWatcher.class);
+ if (watcher == null) {
+ return false;
+ }
+ int spellsCast = watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(source.getControllerId());
+ game.addEffect(new IrencragFeatCantCastEffect(spellsCast), source);
+ return effect.apply(game, source);
+ }
+}
+
+class IrencragFeatCantCastEffect extends ContinuousRuleModifyingEffectImpl {
+
+ private final int spellsCast;
+
+ IrencragFeatCantCastEffect(int spellsCast) {
+ super(Duration.WhileOnBattlefield, Outcome.Detriment);
+ this.spellsCast = spellsCast;
+ }
+
+ private IrencragFeatCantCastEffect(final IrencragFeatCantCastEffect effect) {
+ super(effect);
+ this.spellsCast = effect.spellsCast;
+ }
+
+ @Override
+ public IrencragFeatCantCastEffect copy() {
+ return new IrencragFeatCantCastEffect(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) {
+ CastSpellLastTurnWatcher watcher = game.getState().getWatcher(CastSpellLastTurnWatcher.class);
+ return event.getPlayerId().equals(source.getControllerId())
+ && watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(event.getPlayerId()) > spellsCast + 1;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/i/IrencragPyromancer.java b/Mage.Sets/src/mage/cards/i/IrencragPyromancer.java
new file mode 100644
index 00000000000..15265ab3170
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/i/IrencragPyromancer.java
@@ -0,0 +1,42 @@
+package mage.cards.i;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.DrawSecondCardTriggeredAbility;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.target.common.TargetAnyTarget;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class IrencragPyromancer extends CardImpl {
+
+ public IrencragPyromancer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.WIZARD);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(4);
+
+ // Whenever you draw your second card each turn, Irencrag Pyromancer deals 3 damage to any target.
+ Ability ability = new DrawSecondCardTriggeredAbility(new DamageTargetEffect(3), false);
+ ability.addTarget(new TargetAnyTarget());
+ this.addAbility(ability);
+ }
+
+ private IrencragPyromancer(final IrencragPyromancer card) {
+ super(card);
+ }
+
+ @Override
+ public IrencragPyromancer copy() {
+ return new IrencragPyromancer(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/i/IroasGodOfVictory.java b/Mage.Sets/src/mage/cards/i/IroasGodOfVictory.java
index b964156ea1d..539f75b68aa 100644
--- a/Mage.Sets/src/mage/cards/i/IroasGodOfVictory.java
+++ b/Mage.Sets/src/mage/cards/i/IroasGodOfVictory.java
@@ -1,11 +1,8 @@
-
package mage.cards.i;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.DevotionCount;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.PreventAllDamageToAllEffect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
@@ -14,26 +11,31 @@ import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
-import mage.filter.common.FilterControlledCreatureInPlay;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.AttackingPredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class IroasGodOfVictory extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures you control");
- private static final FilterControlledCreatureInPlay filterAttacking = new FilterControlledCreatureInPlay("attacking creatures you control");
+ private static final FilterPermanent filter
+ = new FilterCreaturePermanent("Creatures you control");
+ private static final FilterPermanent filterAttacking
+ = new FilterControlledCreaturePermanent("attacking creatures you control");
+
static {
filter.add(new ControllerPredicate(TargetController.YOU));
- filterAttacking.getCreatureFilter().add(AttackingPredicate.instance);
+ filterAttacking.add(AttackingPredicate.instance);
}
-
+
public IroasGodOfVictory(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{2}{R}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{2}{R}{W}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.GOD);
@@ -42,21 +44,23 @@ public final class IroasGodOfVictory extends CardImpl {
// Indestructible
this.addAbility(IndestructibleAbility.getInstance());
-
+
// As long as your devotion to red and white is less than seven, Iroas isn't a creature.
- Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.R, ColoredManaSymbol.W), 7);
- effect.setText("As long as your devotion to red and white is less than seven, Iroas isn't a creature");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
-
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.RW, 7))
+ .addHint(DevotionCount.RW.getHint()));
+
// Creatures you control have menace. (They can't be blocked except by two or more creatures.)
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(new MenaceAbility(), Duration.WhileOnBattlefield, filter)));
-
+ this.addAbility(new SimpleStaticAbility(
+ new GainAbilityAllEffect(new MenaceAbility(), Duration.WhileOnBattlefield, filter)
+ ));
+
// Prevent all damage that would be dealt to attacking creatures you control.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventAllDamageToAllEffect(Duration.WhileOnBattlefield, filterAttacking)));
-
+ this.addAbility(new SimpleStaticAbility(
+ new PreventAllDamageToAllEffect(Duration.WhileOnBattlefield, filterAttacking)
+ ));
}
- public IroasGodOfVictory(final IroasGodOfVictory card) {
+ private IroasGodOfVictory(final IroasGodOfVictory card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/i/IronscaleHydra.java b/Mage.Sets/src/mage/cards/i/IronscaleHydra.java
new file mode 100644
index 00000000000..b9c8cfd6fba
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/i/IronscaleHydra.java
@@ -0,0 +1,81 @@
+package mage.cards.i;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.PreventionEffectImpl;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class IronscaleHydra extends CardImpl {
+
+ public IronscaleHydra(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}");
+
+ this.subtype.add(SubType.HYDRA);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(5);
+
+ // If a creature would deal combat damage to Ironscale Hydra, prevent that damage and put a +1/+1 counter on Ironscale Hydra.
+ this.addAbility(new SimpleStaticAbility(new IronscaleHydraEffect()));
+ }
+
+ private IronscaleHydra(final IronscaleHydra card) {
+ super(card);
+ }
+
+ @Override
+ public IronscaleHydra copy() {
+ return new IronscaleHydra(this);
+ }
+}
+
+class IronscaleHydraEffect extends PreventionEffectImpl {
+
+ private static final Effect effect = new AddCountersSourceEffect(CounterType.P1P1.createInstance());
+
+ IronscaleHydraEffect() {
+ super(Duration.WhileOnBattlefield, Integer.MAX_VALUE, true, false);
+ staticText = "If a creature would deal combat damage to {this}, " +
+ "prevent that damage and put a +1/+1 counter on {this}.";
+ }
+
+ private IronscaleHydraEffect(final IronscaleHydraEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public IronscaleHydraEffect copy() {
+ return new IronscaleHydraEffect(this);
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ if (!super.applies(event, source, game)
+ || !event.getTargetId().equals(source.getSourceId())) {
+ return false;
+ }
+ Permanent damageSource = game.getPermanent(event.getSourceId());
+ return damageSource != null && damageSource.isCreature();
+ }
+
+ @Override
+ public boolean replaceEvent(GameEvent event, Ability source, Game game) {
+ effect.apply(game, source);
+ return super.replaceEvent(event, source, game);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/i/IrresistiblePrey.java b/Mage.Sets/src/mage/cards/i/IrresistiblePrey.java
index fb8579bc801..7f6f2d13c26 100644
--- a/Mage.Sets/src/mage/cards/i/IrresistiblePrey.java
+++ b/Mage.Sets/src/mage/cards/i/IrresistiblePrey.java
@@ -2,15 +2,12 @@
package mage.cards.i;
import java.util.UUID;
-import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneTargetEffect;
-import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
-import mage.constants.Zone;
import mage.target.common.TargetCreaturePermanent;
/**
@@ -25,10 +22,7 @@ public final class IrresistiblePrey extends CardImpl {
// Target creature must be blocked this turn if able.
// Draw a card.
- this.getSpellAbility().addEffect(
- new GainAbilityTargetEffect(
- new SimpleStaticAbility(Zone.BATTLEFIELD, new MustBeBlockedByAtLeastOneTargetEffect()),
- Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
}
diff --git a/Mage.Sets/src/mage/cards/i/IslandSanctuary.java b/Mage.Sets/src/mage/cards/i/IslandSanctuary.java
index b5effdc0e10..6c205c394ea 100644
--- a/Mage.Sets/src/mage/cards/i/IslandSanctuary.java
+++ b/Mage.Sets/src/mage/cards/i/IslandSanctuary.java
@@ -67,7 +67,7 @@ class IslandSanctuaryEffect extends ReplacementEffectImpl {
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player controller = game.getPlayer(event.getPlayerId());
if (controller != null && controller.chooseUse(outcome, "Skip draw card? (If you do, until your next turn, you can't be attacked except by creatures with flying and/or islandwalk)", source, game)) {
- game.informPlayers(controller.getLogName() + " skips their draw card action. Until their next turn, he or she can't be attacked except by creatures with flying and/or islandwalk");
+ game.informPlayers(controller.getLogName() + " skips their draw card action. Until their next turn, they can't be attacked except by creatures with flying and/or islandwalk");
game.addEffect(new CantAttackYouAllEffect(Duration.UntilYourNextTurn, notFlyingorIslandwalkCreatures), source);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/i/IsochronScepter.java b/Mage.Sets/src/mage/cards/i/IsochronScepter.java
index 832952667ce..0079f3c737a 100644
--- a/Mage.Sets/src/mage/cards/i/IsochronScepter.java
+++ b/Mage.Sets/src/mage/cards/i/IsochronScepter.java
@@ -1,4 +1,3 @@
-
package mage.cards.i;
import java.util.UUID;
@@ -35,11 +34,15 @@ public final class IsochronScepter extends CardImpl {
public IsochronScepter(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
- // Imprint - When Isochron Scepter enters the battlefield, you may exile an instant card with converted mana cost 2 or less from your hand.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new IsochronScepterImprintEffect(), true, "Imprint — "));
+ // Imprint - When Isochron Scepter enters the battlefield, you may exile an
+ // instant card with converted mana cost 2 or less from your hand.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new IsochronScepterImprintEffect(),
+ true, "Imprint — "));
- // {2}, {tap}: You may copy the exiled card. If you do, you may cast the copy without paying its mana cost.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new IsochronScepterCopyEffect(), new GenericManaCost(2));
+ // {2}, {tap}: You may copy the exiled card. If you do, you may cast the
+ // copy without paying its mana cost.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
+ new IsochronScepterCopyEffect(), new GenericManaCost(2));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
@@ -57,7 +60,8 @@ public final class IsochronScepter extends CardImpl {
class IsochronScepterImprintEffect extends OneShotEffect {
- private static final FilterCard filter = new FilterCard("instant card with converted mana cost 2 or less from your hand");
+ private static final FilterCard filter = new FilterCard("instant card with "
+ + "converted mana cost 2 or less from your hand");
static {
filter.add(new CardTypePredicate(CardType.INSTANT));
@@ -66,7 +70,8 @@ class IsochronScepterImprintEffect extends OneShotEffect {
public IsochronScepterImprintEffect() {
super(Outcome.Benefit);
- staticText = "you may exile an instant card with converted mana cost 2 or less from your hand";
+ staticText = "you may exile an instant card with converted mana "
+ + "cost 2 or less from your hand";
}
public IsochronScepterImprintEffect(IsochronScepterImprintEffect effect) {
@@ -84,11 +89,13 @@ class IsochronScepterImprintEffect extends OneShotEffect {
&& controller.choose(Outcome.Benefit, controller.getHand(), target, game)) {
Card card = controller.getHand().get(target.getFirstTarget(), game);
if (card != null) {
- controller.moveCardToExileWithInfo(card, source.getSourceId(), sourcePermanent.getIdName() + " (Imprint)", source.getSourceId(), game, Zone.HAND, true);
+ controller.moveCardsToExile(card, source, game, true, source.getSourceId(),
+ sourcePermanent.getIdName() + " (Imprint)");
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
permanent.imprint(card.getId(), game);
- permanent.addInfo("imprint", CardUtil.addToolTipMarkTags("[Imprinted card - " + card.getLogName() + ']'), game);
+ permanent.addInfo("imprint", CardUtil.addToolTipMarkTags(
+ "[Imprinted card - " + card.getLogName() + ']'), game);
}
}
}
@@ -110,7 +117,8 @@ class IsochronScepterCopyEffect extends OneShotEffect {
public IsochronScepterCopyEffect() {
super(Outcome.Copy);
- this.staticText = "You may copy the exiled card. If you do, you may cast the copy without paying its mana cost";
+ this.staticText = "You may copy the exiled card. If you do, "
+ + "you may cast the copy without paying its mana cost";
}
public IsochronScepterCopyEffect(final IsochronScepterCopyEffect effect) {
@@ -127,9 +135,12 @@ class IsochronScepterCopyEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Permanent scepter = game.getPermanentOrLKIBattlefield(source.getSourceId());
- if (scepter != null && scepter.getImprinted() != null && !scepter.getImprinted().isEmpty()) {
+ if (scepter != null
+ && scepter.getImprinted() != null
+ && !scepter.getImprinted().isEmpty()) {
Card imprintedInstant = game.getCard(scepter.getImprinted().get(0));
- if (imprintedInstant != null && game.getState().getZone(imprintedInstant.getId()) == Zone.EXILED) {
+ if (imprintedInstant != null
+ && game.getState().getZone(imprintedInstant.getId()) == Zone.EXILED) {
if (controller.chooseUse(outcome, "Create a copy of " + imprintedInstant.getName() + '?', source, game)) {
Card copiedCard = game.copyCard(imprintedInstant, source, source.getControllerId());
if (copiedCard != null) {
@@ -137,9 +148,13 @@ class IsochronScepterCopyEffect extends OneShotEffect {
game.getState().setZone(copiedCard.getId(), Zone.EXILED);
if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
if (copiedCard.getSpellAbility() != null) {
- controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(copiedCard, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), null);
} else {
- Logger.getLogger(IsochronScepterCopyEffect.class).error("Isochron Scepter: spell ability == null " + copiedCard.getName());
+ Logger.getLogger(IsochronScepterCopyEffect.class).error("Isochron Scepter: "
+ + "spell ability == null " + copiedCard.getName());
}
}
}
diff --git a/Mage.Sets/src/mage/cards/i/IsolationCell.java b/Mage.Sets/src/mage/cards/i/IsolationCell.java
index 917e0622dc8..0dd7e6e0e8e 100644
--- a/Mage.Sets/src/mage/cards/i/IsolationCell.java
+++ b/Mage.Sets/src/mage/cards/i/IsolationCell.java
@@ -26,7 +26,7 @@ public final class IsolationCell extends CardImpl {
public IsolationCell(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
- // Whenever an opponent casts a creature spell, that player loses 2 life unless he or she pays {2}.
+ // Whenever an opponent casts a creature spell, that player loses 2 life unless they pay {2}.
this.addAbility(new IsolationCellTriggeredAbility());
}
@@ -75,7 +75,7 @@ class IsolationCellTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
- return "Whenever an opponent casts a creature spell, that player loses 2 life unless he or she pays {2}.";
+ return "Whenever an opponent casts a creature spell, that player loses 2 life unless they pay {2}.";
}
}
@@ -83,7 +83,7 @@ class IsolationCellEffect extends OneShotEffect {
public IsolationCellEffect() {
super(Outcome.Neutral);
- this.staticText = "that player loses 2 life unless he or she pays {2}";
+ this.staticText = "that player loses 2 life unless they pay {2}";
}
public IsolationCellEffect(final IsolationCellEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/i/IsperiaTheInscrutable.java b/Mage.Sets/src/mage/cards/i/IsperiaTheInscrutable.java
index 25d5ee7a915..d9b11cca217 100644
--- a/Mage.Sets/src/mage/cards/i/IsperiaTheInscrutable.java
+++ b/Mage.Sets/src/mage/cards/i/IsperiaTheInscrutable.java
@@ -40,7 +40,7 @@ public final class IsperiaTheInscrutable extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
- // Whenever Isperia the Inscrutable deals combat damage to a player, name a card. That player reveals their hand. If he or she reveals the named card, search your library for a creature card with flying, reveal it, put it into your hand, then shuffle your library.
+ // Whenever Isperia the Inscrutable deals combat damage to a player, name a card. That player reveals their hand. If they reveal the named card, search your library for a creature card with flying, reveal it, put it into your hand, then shuffle your library.
Effect effect1 = new ChooseACardNameEffect(ChooseACardNameEffect.TypeOfName.ALL);
Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect1, false, true);
Effect effect2 = new IsperiaTheInscrutableEffect();
diff --git a/Mage.Sets/src/mage/cards/i/IzzetChemister.java b/Mage.Sets/src/mage/cards/i/IzzetChemister.java
index 66e434e0994..201edddb6f9 100644
--- a/Mage.Sets/src/mage/cards/i/IzzetChemister.java
+++ b/Mage.Sets/src/mage/cards/i/IzzetChemister.java
@@ -1,4 +1,3 @@
-
package mage.cards.i;
import java.util.UUID;
@@ -83,7 +82,7 @@ public final class IzzetChemister extends CardImpl {
class IzzetChemisterCastFromExileEffect extends OneShotEffect {
- private UUID exileId;
+ private final UUID exileId;
public IzzetChemisterCastFromExileEffect(UUID exileId, String description) {
super(Outcome.PlayForFree);
@@ -106,7 +105,8 @@ class IzzetChemisterCastFromExileEffect extends OneShotEffect {
ExileZone exile = game.getExile().getExileZone(exileId);
Player controller = game.getPlayer(source.getControllerId());
FilterCard filter = new FilterCard();
- if (controller != null && exile != null) {
+ if (controller != null
+ && exile != null) {
Cards cardsToExile = new CardsImpl();
cardsToExile.addAll(exile.getCards(game));
OuterLoop:
@@ -116,11 +116,17 @@ class IzzetChemisterCastFromExileEffect extends OneShotEffect {
}
TargetCardInExile target = new TargetCardInExile(0, 1, filter, exileId, false);
target.setNotTarget(true);
- while (cardsToExile.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, cardsToExile, target, game)) {
+ while (cardsToExile.count(filter, game) > 0
+ && controller.choose(Outcome.PlayForFree, cardsToExile, target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
- cardsToExile.remove(card);
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true), game, true,
+ new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (cardWasCast) {
+ cardsToExile.remove(card);
+ }
} else {
break OuterLoop;
}
diff --git a/Mage.Sets/src/mage/cards/i/IzzetKeyrune.java b/Mage.Sets/src/mage/cards/i/IzzetKeyrune.java
index a2a2a59ab9f..992bca57bcb 100644
--- a/Mage.Sets/src/mage/cards/i/IzzetKeyrune.java
+++ b/Mage.Sets/src/mage/cards/i/IzzetKeyrune.java
@@ -72,7 +72,7 @@ public final class IzzetKeyrune extends CardImpl {
Player player = game.getPlayer(source.getControllerId());
if (player != null && player.chooseUse(Outcome.DrawCard, "Do you wish to draw a card? If you do, discard a card.", source, game)) {
if (player.drawCards(1, game) > 0) {
- player.discard(1, source, game);
+ player.discard(1, false, source, game);
}
return true;
}
diff --git a/Mage.Sets/src/mage/cards/j/JaceArcaneStrategist.java b/Mage.Sets/src/mage/cards/j/JaceArcaneStrategist.java
index bbaeeef62d9..cec4fe502cd 100644
--- a/Mage.Sets/src/mage/cards/j/JaceArcaneStrategist.java
+++ b/Mage.Sets/src/mage/cards/j/JaceArcaneStrategist.java
@@ -1,18 +1,20 @@
package mage.cards.j;
+import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
-import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.DrawSecondCardTriggeredAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.combat.CantBeBlockedAllEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.SuperType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
-import mage.game.Game;
-import mage.game.events.GameEvent;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
@@ -30,7 +32,11 @@ public final class JaceArcaneStrategist extends CardImpl {
this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
// Whenever you draw your second card each turn, put a +1/+1 counter on target creature you control.
- this.addAbility(new JaceArcaneStrategistTriggeredAbility());
+ Ability ability = new DrawSecondCardTriggeredAbility(
+ new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false
+ );
+ ability.addTarget(new TargetControlledCreaturePermanent());
+ this.addAbility(ability);
// +1: Draw a card.
this.addAbility(new LoyaltyAbility(new DrawCardSourceControllerEffect(1), 1));
@@ -50,59 +56,3 @@ public final class JaceArcaneStrategist extends CardImpl {
return new JaceArcaneStrategist(this);
}
}
-
-class JaceArcaneStrategistTriggeredAbility extends TriggeredAbilityImpl {
-
- private boolean triggeredOnce = false;
- private boolean triggeredTwice = false;
-
- JaceArcaneStrategistTriggeredAbility() {
- super(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false);
- this.addTarget(new TargetControlledCreaturePermanent());
- }
-
- private JaceArcaneStrategistTriggeredAbility(final JaceArcaneStrategistTriggeredAbility ability) {
- super(ability);
- this.triggeredOnce = ability.triggeredOnce;
- this.triggeredTwice = ability.triggeredTwice;
- }
-
- @Override
- public boolean checkEventType(GameEvent event, Game game) {
- return event.getType() == GameEvent.EventType.DREW_CARD
- || event.getType() == GameEvent.EventType.END_PHASE_POST;
- }
-
- @Override
- public boolean checkTrigger(GameEvent event, Game game) {
- if (event.getType() == GameEvent.EventType.END_PHASE_POST) {
- triggeredOnce = triggeredTwice = false;
- return false;
- }
- if (event.getType() == GameEvent.EventType.DREW_CARD
- && event.getPlayerId().equals(controllerId)) {
- if (triggeredOnce) {
- if (triggeredTwice) {
- return false;
- } else {
- triggeredTwice = true;
- return true;
- }
- } else {
- triggeredOnce = true;
- return false;
- }
- }
- return false;
- }
-
- @Override
- public String getRule() {
- return "Whenever you draw your second card each turn, put a +1/+1 counter on target creature you control.";
- }
-
- @Override
- public JaceArcaneStrategistTriggeredAbility copy() {
- return new JaceArcaneStrategistTriggeredAbility(this);
- }
-}
diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java
index f4030e71483..e8137b8f2f3 100644
--- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java
+++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java
@@ -59,10 +59,12 @@ public final class JaceArchitectOfThought extends CardImpl {
// +1: Until your next turn, whenever a creature an opponent controls attacks, it gets -1/-0 until end of turn.
this.addAbility(new LoyaltyAbility(new JaceArchitectOfThoughtStartEffect1(), 1));
- // -2: Reveal the top three cards of your library. An opponent separates those cards into two piles. Put one pile into your hand and the other on the bottom of your library in any order.
+ // -2: Reveal the top three cards of your library. An opponent separates those cards into two piles.
+ // Put one pile into your hand and the other on the bottom of your library in any order.
this.addAbility(new LoyaltyAbility(new JaceArchitectOfThoughtEffect2(), -2));
- // -8: For each player, search that player's library for a nonland card and exile it, then that player shuffles their library. You may cast those cards without paying their mana costs.
+ // -8: For each player, search that player's library for a nonland card and exile it,
+ // then that player shuffles their library. You may cast those cards without paying their mana costs.
this.addAbility(new LoyaltyAbility(new JaceArchitectOfThoughtEffect3(), -8));
}
@@ -81,7 +83,8 @@ class JaceArchitectOfThoughtStartEffect1 extends OneShotEffect {
public JaceArchitectOfThoughtStartEffect1() {
super(Outcome.UnboostCreature);
- this.staticText = "Until your next turn, whenever a creature an opponent controls attacks, it gets -1/-0 until end of turn";
+ this.staticText = "Until your next turn, whenever a creature an opponent "
+ + "controls attacks, it gets -1/-0 until end of turn";
}
public JaceArchitectOfThoughtStartEffect1(final JaceArchitectOfThoughtStartEffect1 effect) {
@@ -138,7 +141,8 @@ class JaceArchitectOfThoughtDelayedTriggeredAbility extends DelayedTriggeredAbil
@Override
public boolean isInactive(Game game) {
- return game.isActivePlayer(getControllerId()) && game.getTurnNum() != startingTurn;
+ return game.isActivePlayer(getControllerId())
+ && game.getTurnNum() != startingTurn;
}
@Override
@@ -151,7 +155,8 @@ class JaceArchitectOfThoughtEffect2 extends OneShotEffect {
public JaceArchitectOfThoughtEffect2() {
super(Outcome.DrawCard);
- this.staticText = "Reveal the top three cards of your library. An opponent separates those cards into two piles. Put one pile into your hand and the other on the bottom of your library in any order";
+ this.staticText = "Reveal the top three cards of your library. An opponent separates those cards "
+ + "into two piles. Put one pile into your hand and the other on the bottom of your library in any order";
}
public JaceArchitectOfThoughtEffect2(final JaceArchitectOfThoughtEffect2 effect) {
@@ -223,7 +228,8 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect {
public JaceArchitectOfThoughtEffect3() {
super(Outcome.PlayForFree);
- this.staticText = "For each player, search that player's library for a nonland card and exile it, then that player shuffles their library. You may cast those cards without paying their mana costs";
+ this.staticText = "For each player, search that player's library for a nonland card and exile it, "
+ + "then that player shuffles their library. You may cast those cards without paying their mana costs";
}
public JaceArchitectOfThoughtEffect3(final JaceArchitectOfThoughtEffect3 effect) {
@@ -303,7 +309,11 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect {
controller.choose(Outcome.PlayForFree, jaceExileZone, target, game);
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
- if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (cardWasCast) {
game.getExile().removeCard(card, game);
}
}
diff --git a/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java b/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java
index f4bd134f436..38841f67475 100644
--- a/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java
+++ b/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java
@@ -1,24 +1,17 @@
package mage.cards.j;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DrawDiscardControllerEffect;
-import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.SuperType;
+import mage.constants.*;
import mage.game.Game;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent;
@@ -26,8 +19,11 @@ import mage.game.permanent.Permanent;
import mage.game.permanent.token.JaceCunningCastawayIllusionToken;
import mage.target.targetpointer.FixedTarget;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
/**
- *
* @author TheElk801
*/
public final class JaceCunningCastaway extends CardImpl {
@@ -50,7 +46,7 @@ public final class JaceCunningCastaway extends CardImpl {
this.addAbility(new LoyaltyAbility(new JaceCunningCastawayCopyEffect(), -5));
}
- public JaceCunningCastaway(final JaceCunningCastaway card) {
+ private JaceCunningCastaway(final JaceCunningCastaway card) {
super(card);
}
@@ -62,12 +58,12 @@ public final class JaceCunningCastaway extends CardImpl {
class JaceCunningCastawayEffect1 extends OneShotEffect {
- public JaceCunningCastawayEffect1() {
+ JaceCunningCastawayEffect1() {
super(Outcome.DrawCard);
this.staticText = "Whenever one or more creatures you control deal combat damage to a player this turn, draw a card, then discard a card";
}
- public JaceCunningCastawayEffect1(final JaceCunningCastawayEffect1 effect) {
+ private JaceCunningCastawayEffect1(final JaceCunningCastawayEffect1 effect) {
super(effect);
}
@@ -86,13 +82,13 @@ class JaceCunningCastawayEffect1 extends OneShotEffect {
class JaceCunningCastawayDamageTriggeredAbility extends DelayedTriggeredAbility {
- List damagedPlayerIds = new ArrayList<>();
+ private final List damagedPlayerIds = new ArrayList<>();
- public JaceCunningCastawayDamageTriggeredAbility() {
+ JaceCunningCastawayDamageTriggeredAbility() {
super(new DrawDiscardControllerEffect(1, 1), Duration.EndOfTurn, false);
}
- public JaceCunningCastawayDamageTriggeredAbility(final JaceCunningCastawayDamageTriggeredAbility ability) {
+ private JaceCunningCastawayDamageTriggeredAbility(final JaceCunningCastawayDamageTriggeredAbility ability) {
super(ability);
}
@@ -104,7 +100,7 @@ class JaceCunningCastawayDamageTriggeredAbility extends DelayedTriggeredAbility
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_PLAYER
- || event.getType() == GameEvent.EventType.END_COMBAT_STEP_POST;
+ || event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_POST;
}
@Override
@@ -119,7 +115,7 @@ class JaceCunningCastawayDamageTriggeredAbility extends DelayedTriggeredAbility
}
}
}
- if (event.getType() == GameEvent.EventType.END_COMBAT_STEP_POST) {
+ if (event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_POST) {
damagedPlayerIds.clear();
}
return false;
@@ -138,7 +134,7 @@ class JaceCunningCastawayCopyEffect extends OneShotEffect {
this.staticText = "Create two tokens that are copies of {this}, except they're not legendary";
}
- JaceCunningCastawayCopyEffect(final JaceCunningCastawayCopyEffect effect) {
+ private JaceCunningCastawayCopyEffect(final JaceCunningCastawayCopyEffect effect) {
super(effect);
}
@@ -150,12 +146,12 @@ class JaceCunningCastawayCopyEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
- if (permanent != null) {
- CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, false, 2);
- effect.setTargetPointer(new FixedTarget(source.getSourceId(), game));
- effect.setIsntLegendary(true);
- return effect.apply(game, source);
+ if (permanent == null) {
+ return false;
}
- return false;
+ CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, false, 2);
+ effect.setTargetPointer(new FixedTarget(source.getSourceId(), game));
+ effect.setIsntLegendary(true);
+ return effect.apply(game, source);
}
}
diff --git a/Mage.Sets/src/mage/cards/j/JacesMindseeker.java b/Mage.Sets/src/mage/cards/j/JacesMindseeker.java
index 2b9cc0da59a..dd0f2354fe6 100644
--- a/Mage.Sets/src/mage/cards/j/JacesMindseeker.java
+++ b/Mage.Sets/src/mage/cards/j/JacesMindseeker.java
@@ -1,4 +1,3 @@
-
package mage.cards.j;
import java.util.HashSet;
@@ -42,7 +41,8 @@ public final class JacesMindseeker extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
- // When Jace's Mindseeker enters the battlefield, target opponent puts the top five cards of their library into their graveyard.
+ // When Jace's Mindseeker enters the battlefield, target opponent puts
+ // the top five cards of their library into their graveyard.
// You may cast an instant or sorcery card from among them without paying its mana cost.
Ability ability = new EntersBattlefieldTriggeredAbility(new JaceMindseekerEffect());
ability.addTarget(new TargetOpponent());
@@ -65,7 +65,9 @@ class JaceMindseekerEffect extends OneShotEffect {
public JaceMindseekerEffect() {
super(Outcome.PlayForFree);
- this.staticText = "target opponent puts the top five cards of their library into their graveyard. You may cast an instant or sorcery card from among them without paying its mana cost";
+ this.staticText = "target opponent puts the top five cards of their "
+ + "library into their graveyard. You may cast an instant or "
+ + "sorcery card from among them without paying its mana cost";
}
public JaceMindseekerEffect(final JaceMindseekerEffect effect) {
@@ -89,9 +91,11 @@ class JaceMindseekerEffect extends OneShotEffect {
for (Card card : allCards) {
if (filter.match(card, game)) {
Zone zone = game.getState().getZone(card.getId());
- // If the five cards are put into a public zone such as exile instead of a graveyard (perhaps due to the ability of Rest in Peace),
+ // If the five cards are put into a public zone such as exile instead
+ // of a graveyard (perhaps due to the ability of Rest in Peace),
// you can cast one of those instant or sorcery cards from that zone.
- if (zone == Zone.GRAVEYARD || zone == Zone.EXILED) {
+ if (zone == Zone.GRAVEYARD
+ || zone == Zone.EXILED) {
cardsToCast.add(card);
}
}
@@ -104,10 +108,13 @@ class JaceMindseekerEffect extends OneShotEffect {
TargetCard target = new TargetCard(Zone.GRAVEYARD, filter); // zone should be ignored here
target.setNotTarget(true);
if (controller.chooseUse(outcome, "Cast an instant or sorcery card from among them for free?", source, game)
- && controller.choose(outcome, cardsToCast, target, game)) {
+ && controller.choose(Outcome.PlayForFree, cardsToCast, target, game)) {
Card card = cardsToCast.get(target.getFirstTarget(), game);
if (card != null) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
}
diff --git a/Mage.Sets/src/mage/cards/j/JaradGolgariLichLord.java b/Mage.Sets/src/mage/cards/j/JaradGolgariLichLord.java
index e895731ea58..761115fe648 100644
--- a/Mage.Sets/src/mage/cards/j/JaradGolgariLichLord.java
+++ b/Mage.Sets/src/mage/cards/j/JaradGolgariLichLord.java
@@ -1,4 +1,3 @@
-
package mage.cards.j;
import java.util.UUID;
@@ -19,7 +18,6 @@ import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledPermanent;
-import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetControlledPermanent;
@@ -48,7 +46,7 @@ public final class JaradGolgariLichLord extends CardImpl {
this.toughness = new MageInt(2);
// Jarad, Golgari Lich Lord gets +1/+1 for each creature card in your graveyard.
- DynamicValue amount = new CardsInControllerGraveyardCount(new FilterCreatureCard());
+ DynamicValue amount = new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE);
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(amount, amount, Duration.WhileOnBattlefield));
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/j/JeskaiInfiltrator.java b/Mage.Sets/src/mage/cards/j/JeskaiInfiltrator.java
index 668374e0b07..654d6093374 100644
--- a/Mage.Sets/src/mage/cards/j/JeskaiInfiltrator.java
+++ b/Mage.Sets/src/mage/cards/j/JeskaiInfiltrator.java
@@ -91,12 +91,12 @@ class JeskaiInfiltratorEffect extends OneShotEffect {
for (Card card : exileZone.getCards(game)) {
card.setFaceDown(true, game);
}
- game.fireUpdatePlayersEvent(); // removes Jeskai from Battlefield, so he returns as a fresh permanent to the battlefield with new position
+ game.fireUpdatePlayersEvent(); // removes Jeskai Infiltrator from Battlefield, so Jeskai Infiltrator returns as a fresh permanent to the battlefield with new position
Ability newSource = source.copy();
newSource.setWorksFaceDown(true);
- while (!exileZone.isEmpty()) {
- Card card = exileZone.getRandom(game);
+ //the Set will mimic the Shuffling
+ exileZone.getCards(game).forEach(card -> {
ManaCosts manaCosts = null;
if (card.isCreature()) {
manaCosts = card.getSpellAbility().getManaCosts();
@@ -106,7 +106,7 @@ class JeskaiInfiltratorEffect extends OneShotEffect {
}
MageObjectReference objectReference = new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) + 1, game);
game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource);
- }
+ });
controller.moveCards(exileZone.getCards(game), Zone.BATTLEFIELD, source, game, false, true, false, null);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/j/Jokulmorder.java b/Mage.Sets/src/mage/cards/j/Jokulmorder.java
index dfe4138831a..121acc632a3 100644
--- a/Mage.Sets/src/mage/cards/j/Jokulmorder.java
+++ b/Mage.Sets/src/mage/cards/j/Jokulmorder.java
@@ -1,4 +1,3 @@
-
package mage.cards.j;
import mage.MageInt;
@@ -27,7 +26,6 @@ import mage.target.common.TargetControlledPermanent;
import java.util.UUID;
/**
- *
* @author fireshoes
*/
public final class Jokulmorder extends CardImpl {
@@ -85,7 +83,8 @@ class JokulmorderTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent land = game.getPermanent(event.getTargetId());
- return land.hasSubtype(SubType.ISLAND, game)
+ return land != null
+ && land.hasSubtype(SubType.ISLAND, game)
&& land.isControlledBy(this.controllerId);
}
diff --git a/Mage.Sets/src/mage/cards/j/Joust.java b/Mage.Sets/src/mage/cards/j/Joust.java
new file mode 100644
index 00000000000..c6ccef240f5
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/j/Joust.java
@@ -0,0 +1,88 @@
+package mage.cards.j;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.ContinuousEffect;
+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.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetControlledCreaturePermanent;
+import mage.target.targetpointer.FixedTarget;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class Joust extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterCreaturePermanent("creature you don't control");
+
+ static {
+ filter.add(new ControllerPredicate(TargetController.NOT_YOU));
+ }
+
+ public Joust(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}");
+
+ // Choose target creature you control and target creature you don't control. The creature you control gets +2/+1 until end of turn if it's a Knight. Then those creatures fight each other.
+ this.getSpellAbility().addEffect(new JoustEffect());
+ this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
+ this.getSpellAbility().addTarget(new TargetPermanent(filter));
+ }
+
+ private Joust(final Joust card) {
+ super(card);
+ }
+
+ @Override
+ public Joust copy() {
+ return new Joust(this);
+ }
+}
+
+class JoustEffect extends OneShotEffect {
+
+ JoustEffect() {
+ super(Outcome.Benefit);
+ staticText = "Choose target creature you control and target creature you don't control. " +
+ "The creature you control gets +2/+1 until end of turn if it's a Knight. " +
+ "Then those creatures fight each other.";
+ }
+
+ private JoustEffect(final JoustEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public JoustEffect copy() {
+ return new JoustEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent creature1 = game.getPermanent(source.getTargets().get(0).getFirstTarget());
+ Permanent creature2 = game.getPermanent(source.getTargets().get(1).getFirstTarget());
+ if (creature1 == null) {
+ return false;
+ }
+ if (creature1.hasSubtype(SubType.KNIGHT, game)) {
+ ContinuousEffect effect = new BoostTargetEffect(2, 1, Duration.EndOfTurn);
+ effect.setTargetPointer(new FixedTarget(creature1.getId(), game));
+ game.addEffect(effect, source);
+ }
+ if (creature2 == null) {
+ return true;
+ }
+ game.applyEffects();
+ return creature1.fight(creature2, source, game);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/j/JoustingDummy.java b/Mage.Sets/src/mage/cards/j/JoustingDummy.java
new file mode 100644
index 00000000000..a6a4d73cdc8
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/j/JoustingDummy.java
@@ -0,0 +1,42 @@
+package mage.cards.j;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class JoustingDummy extends CardImpl {
+
+ public JoustingDummy(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}");
+
+ this.subtype.add(SubType.SCARECROW);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(1);
+
+ // {3}: Jousting Dummy gets +1/+0 until end of turn.
+ this.addAbility(new SimpleActivatedAbility(
+ new BoostSourceEffect(1, 0, Duration.EndOfTurn), new GenericManaCost(3)
+ ));
+ }
+
+ private JoustingDummy(final JoustingDummy card) {
+ super(card);
+ }
+
+ @Override
+ public JoustingDummy copy() {
+ return new JoustingDummy(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/k/KaaliaZenithSeeker.java b/Mage.Sets/src/mage/cards/k/KaaliaZenithSeeker.java
index dae541d8ee0..527e6b533ae 100644
--- a/Mage.Sets/src/mage/cards/k/KaaliaZenithSeeker.java
+++ b/Mage.Sets/src/mage/cards/k/KaaliaZenithSeeker.java
@@ -1,5 +1,6 @@
package mage.cards.k;
+import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -18,8 +19,6 @@ import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary;
-import java.util.UUID;
-
/**
* @author TheElk801
*/
@@ -75,10 +74,10 @@ class KaaliaZenithSeekerEffect extends OneShotEffect {
KaaliaZenithSeekerEffect() {
super(Outcome.Benefit);
- staticText = "look at the top six cards of your library. " +
- "You may reveal an Angel card, a Demon card, and/or a Dragon card " +
- "from among them and put them into your hand. " +
- "Put the rest on the bottom of your library in a random order.";
+ staticText = "look at the top six cards of your library. "
+ + "You may reveal an Angel card, a Demon card, and/or a Dragon card "
+ + "from among them and put them into your hand. "
+ + "Put the rest on the bottom of your library in a random order.";
}
private KaaliaZenithSeekerEffect(final KaaliaZenithSeekerEffect effect) {
@@ -105,6 +104,7 @@ class KaaliaZenithSeekerEffect extends OneShotEffect {
}
}
cards.removeAll(toHand);
+ player.revealCards(source, toHand, game);
player.moveCards(toHand, Zone.HAND, source, game);
player.putCardsOnBottomOfLibrary(cards, game, source, false);
return true;
diff --git a/Mage.Sets/src/mage/cards/k/KahoMinamoHistorian.java b/Mage.Sets/src/mage/cards/k/KahoMinamoHistorian.java
index cc3c297d346..432b0f8d1c4 100644
--- a/Mage.Sets/src/mage/cards/k/KahoMinamoHistorian.java
+++ b/Mage.Sets/src/mage/cards/k/KahoMinamoHistorian.java
@@ -1,4 +1,3 @@
-
package mage.cards.k;
import java.util.UUID;
@@ -42,11 +41,14 @@ public final class KahoMinamoHistorian extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- // When Kaho, Minamo Historian enters the battlefield, search your library for up to three instant cards and exile them. Then shuffle your library.
+ // When Kaho, Minamo Historian enters the battlefield, search your library for up to three
+ // instant cards and exile them. Then shuffle your library.
this.addAbility(new EntersBattlefieldTriggeredAbility(new KahoMinamoHistorianEffect(), false));
- // {X}, {tap}: You may cast a card with converted mana cost X exiled with Kaho without paying its mana cost.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new KahoMinamoHistorianCastEffect(), new ManaCostsImpl("{X}"));
+ // {X}, {tap}: You may cast a card with converted mana cost X exiled with
+ // Kaho without paying its mana cost.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
+ new KahoMinamoHistorianCastEffect(), new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
@@ -71,7 +73,8 @@ class KahoMinamoHistorianEffect extends SearchEffect {
public KahoMinamoHistorianEffect() {
super(new TargetCardInLibrary(0, 3, filter), Outcome.Benefit);
- this.staticText = "search your library for up to three instant cards and exile them. Then shuffle your library";
+ this.staticText = "search your library for up to three instant cards "
+ + "and exile them. Then shuffle your library";
}
public KahoMinamoHistorianEffect(final KahoMinamoHistorianEffect effect) {
@@ -91,7 +94,8 @@ class KahoMinamoHistorianEffect extends SearchEffect {
if (controller.searchLibrary(target, source, game)) {
UUID exileZone = CardUtil.getCardExileZoneId(game, source);
if (!target.getTargets().isEmpty()) {
- controller.moveCardsToExile(new CardsImpl(target.getTargets()).getCards(game), source, game, true, exileZone, sourceObject.getIdName());
+ controller.moveCardsToExile(new CardsImpl(target.getTargets()).getCards(game),
+ source, game, true, exileZone, sourceObject.getIdName());
}
}
controller.shuffleLibrary(source, game);
@@ -106,7 +110,8 @@ class KahoMinamoHistorianCastEffect extends OneShotEffect {
public KahoMinamoHistorianCastEffect() {
super(Outcome.PlayForFree);
- this.staticText = "you may cast a card with converted mana cost X exiled with {this} without paying its mana cost";
+ this.staticText = "you may cast a card with converted mana cost X "
+ + "exiled with {this} without paying its mana cost";
}
public KahoMinamoHistorianCastEffect(final KahoMinamoHistorianCastEffect effect) {
@@ -126,10 +131,14 @@ class KahoMinamoHistorianCastEffect extends OneShotEffect {
filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, source.getManaCostsToPay().getX()));
TargetCardInExile target = new TargetCardInExile(filter, CardUtil.getCardExileZoneId(game, source));
Cards cards = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
- if (!cards.isEmpty() && controller.choose(Outcome.PlayForFree, cards, target, game)) {
+ if (!cards.isEmpty()
+ && controller.choose(Outcome.PlayForFree, cards, target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
return true;
diff --git a/Mage.Sets/src/mage/cards/k/KamahlsSummons.java b/Mage.Sets/src/mage/cards/k/KamahlsSummons.java
index b1d2ae75018..7c850062179 100644
--- a/Mage.Sets/src/mage/cards/k/KamahlsSummons.java
+++ b/Mage.Sets/src/mage/cards/k/KamahlsSummons.java
@@ -1,4 +1,3 @@
-
package mage.cards.k;
import java.util.HashMap;
@@ -13,11 +12,9 @@ import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
-import mage.filter.FilterCard;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.token.BearToken;
-import mage.game.permanent.token.TokenImpl;
import mage.game.permanent.token.Token;
import mage.players.Player;
import mage.target.common.TargetCardInHand;
@@ -29,9 +26,9 @@ import mage.target.common.TargetCardInHand;
public final class KamahlsSummons extends CardImpl {
public KamahlsSummons(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}");
- // Each player may reveal any number of creature cards from their hand. Then each player creates a 2/2 green Bear creature token for each card he or she revealed this way.
+ // Each player may reveal any number of creature cards from their hand. Then each player creates a 2/2 green Bear creature token for each card they revealed this way.
getSpellAbility().addEffect(new KamahlsSummonsEffect());
}
@@ -47,11 +44,9 @@ public final class KamahlsSummons extends CardImpl {
class KamahlsSummonsEffect extends OneShotEffect {
- private static final FilterCard filter = new FilterCreatureCard();
-
public KamahlsSummonsEffect() {
super(Outcome.Benefit);
- this.staticText = "Each player may reveal any number of creature cards from their hand. Then each player creates a 2/2 green Bear creature token for each card he or she revealed this way";
+ this.staticText = "Each player may reveal any number of creature cards from their hand. Then each player creates a 2/2 green Bear creature token for each card they revealed this way";
}
public KamahlsSummonsEffect(final KamahlsSummonsEffect effect) {
@@ -68,12 +63,12 @@ class KamahlsSummonsEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
if (controller != null && sourceObject != null) {
- Map revealedCards = new HashMap<>();
+ Map revealedCards = new HashMap<>();
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
- if (player.getHand().count(filter, game) > 0) {
- TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter);
+ if (player.getHand().count(StaticFilters.FILTER_CARD_CREATURE, game) > 0) {
+ TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, StaticFilters.FILTER_CARD_CREATURE);
if (player.choose(outcome, target, source.getSourceId(), game)) {
Cards cards = new CardsImpl(target.getTargets());
controller.revealCards(sourceObject.getIdName(), cards, game);
@@ -83,7 +78,7 @@ class KamahlsSummonsEffect extends OneShotEffect {
}
}
Token token = new BearToken();
- for (Map.Entry revealedCardsByPlayer: revealedCards.entrySet()) {
+ for (Map.Entry revealedCardsByPlayer : revealedCards.entrySet()) {
int value = revealedCardsByPlayer.getValue();
if (value > 0) {
token.putOntoBattlefield(value, game, source.getSourceId(), revealedCardsByPlayer.getKey());
diff --git a/Mage.Sets/src/mage/cards/k/KaradorGhostChieftain.java b/Mage.Sets/src/mage/cards/k/KaradorGhostChieftain.java
index 1ea6ab2fe60..d9dff8edaa0 100644
--- a/Mage.Sets/src/mage/cards/k/KaradorGhostChieftain.java
+++ b/Mage.Sets/src/mage/cards/k/KaradorGhostChieftain.java
@@ -13,7 +13,7 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
@@ -38,12 +38,12 @@ public final class KaradorGhostChieftain extends CardImpl {
this.toughness = new MageInt(4);
// Karador, Ghost Chieftain costs {1} less to cast for each creature card in your graveyard.
- this.addAbility(new SimpleStaticAbility(Zone.STACK,
+ this.addAbility(new SimpleStaticAbility(Zone.STACK,
new KaradorGhostChieftainCostReductionEffect()));
// During each of your turns, you may cast one creature card from your graveyard.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
- new KaradorGhostChieftainContinuousEffect()),
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
+ new KaradorGhostChieftainContinuousEffect()),
new KaradorGhostChieftainWatcher());
}
@@ -72,7 +72,7 @@ class KaradorGhostChieftainCostReductionEffect extends CostModificationEffectImp
public boolean apply(Game game, Ability source, Ability abilityToModify) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- int reductionAmount = player.getGraveyard().count(new FilterCreatureCard(), game);
+ int reductionAmount = player.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game);
CardUtil.reduceCost(abilityToModify, reductionAmount);
return true;
}
@@ -81,7 +81,7 @@ class KaradorGhostChieftainCostReductionEffect extends CostModificationEffectImp
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
- if ((abilityToModify instanceof SpellAbility)
+ if ((abilityToModify instanceof SpellAbility)
&& abilityToModify.getSourceId().equals(source.getSourceId())) {
return game.getCard(abilityToModify.getSourceId()) != null;
}
@@ -114,11 +114,11 @@ class KaradorGhostChieftainContinuousEffect extends ContinuousEffectImpl {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- if (game.getActivePlayerId() == null
+ if (game.getActivePlayerId() == null
|| !game.isActivePlayer(player.getId())) {
return false;
}
- for (Card card : player.getGraveyard().getCards(new FilterCreatureCard(), game)) {
+ for (Card card : player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game)) {
ContinuousEffect effect = new KaradorGhostChieftainCastFromGraveyardEffect();
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
@@ -160,9 +160,9 @@ class KaradorGhostChieftainCastFromGraveyardEffect extends AsThoughEffectImpl {
&& affectedControllerId != null
&& objectCard.getSpellAbility().spellCanBeActivatedRegularlyNow(affectedControllerId, game)) {
if (affectedControllerId.equals(source.getControllerId())) {
- KaradorGhostChieftainWatcher watcher =
- game.getState().getWatcher(KaradorGhostChieftainWatcher.class, source.getSourceId());
- return watcher != null
+ KaradorGhostChieftainWatcher watcher
+ = game.getState().getWatcher(KaradorGhostChieftainWatcher.class, source.getSourceId());
+ return watcher != null
&& !watcher.isAbilityUsed();
}
}
@@ -185,7 +185,7 @@ class KaradorGhostChieftainWatcher extends Watcher {
@Override
public void watch(GameEvent event, Game game) {
- if (event.getType() == GameEvent.EventType.SPELL_CAST
+ if (event.getType() == GameEvent.EventType.SPELL_CAST
&& event.getZone() == Zone.GRAVEYARD) {
Spell spell = (Spell) game.getObject(event.getTargetId());
if (spell.isCreature()) {
diff --git a/Mage.Sets/src/mage/cards/k/KarametraGodOfHarvests.java b/Mage.Sets/src/mage/cards/k/KarametraGodOfHarvests.java
index 6ccd4c9f3b1..e871deb41db 100644
--- a/Mage.Sets/src/mage/cards/k/KarametraGodOfHarvests.java
+++ b/Mage.Sets/src/mage/cards/k/KarametraGodOfHarvests.java
@@ -1,26 +1,26 @@
-
package mage.cards.k;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.dynamicvalue.common.DevotionCount;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.SuperType;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.common.TargetCardInLibrary;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class KarametraGodOfHarvests extends CardImpl {
@@ -30,7 +30,8 @@ public final class KarametraGodOfHarvests extends CardImpl {
static {
filter.add(Predicates.or(
new SubtypePredicate(SubType.FOREST),
- new SubtypePredicate(SubType.PLAINS)));
+ new SubtypePredicate(SubType.PLAINS)
+ ));
}
public KarametraGodOfHarvests(UUID ownerId, CardSetInfo setInfo) {
@@ -43,16 +44,19 @@ public final class KarametraGodOfHarvests extends CardImpl {
// Indestructible
this.addAbility(IndestructibleAbility.getInstance());
+
// As long as your devotion to green and white is less than seven, Karametra isn't a creature.
- Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.G, ColoredManaSymbol.W), 7);
- effect.setText("As long as your devotion to green and white is less than seven, Karametra isn't a creature");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.GW, 7))
+ .addHint(DevotionCount.GW.getHint()));
+
// Whenever you cast a creature spell, you may search your library for a Forest or Plains card, put it onto the battlefield tapped, then shuffle your library.
this.addAbility(new SpellCastControllerTriggeredAbility(
- new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter), true), StaticFilters.FILTER_SPELL_A_CREATURE, true));
+ new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter), true),
+ StaticFilters.FILTER_SPELL_A_CREATURE, true
+ ));
}
- public KarametraGodOfHarvests(final KarametraGodOfHarvests card) {
+ private KarametraGodOfHarvests(final KarametraGodOfHarvests card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/k/KarametrasAcolyte.java b/Mage.Sets/src/mage/cards/k/KarametrasAcolyte.java
index b3c204437a6..1d2842be3d1 100644
--- a/Mage.Sets/src/mage/cards/k/KarametrasAcolyte.java
+++ b/Mage.Sets/src/mage/cards/k/KarametrasAcolyte.java
@@ -1,7 +1,5 @@
-
package mage.cards.k;
-import java.util.UUID;
import mage.MageInt;
import mage.Mana;
import mage.abilities.dynamicvalue.common.DevotionCount;
@@ -10,16 +8,16 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.ColoredManaSymbol;
+
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class KarametrasAcolyte extends CardImpl {
public KarametrasAcolyte(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.DRUID);
@@ -27,11 +25,13 @@ public final class KarametrasAcolyte extends CardImpl {
this.toughness = new MageInt(4);
// {T}: Add an amount of {G} equal to your devotion to green.
- this.addAbility(new DynamicManaAbility(Mana.GreenMana(1), new DevotionCount(ColoredManaSymbol.G),
- "Add an amount of {G} equal to your devotion to green. (Each {G} in the mana costs of permanents you control counts towards your devotion to green.)"));
+ this.addAbility(new DynamicManaAbility(
+ Mana.GreenMana(1), DevotionCount.G, "Add an amount of {G} equal to your devotion to green. " +
+ "(Each {G} in the mana costs of permanents you control counts towards your devotion to green.)"
+ ).addHint(DevotionCount.G.getHint()));
}
- public KarametrasAcolyte(final KarametrasAcolyte card) {
+ private KarametrasAcolyte(final KarametrasAcolyte card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/k/Karma.java b/Mage.Sets/src/mage/cards/k/Karma.java
index 9da7ffb90a8..622ab96aa28 100644
--- a/Mage.Sets/src/mage/cards/k/Karma.java
+++ b/Mage.Sets/src/mage/cards/k/Karma.java
@@ -30,7 +30,7 @@ public final class Karma extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}{W}");
- // At the beginning of each player's upkeep, Karma deals damage to that player equal to the number of Swamps he or she controls.
+ // At the beginning of each player's upkeep, Karma deals damage to that player equal to the number of Swamps they control.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new KarmaDamageTargetEffect(), TargetController.ANY, false));
}
@@ -63,7 +63,7 @@ class KarmaDamageTargetEffect extends OneShotEffect{
@Override
public String getText(Mode mode) {
- return "{this} deals damage to that player equal to the number of Swamps he or she controls";
+ return "{this} deals damage to that player equal to the number of Swamps they control";
}
@Override
diff --git a/Mage.Sets/src/mage/cards/k/KazuulTyrantOfTheCliffs.java b/Mage.Sets/src/mage/cards/k/KazuulTyrantOfTheCliffs.java
index 370f5d4eb70..c5061f7826e 100644
--- a/Mage.Sets/src/mage/cards/k/KazuulTyrantOfTheCliffs.java
+++ b/Mage.Sets/src/mage/cards/k/KazuulTyrantOfTheCliffs.java
@@ -1,8 +1,5 @@
-
package mage.cards.k;
-import java.util.Objects;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
@@ -11,21 +8,17 @@ import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Outcome;
-import mage.constants.SuperType;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
-import mage.game.permanent.Permanent;
import mage.game.permanent.token.OgreToken;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
+import java.util.UUID;
+
/**
- *
* @author jeffwadsworth
*/
public final class KazuulTyrantOfTheCliffs extends CardImpl {
@@ -55,11 +48,11 @@ public final class KazuulTyrantOfTheCliffs extends CardImpl {
class KazuulTyrantOfTheCliffsTriggeredAbility extends TriggeredAbilityImpl {
- public KazuulTyrantOfTheCliffsTriggeredAbility() {
+ KazuulTyrantOfTheCliffsTriggeredAbility() {
super(Zone.BATTLEFIELD, new KazuulTyrantOfTheCliffsEffect(new GenericManaCost(3)));
}
- public KazuulTyrantOfTheCliffsTriggeredAbility(final KazuulTyrantOfTheCliffsTriggeredAbility ability) {
+ private KazuulTyrantOfTheCliffsTriggeredAbility(final KazuulTyrantOfTheCliffsTriggeredAbility ability) {
super(ability);
}
@@ -75,19 +68,17 @@ class KazuulTyrantOfTheCliffsTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
- Permanent attacker = game.getPermanent(event.getSourceId());
- Player defender = game.getPlayer(event.getTargetId());
- Player you = game.getPlayer(controllerId);
- if (!Objects.equals(attacker.getControllerId(), you.getId()) && Objects.equals(defender, you)) {
- this.getEffects().get(0).setTargetPointer(new FixedTarget(attacker.getControllerId()));
- return true;
+ if (!getControllerId().equals(game.getCombat().getDefendingPlayerId(event.getSourceId(), game))) {
+ return false;
}
- return false;
+ this.getEffects().get(0).setTargetPointer(new FixedTarget(game.getControllerId(event.getSourceId())));
+ return true;
}
@Override
public String getRule() {
- return "Whenever a creature an opponent controls attacks, if you're the defending player, create a 3/3 red Ogre creature token unless that creature's controller pays {3}";
+ return "Whenever a creature an opponent controls attacks, if you're the defending player, " +
+ "create a 3/3 red Ogre creature token unless that creature's controller pays {3}";
}
}
@@ -96,12 +87,12 @@ class KazuulTyrantOfTheCliffsEffect extends OneShotEffect {
protected Cost cost;
private static OgreToken token = new OgreToken();
- public KazuulTyrantOfTheCliffsEffect(Cost cost) {
+ KazuulTyrantOfTheCliffsEffect(Cost cost) {
super(Outcome.PutCreatureInPlay);
this.cost = cost;
}
- public KazuulTyrantOfTheCliffsEffect(KazuulTyrantOfTheCliffsEffect effect) {
+ private KazuulTyrantOfTheCliffsEffect(KazuulTyrantOfTheCliffsEffect effect) {
super(effect);
this.cost = effect.cost.copy();
}
@@ -109,13 +100,14 @@ class KazuulTyrantOfTheCliffsEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player payee = game.getPlayer(targetPointer.getFirst(game, source));
- if (payee != null) {
- cost.clearPaid();
- if (!cost.pay(source, game, source.getSourceId(), payee.getId(), false, null)) {
- return token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId());
- }
+ if (payee == null) {
+ return false;
}
- return false;
+ cost.clearPaid();
+ if (cost.pay(source, game, source.getSourceId(), payee.getId(), false, null)) {
+ return false;
+ }
+ return token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId());
}
@Override
diff --git a/Mage.Sets/src/mage/cards/k/KeeperOfFables.java b/Mage.Sets/src/mage/cards/k/KeeperOfFables.java
new file mode 100644
index 00000000000..e5e07bdb117
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/k/KeeperOfFables.java
@@ -0,0 +1,93 @@
+package mage.cards.k;
+
+import mage.MageInt;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.events.DamagedPlayerEvent;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class KeeperOfFables extends CardImpl {
+
+ public KeeperOfFables(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}");
+
+ this.subtype.add(SubType.CAT);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(5);
+
+ // Whenever one or more non-Human creatures you control deal combat damage to a player, draw a card.
+ this.addAbility(new KeeperOfFablesTriggeredAbility());
+ }
+
+ private KeeperOfFables(final KeeperOfFables card) {
+ super(card);
+ }
+
+ @Override
+ public KeeperOfFables copy() {
+ return new KeeperOfFables(this);
+ }
+}
+
+class KeeperOfFablesTriggeredAbility extends TriggeredAbilityImpl {
+
+ private final List damagedPlayerIds = new ArrayList<>();
+
+ KeeperOfFablesTriggeredAbility() {
+ super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), false);
+ }
+
+ private KeeperOfFablesTriggeredAbility(final KeeperOfFablesTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public KeeperOfFablesTriggeredAbility copy() {
+ return new KeeperOfFablesTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.DAMAGED_PLAYER
+ || event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_POST;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER) {
+ if (((DamagedPlayerEvent) event).isCombatDamage()) {
+ Permanent creature = game.getPermanent(event.getSourceId());
+ if (creature != null
+ && creature.isControlledBy(controllerId)
+ && !creature.hasSubtype(SubType.HUMAN, game)
+ && !damagedPlayerIds.contains(event.getTargetId())) {
+ damagedPlayerIds.add(event.getTargetId());
+ return true;
+ }
+ }
+ }
+ if (event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_POST) {
+ damagedPlayerIds.clear();
+ }
+ return false;
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever one or more non-Human creatures you control deal combat damage to a player, draw a card";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/k/KeeperOfTheDead.java b/Mage.Sets/src/mage/cards/k/KeeperOfTheDead.java
index 3508e2839f3..a934d9a37dc 100644
--- a/Mage.Sets/src/mage/cards/k/KeeperOfTheDead.java
+++ b/Mage.Sets/src/mage/cards/k/KeeperOfTheDead.java
@@ -57,7 +57,7 @@ public final class KeeperOfTheDead extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(2);
- // {B}, {T}: Choose target opponent who had at least two fewer creature cards in their graveyard than you did as you activated this ability. Destroy target nonblack creature he or she controls.
+ // {B}, {T}: Choose target opponent who had at least two fewer creature cards in their graveyard than you did as you activated this ability. Destroy target nonblack creature they control.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new KeeperOfTheDeadEffect(), new TapSourceCost());
ability.addCost(new ManaCostsImpl("{B}"));
ability.addTarget(new TargetPlayer(1, 1, false, filter));
diff --git a/Mage.Sets/src/mage/cards/k/KeeperOfTheFlame.java b/Mage.Sets/src/mage/cards/k/KeeperOfTheFlame.java
index 9c1bcdd170f..b70d3feaea3 100644
--- a/Mage.Sets/src/mage/cards/k/KeeperOfTheFlame.java
+++ b/Mage.Sets/src/mage/cards/k/KeeperOfTheFlame.java
@@ -38,9 +38,9 @@ public final class KeeperOfTheFlame extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(2);
- // {R}, {tap}: Choose target opponent who had more life than you did as you activated this ability. Keeper of the Flame deals 2 damage to him or her.
+ // {R}, {tap}: Choose target opponent who had more life than you did as you activated this ability. Keeper of the Flame deals 2 damage to that player.
Ability ability = new SimpleActivatedAbility(
- new DamageTargetEffect(2).setText("Choose target opponent who had more life than you did as you activated this ability. {this} deals 2 damage to him or her"),
+ new DamageTargetEffect(2).setText("Choose target opponent who had more life than you did as you activated this ability. {this} deals 2 damage to that player"),
new ManaCostsImpl("{R}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetPlayer(1, 1, false, filter));
diff --git a/Mage.Sets/src/mage/cards/k/KeldonFirebombers.java b/Mage.Sets/src/mage/cards/k/KeldonFirebombers.java
index 6e02b583b8b..365c041bc44 100644
--- a/Mage.Sets/src/mage/cards/k/KeldonFirebombers.java
+++ b/Mage.Sets/src/mage/cards/k/KeldonFirebombers.java
@@ -35,7 +35,7 @@ public final class KeldonFirebombers extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(3);
- // When Keldon Firebombers enters the battlefield, each player sacrifices all lands he or she controls except for three.
+ // When Keldon Firebombers enters the battlefield, each player sacrifices all lands they control except for three.
this.addAbility(new EntersBattlefieldTriggeredAbility(new KeldonFirebombersEffect()));
}
@@ -56,7 +56,7 @@ class KeldonFirebombersEffect extends OneShotEffect {
public KeldonFirebombersEffect() {
super(Outcome.AIDontUseIt);
- this.staticText = "each player sacrifices all lands he or she controls except for three";
+ this.staticText = "each player sacrifices all lands they control except for three";
}
public KeldonFirebombersEffect(final KeldonFirebombersEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/k/KeldonTwilight.java b/Mage.Sets/src/mage/cards/k/KeldonTwilight.java
index e5a6468735b..2777bad2ff6 100644
--- a/Mage.Sets/src/mage/cards/k/KeldonTwilight.java
+++ b/Mage.Sets/src/mage/cards/k/KeldonTwilight.java
@@ -32,9 +32,9 @@ public final class KeldonTwilight extends CardImpl {
public KeldonTwilight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{R}");
- // At the beginning of each player's end step, if no creatures attacked this turn, that player sacrifices a creature he or she controlled since the beginning of the turn.
+ // At the beginning of each player's end step, if no creatures attacked this turn, that player sacrifices a creature they controlled since the beginning of the turn.
Effect effect = new SacrificeEffect(filter, 1, "that player ");
- effect.setText("that player sacrifices a creature he or she controlled since the beginning of the turn");
+ effect.setText("that player sacrifices a creature they controlled since the beginning of the turn");
BeginningOfEndStepTriggeredAbility ability
= new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.ANY, new KeldonTwilightCondition(), false);
this.addAbility(ability, new AttackedThisTurnWatcher());
diff --git a/Mage.Sets/src/mage/cards/k/KenrithTheReturnedKing.java b/Mage.Sets/src/mage/cards/k/KenrithTheReturnedKing.java
new file mode 100644
index 00000000000..c1b780cf35c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/k/KenrithTheReturnedKing.java
@@ -0,0 +1,114 @@
+package mage.cards.k;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DrawCardTargetEffect;
+import mage.abilities.effects.common.GainLifeTargetEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.abilities.keyword.HasteAbility;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.counters.CounterType;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.TargetPlayer;
+import mage.target.common.TargetCardInGraveyard;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class KenrithTheReturnedKing extends CardImpl {
+
+ public KenrithTheReturnedKing(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.NOBLE);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(5);
+
+ // {R}: All creatures gain trample and haste until end of turn.
+ Ability ability = new SimpleActivatedAbility(new GainAbilityAllEffect(
+ TrampleAbility.getInstance(), Duration.EndOfTurn,
+ StaticFilters.FILTER_PERMANENT_CREATURE
+ ).setText("all creatures gain trample"), new ManaCostsImpl("{R}"));
+ ability.addEffect(new GainAbilityAllEffect(
+ HasteAbility.getInstance(), Duration.EndOfTurn,
+ StaticFilters.FILTER_PERMANENT_CREATURE
+ ).setText("and haste until end of turn"));
+ this.addAbility(ability);
+
+ // {1}{G}: Put a +1/+1 counter on target creature.
+ ability = new SimpleActivatedAbility(
+ new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl("{1}{G}")
+ );
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+
+ // {2}{W}: Target player gains 5 life.
+ ability = new SimpleActivatedAbility(new GainLifeTargetEffect(5), new ManaCostsImpl("{2}{W}"));
+ ability.addTarget(new TargetPlayer());
+ this.addAbility(ability);
+
+ // {3}{U}: Target player draws a card.
+ ability = new SimpleActivatedAbility(new DrawCardTargetEffect(1), new ManaCostsImpl("{3}{U}"));
+ ability.addTarget(new TargetPlayer());
+ this.addAbility(ability);
+
+ // {4}{B}: Put target creature card from a graveyard onto the battlefield under its owner's control.
+ ability = new SimpleActivatedAbility(new KenrithTheReturnedKingEffect(), new ManaCostsImpl("{4}{B}"));
+ ability.addTarget(new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE));
+ this.addAbility(ability);
+ }
+
+ private KenrithTheReturnedKing(final KenrithTheReturnedKing card) {
+ super(card);
+ }
+
+ @Override
+ public KenrithTheReturnedKing copy() {
+ return new KenrithTheReturnedKing(this);
+ }
+}
+
+class KenrithTheReturnedKingEffect extends OneShotEffect {
+
+ KenrithTheReturnedKingEffect() {
+ super(Outcome.Benefit);
+ staticText = "put target creature card from a graveyard onto the battlefield under its owner's control";
+ }
+
+ private KenrithTheReturnedKingEffect(final KenrithTheReturnedKingEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public KenrithTheReturnedKingEffect copy() {
+ return new KenrithTheReturnedKingEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Card card = game.getCard(source.getFirstTarget());
+ if (card == null) {
+ return false;
+ }
+ Player player = game.getPlayer(card.getOwnerId());
+ if (player == null) {
+ return false;
+ }
+ return player.moveCards(card, Zone.BATTLEFIELD, source, game);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/k/KenrithsTransformation.java b/Mage.Sets/src/mage/cards/k/KenrithsTransformation.java
new file mode 100644
index 00000000000..800bc419d51
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/k/KenrithsTransformation.java
@@ -0,0 +1,58 @@
+package mage.cards.k;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.continuous.BecomesCreatureAttachedEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.game.permanent.token.custom.CreatureToken;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class KenrithsTransformation extends CardImpl {
+
+ public KenrithsTransformation(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
+
+ this.subtype.add(SubType.AURA);
+
+ // Enchant creature
+ TargetPermanent auraTarget = new TargetCreaturePermanent();
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // When Kenrith's Transformation enters the battlefield, draw a card.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)));
+
+ // Enchanted creature loses all abilities and is a green Elk creature with base power and toughness 3/3.
+ this.addAbility(new SimpleStaticAbility(new BecomesCreatureAttachedEffect(
+ new CreatureToken(3, 3, "", SubType.ELK).withColor("G"),
+ "Enchanted creature loses all abilities and is a green Elk creature with base power and toughness 3/3",
+ Duration.WhileOnBattlefield, BecomesCreatureAttachedEffect.LoseType.ALL
+ )));
+ }
+
+ private KenrithsTransformation(final KenrithsTransformation card) {
+ super(card);
+ }
+
+ @Override
+ public KenrithsTransformation copy() {
+ return new KenrithsTransformation(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/k/KeranosGodOfStorms.java b/Mage.Sets/src/mage/cards/k/KeranosGodOfStorms.java
index fbcec941d28..e0c75bf8555 100644
--- a/Mage.Sets/src/mage/cards/k/KeranosGodOfStorms.java
+++ b/Mage.Sets/src/mage/cards/k/KeranosGodOfStorms.java
@@ -1,12 +1,9 @@
-
package mage.cards.k;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.DevotionCount;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.InfoEffect;
@@ -18,7 +15,6 @@ import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.ColoredManaSymbol;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.game.Game;
@@ -29,15 +25,15 @@ import mage.players.Player;
import mage.target.common.TargetAnyTarget;
import mage.watchers.common.CardsAmountDrawnThisTurnWatcher;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class KeranosGodOfStorms extends CardImpl {
-
public KeranosGodOfStorms(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{3}{U}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{3}{U}{R}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.GOD);
@@ -46,20 +42,18 @@ public final class KeranosGodOfStorms extends CardImpl {
// Indestructible
this.addAbility(IndestructibleAbility.getInstance());
+
// As long as your devotion to blue and red is less than seven, Keranos isn't a creature.
- Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.U, ColoredManaSymbol.R), 7);
- effect.setText("As long as your devotion to blue and red is less than seven, Keranos isn't a creature");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
-
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.UR, 7))
+ .addHint(DevotionCount.UR.getHint()));
+
// Reveal the first card you draw on each of your turns.
// Whenever you reveal a land card this way, draw a card.
// Whenever you reveal a nonland card this way, Keranos deals 3 damage to any target.
this.addAbility(new KeranosGodOfStormsTriggeredAbility(), new CardsAmountDrawnThisTurnWatcher());
-
-
}
- public KeranosGodOfStorms(final KeranosGodOfStorms card) {
+ private KeranosGodOfStorms(final KeranosGodOfStorms card) {
super(card);
}
@@ -75,7 +69,7 @@ class KeranosGodOfStormsTriggeredAbility extends TriggeredAbilityImpl {
super(Zone.BATTLEFIELD, new InfoEffect(""), false);
}
- KeranosGodOfStormsTriggeredAbility(final KeranosGodOfStormsTriggeredAbility ability) {
+ private KeranosGodOfStormsTriggeredAbility(final KeranosGodOfStormsTriggeredAbility ability) {
super(ability);
}
@@ -91,36 +85,38 @@ class KeranosGodOfStormsTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
- if (event.getPlayerId().equals(this.getControllerId())) {
- if (game.isActivePlayer(this.getControllerId())) {
- CardsAmountDrawnThisTurnWatcher watcher =
- game.getState().getWatcher(CardsAmountDrawnThisTurnWatcher.class);
- if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) != 1) {
- return false;
- }
- Card card = game.getCard(event.getTargetId());
- Player controller = game.getPlayer(this.getControllerId());
- Permanent sourcePermanent = (Permanent) getSourceObject(game);
- if (card != null && controller != null && sourcePermanent != null) {
- controller.revealCards(sourcePermanent.getIdName(), new CardsImpl(card), game);
- this.getTargets().clear();
- this.getEffects().clear();
- if (card.isLand()) {
- this.addEffect(new DrawCardSourceControllerEffect(1));
- } else {
- this.addEffect(new DamageTargetEffect(3));
- this.addTarget(new TargetAnyTarget());
- }
- return true;
- }
- }
+ if (!event.getPlayerId().equals(this.getControllerId())) {
+ return false;
}
- return false;
+ if (!game.isActivePlayer(this.getControllerId())) {
+ return false;
+ }
+ CardsAmountDrawnThisTurnWatcher watcher =
+ game.getState().getWatcher(CardsAmountDrawnThisTurnWatcher.class);
+ if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) != 1) {
+ return false;
+ }
+ Card card = game.getCard(event.getTargetId());
+ Player controller = game.getPlayer(this.getControllerId());
+ Permanent sourcePermanent = (Permanent) getSourceObject(game);
+ if (card == null || controller == null || sourcePermanent == null) {
+ return false;
+ }
+ controller.revealCards(sourcePermanent.getIdName(), new CardsImpl(card), game);
+ this.getTargets().clear();
+ this.getEffects().clear();
+ if (card.isLand()) {
+ this.addEffect(new DrawCardSourceControllerEffect(1));
+ } else {
+ this.addEffect(new DamageTargetEffect(3));
+ this.addTarget(new TargetAnyTarget());
+ }
+ return true;
}
@Override
public String getRule() {
return "Reveal the first card you draw on each of your turns. Whenever you reveal a land card this way, draw a card. " +
- "Whenever you reveal a nonland card this way, Keranos deals 3 damage to any target.";
+ "Whenever you reveal a nonland card this way, {this} deals 3 damage to any target.";
}
}
diff --git a/Mage.Sets/src/mage/cards/k/KessigCagebreakers.java b/Mage.Sets/src/mage/cards/k/KessigCagebreakers.java
index 24e80dff940..0bfd9735b0b 100644
--- a/Mage.Sets/src/mage/cards/k/KessigCagebreakers.java
+++ b/Mage.Sets/src/mage/cards/k/KessigCagebreakers.java
@@ -1,4 +1,3 @@
-
package mage.cards.k;
import java.util.UUID;
@@ -11,7 +10,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.token.WolfToken;
import mage.players.Player;
@@ -23,7 +22,7 @@ import mage.players.Player;
public final class KessigCagebreakers extends CardImpl {
public KessigCagebreakers(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ROGUE);
@@ -65,7 +64,7 @@ class KessigCagebreakersEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
WolfToken token = new WolfToken();
- int count = player.getGraveyard().count(new FilterCreatureCard(), game);
+ int count = player.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game);
for (int i = 0; i < count; i++) {
token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId(), true, true);
}
diff --git a/Mage.Sets/src/mage/cards/k/KethisTheHiddenHand.java b/Mage.Sets/src/mage/cards/k/KethisTheHiddenHand.java
index 8db1f2d43a5..bb1d5204f3e 100644
--- a/Mage.Sets/src/mage/cards/k/KethisTheHiddenHand.java
+++ b/Mage.Sets/src/mage/cards/k/KethisTheHiddenHand.java
@@ -1,6 +1,7 @@
package mage.cards.k;
import mage.MageInt;
+import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
@@ -75,24 +76,43 @@ class KethisTheHiddenHandEffect extends ContinuousEffectImpl {
super(effect);
}
+ @Override
+ public void init(Ability source, Game game) {
+ super.init(source, game);
+ if (!this.affectedObjectsSet) {
+ return;
+ }
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return;
+ }
+ player.getGraveyard()
+ .stream()
+ .map(game::getCard)
+ .filter(Card::isLegendary)
+ .forEach(card -> affectedObjectList.add(new MageObjectReference(card, game)));
+ }
+
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
- for (UUID cardId : controller.getGraveyard()) {
- Card card = game.getCard(cardId);
- if (card == null || !card.isLegendary()) {
- continue;
- }
+ controller.getGraveyard()
+ .getCards(game)
+ .stream()
+ .filter(card -> affectedObjectList
+ .stream()
+ .anyMatch(mor -> mor.refersTo(card, game))
+ ).forEach(card -> {
Ability ability = new SimpleStaticAbility(
Zone.GRAVEYARD, new KethisTheHiddenHandGraveyardEffect()
);
- ability.setSourceId(cardId);
+ ability.setSourceId(card.getId());
ability.setControllerId(card.getOwnerId());
game.getState().addOtherAbility(card, ability);
- }
+ });
return true;
}
diff --git a/Mage.Sets/src/mage/cards/k/KheruLichLord.java b/Mage.Sets/src/mage/cards/k/KheruLichLord.java
index b0c98908045..9bfbf9de11c 100644
--- a/Mage.Sets/src/mage/cards/k/KheruLichLord.java
+++ b/Mage.Sets/src/mage/cards/k/KheruLichLord.java
@@ -1,4 +1,3 @@
-
package mage.cards.k;
import java.util.UUID;
@@ -28,7 +27,7 @@ import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
@@ -85,7 +84,7 @@ class KheruLichLordEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- Cards cards = new CardsImpl(controller.getGraveyard().getCards(new FilterCreatureCard(), source.getSourceId(), source.getControllerId(), game));
+ Cards cards = new CardsImpl(controller.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, source.getSourceId(), source.getControllerId(), game));
Card card = cards.getRandom(game);
if (card != null) {
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
diff --git a/Mage.Sets/src/mage/cards/k/KillingWave.java b/Mage.Sets/src/mage/cards/k/KillingWave.java
index 0f146aac56d..cb30af1dd2f 100644
--- a/Mage.Sets/src/mage/cards/k/KillingWave.java
+++ b/Mage.Sets/src/mage/cards/k/KillingWave.java
@@ -24,7 +24,7 @@ public final class KillingWave extends CardImpl {
public KillingWave(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}");
- // For each creature, its controller sacrifices it unless he or she pays X life.
+ // For each creature, its controller sacrifices it unless they pay X life.
this.getSpellAbility().addEffect(new KillingWaveEffect());
}
@@ -42,7 +42,7 @@ class KillingWaveEffect extends OneShotEffect {
public KillingWaveEffect() {
super(Outcome.Sacrifice);
- this.staticText = "For each creature, its controller sacrifices it unless he or she pays X life";
+ this.staticText = "For each creature, its controller sacrifices it unless they pay X life";
}
public KillingWaveEffect(final KillingWaveEffect effect) {
@@ -77,7 +77,7 @@ class KillingWaveEffect extends OneShotEffect {
for (Permanent creature : creatures) {
String message = "Pay " + amount + " life? If you don't, " + creature.getName() + " will be sacrificed.";
if (playerLife - amount - lifePaid >= 0 && player.chooseUse(Outcome.Neutral, message, source, game)) {
- game.informPlayers(player.getLogName() + " pays " + amount + " life. He will not sacrifice " + creature.getName());
+ game.informPlayers(player.getLogName() + " pays " + amount + " life. They will not sacrifice " + creature.getName());
lifePaid += amount;
} else {
game.informPlayers(player.getLogName() + " will sacrifice " + creature.getName());
diff --git a/Mage.Sets/src/mage/cards/k/Kindle.java b/Mage.Sets/src/mage/cards/k/Kindle.java
index 24a88be94e9..ac8d7a38cae 100644
--- a/Mage.Sets/src/mage/cards/k/Kindle.java
+++ b/Mage.Sets/src/mage/cards/k/Kindle.java
@@ -1,7 +1,5 @@
-
package mage.cards.k;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
@@ -16,8 +14,9 @@ import mage.players.Player;
import mage.players.PlayerList;
import mage.target.common.TargetAnyTarget;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class Kindle extends CardImpl {
@@ -29,7 +28,7 @@ public final class Kindle extends CardImpl {
}
public Kindle(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}");
// Kindle deals X damage to any target, where X is 2 plus the number of cards named Kindle in all graveyards.
@@ -64,7 +63,7 @@ class KindleCardsInAllGraveyardsCount implements DynamicValue {
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
int amount = 0;
- PlayerList playerList = game.getPlayerList();
+ PlayerList playerList = game.getPlayerList().copy();
for (UUID playerUUID : playerList) {
Player player = game.getPlayer(playerUUID);
if (player != null) {
diff --git a/Mage.Sets/src/mage/cards/k/KingMacarTheGoldCursed.java b/Mage.Sets/src/mage/cards/k/KingMacarTheGoldCursed.java
index f943bf421d9..c9ce38abf25 100644
--- a/Mage.Sets/src/mage/cards/k/KingMacarTheGoldCursed.java
+++ b/Mage.Sets/src/mage/cards/k/KingMacarTheGoldCursed.java
@@ -1,7 +1,6 @@
package mage.cards.k;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.effects.Effect;
@@ -16,8 +15,9 @@ import mage.constants.SuperType;
import mage.game.permanent.token.GoldToken;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class KingMacarTheGoldCursed extends CardImpl {
@@ -25,7 +25,7 @@ public final class KingMacarTheGoldCursed extends CardImpl {
public KingMacarTheGoldCursed(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}");
addSuperType(SuperType.LEGENDARY);
- this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.HUMAN, SubType.NOBLE);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
diff --git a/Mage.Sets/src/mage/cards/k/KingSuleiman.java b/Mage.Sets/src/mage/cards/k/KingSuleiman.java
index 3af926e5db8..b3ea6d5648c 100644
--- a/Mage.Sets/src/mage/cards/k/KingSuleiman.java
+++ b/Mage.Sets/src/mage/cards/k/KingSuleiman.java
@@ -1,7 +1,5 @@
-
package mage.cards.k;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -17,8 +15,9 @@ import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.TargetPermanent;
+import java.util.UUID;
+
/**
- *
* @author KholdFuzion
*/
public final class KingSuleiman extends CardImpl {
@@ -26,14 +25,15 @@ public final class KingSuleiman extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("Djinn or Efreet");
static {
- filter.add( Predicates.or(
+ filter.add(Predicates.or(
new SubtypePredicate(SubType.DJINN),
- new SubtypePredicate(SubType.EFREET)));
+ new SubtypePredicate(SubType.EFREET)
+ ));
}
public KingSuleiman(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}");
- this.subtype.add(SubType.HUMAN);
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
+ this.subtype.add(SubType.HUMAN, SubType.NOBLE);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
diff --git a/Mage.Sets/src/mage/cards/k/Kitesail.java b/Mage.Sets/src/mage/cards/k/Kitesail.java
index c80922057c1..f4bd0a7a89d 100644
--- a/Mage.Sets/src/mage/cards/k/Kitesail.java
+++ b/Mage.Sets/src/mage/cards/k/Kitesail.java
@@ -2,6 +2,8 @@
package mage.cards.k;
import java.util.UUID;
+
+import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
@@ -22,8 +24,14 @@ public final class Kitesail extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
this.subtype.add(SubType.EQUIPMENT);
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 0)));
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.EQUIPMENT)));
+ // Equipped creature gets +1/+0 and has flying.
+ Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(1, 0));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ FlyingAbility.getInstance(), AttachmentType.EQUIPMENT).setText("and has flying")
+ );
+ this.addAbility(ability);
+
+ // Equip {2}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2)));
}
diff --git a/Mage.Sets/src/mage/cards/k/KlothysGodOfDestiny.java b/Mage.Sets/src/mage/cards/k/KlothysGodOfDestiny.java
new file mode 100644
index 00000000000..5b36b262321
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/k/KlothysGodOfDestiny.java
@@ -0,0 +1,108 @@
+package mage.cards.k;
+
+import mage.MageInt;
+import mage.Mana;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfPreCombatMainTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.common.DevotionCount;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
+import mage.abilities.keyword.IndestructibleAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.common.TargetCardInGraveyard;
+
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class KlothysGodOfDestiny extends CardImpl {
+
+ public KlothysGodOfDestiny(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{R}{G}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.GOD);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(5);
+
+ // Indestructible
+ this.addAbility(IndestructibleAbility.getInstance());
+
+ // As long as your devotion to red and green is less than seven, Klothys isn't a creature.
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.RG, 7))
+ .addHint(DevotionCount.RG.getHint()));
+
+ // At the beginning of your precombat main phase, exile target card from a graveyard. If it was a land card, add {R} or {G}. Otherwise, you gain 2 life and Klothys deals 2 damage to each opponent.
+ Ability ability = new BeginningOfPreCombatMainTriggeredAbility(
+ new KlothysGodOfDestinyEffect(), TargetController.YOU, false
+ );
+ ability.addTarget(new TargetCardInGraveyard());
+ this.addAbility(ability);
+ }
+
+ private KlothysGodOfDestiny(final KlothysGodOfDestiny card) {
+ super(card);
+ }
+
+ @Override
+ public KlothysGodOfDestiny copy() {
+ return new KlothysGodOfDestiny(this);
+ }
+}
+
+class KlothysGodOfDestinyEffect extends OneShotEffect {
+
+ KlothysGodOfDestinyEffect() {
+ super(Outcome.Benefit);
+ staticText = "exile target card from a graveyard. If it was a land card, add {R} or {G}. " +
+ "Otherwise, you gain 2 life and {this} deals 2 damage to each opponent.";
+ }
+
+ private KlothysGodOfDestinyEffect(final KlothysGodOfDestinyEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public KlothysGodOfDestinyEffect copy() {
+ return new KlothysGodOfDestinyEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ Card card = game.getCard(source.getFirstTarget());
+ if (player == null || card == null) {
+ return false;
+ }
+ boolean isLand = card.isLand();
+ player.moveCards(card, Zone.EXILED, source, game);
+ if (isLand) {
+ Mana mana = new Mana();
+ if (player.chooseUse(
+ Outcome.PutManaInPool, "Choose a color of mana to add",
+ null, "Red", "Green", source, game
+ )) {
+ mana.increaseRed();
+ } else {
+ mana.increaseGreen();
+ }
+ player.getManaPool().addMana(mana, game, source);
+ return true;
+ }
+ player.gainLife(2, game, source);
+ game.getOpponents(player.getId())
+ .stream()
+ .map(game::getPlayer)
+ .filter(Objects::nonNull)
+ .forEach(opponent -> opponent.damage(2, source.getSourceId(), game));
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/k/KlothyssDesign.java b/Mage.Sets/src/mage/cards/k/KlothyssDesign.java
new file mode 100644
index 00000000000..66d04c7c5a0
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/k/KlothyssDesign.java
@@ -0,0 +1,37 @@
+package mage.cards.k;
+
+import mage.abilities.dynamicvalue.common.DevotionCount;
+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 java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class KlothyssDesign extends CardImpl {
+
+ public KlothyssDesign(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{G}");
+
+ // Creatures you control get +X/+X until end of turn, where X is your devotion to green.
+ this.getSpellAbility().addEffect(new BoostControlledEffect(
+ DevotionCount.G, DevotionCount.G, Duration.EndOfTurn,
+ StaticFilters.FILTER_PERMANENT_CREATURES, false, true
+ ));
+ this.getSpellAbility().addHint(DevotionCount.G.getHint());
+ }
+
+ private KlothyssDesign(final KlothyssDesign card) {
+ super(card);
+ }
+
+ @Override
+ public KlothyssDesign copy() {
+ return new KlothyssDesign(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/k/KnightOfTheKeep.java b/Mage.Sets/src/mage/cards/k/KnightOfTheKeep.java
new file mode 100644
index 00000000000..4a44649a469
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/k/KnightOfTheKeep.java
@@ -0,0 +1,33 @@
+package mage.cards.k;
+
+import mage.MageInt;
+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 KnightOfTheKeep extends CardImpl {
+
+ public KnightOfTheKeep(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(2);
+ }
+
+ private KnightOfTheKeep(final KnightOfTheKeep card) {
+ super(card);
+ }
+
+ @Override
+ public KnightOfTheKeep copy() {
+ return new KnightOfTheKeep(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/k/KnightsCharge.java b/Mage.Sets/src/mage/cards/k/KnightsCharge.java
new file mode 100644
index 00000000000..31d33c18a27
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/k/KnightsCharge.java
@@ -0,0 +1,88 @@
+package mage.cards.k;
+
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.effects.common.LoseLifeOpponentsEffect;
+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.filter.common.FilterControlledCreaturePermanent;
+import mage.game.Game;
+import mage.players.Player;
+
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * @author TheElk801
+ */
+public final class KnightsCharge extends CardImpl {
+
+ private static final FilterControlledCreaturePermanent filter
+ = new FilterControlledCreaturePermanent(SubType.KNIGHT);
+
+ public KnightsCharge(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{B}");
+
+ // Whenever a Knight you control attacks, each opponent loses 1 life and you gain 1 life.
+ Ability ability = new AttacksCreatureYouControlTriggeredAbility(
+ new LoseLifeOpponentsEffect(1), false, filter
+ );
+ ability.addEffect(new GainLifeEffect(1).concatBy("and"));
+ this.addAbility(ability);
+
+ // {6}{W}{B}, Sacrifice Knights' Charge: Return all Knight creature cards from your graveyard to the battlefield.
+ ability = new SimpleActivatedAbility(new KnightsChargeEffect(), new ManaCostsImpl("{6}{W}{B}"));
+ ability.addCost(new SacrificeSourceCost());
+ this.addAbility(ability);
+ }
+
+ private KnightsCharge(final KnightsCharge card) {
+ super(card);
+ }
+
+ @Override
+ public KnightsCharge copy() {
+ return new KnightsCharge(this);
+ }
+}
+
+class KnightsChargeEffect extends OneShotEffect {
+
+ KnightsChargeEffect() {
+ super(Outcome.Benefit);
+ staticText = "return all Knight creature cards from your graveyard to the battlefield";
+ }
+
+ private KnightsChargeEffect(final KnightsChargeEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public KnightsChargeEffect copy() {
+ return new KnightsChargeEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ return player != null && player.moveCards(new CardsImpl(
+ player.getGraveyard()
+ .getCards(game)
+ .stream()
+ .filter(Card::isCreature)
+ .filter(card -> card.hasSubtype(SubType.KNIGHT, game))
+ .collect(Collectors.toSet())
+ ), Zone.BATTLEFIELD, source, game);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/k/KnowledgeExploitation.java b/Mage.Sets/src/mage/cards/k/KnowledgeExploitation.java
index 577861370b1..e4651f7aab5 100644
--- a/Mage.Sets/src/mage/cards/k/KnowledgeExploitation.java
+++ b/Mage.Sets/src/mage/cards/k/KnowledgeExploitation.java
@@ -1,4 +1,3 @@
-
package mage.cards.k;
import java.util.UUID;
@@ -31,7 +30,9 @@ public final class KnowledgeExploitation extends CardImpl {
// Prowl {3}{U}
this.addAbility(new ProwlAbility(this, "{3}{U}"));
- // Search target opponent's library for an instant or sorcery card. You may cast that card without paying its mana cost. Then that player shuffles their library.
+ // Search target opponent's library for an instant or sorcery card.
+ // You may cast that card without paying its mana cost.
+ // Then that player shuffles their library.
this.getSpellAbility().addEffect(new KnowledgeExploitationEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
}
@@ -49,8 +50,11 @@ public final class KnowledgeExploitation extends CardImpl {
class KnowledgeExploitationEffect extends OneShotEffect {
KnowledgeExploitationEffect() {
- super(Outcome.Benefit);
- this.staticText = "Search target opponent's library for an instant or sorcery card. You may cast that card without paying its mana cost. Then that player shuffles their library";
+ super(Outcome.PlayForFree);
+ this.staticText = "Search target opponent's library for an "
+ + "instant or sorcery card. You may cast that card "
+ + "without paying its mana cost. Then that "
+ + "player shuffles their library";
}
KnowledgeExploitationEffect(final KnowledgeExploitationEffect effect) {
@@ -71,7 +75,10 @@ class KnowledgeExploitationEffect extends OneShotEffect {
if (controller.searchLibrary(target, source, game, opponent.getId())) {
Card card = opponent.getLibrary().remove(target.getFirstTarget(), game);
if (card != null) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
opponent.shuffleLibrary(source, game);
diff --git a/Mage.Sets/src/mage/cards/k/KnowledgePool.java b/Mage.Sets/src/mage/cards/k/KnowledgePool.java
index b2317ba720e..f9278bec371 100644
--- a/Mage.Sets/src/mage/cards/k/KnowledgePool.java
+++ b/Mage.Sets/src/mage/cards/k/KnowledgePool.java
@@ -39,7 +39,7 @@ public final class KnowledgePool extends CardImpl {
// Imprint - When Knowledge Pool enters the battlefield, each player exiles the top three cards of their library
this.addAbility(new EntersBattlefieldTriggeredAbility(new KnowledgePoolEffect1(), false));
- // Whenever a player casts a spell from their hand, that player exiles it. If the player does, he or she may cast another nonland card exiled with Knowledge Pool without paying that card's mana cost.
+ // Whenever a player casts a spell from their hand, that player exiles it. If the player does, they may cast another nonland card exiled with Knowledge Pool without paying that card's mana cost.
this.addAbility(new KnowledgePoolAbility());
}
@@ -132,7 +132,7 @@ class KnowledgePoolEffect2 extends OneShotEffect {
public KnowledgePoolEffect2() {
super(Outcome.Neutral);
- staticText = "Whenever a player casts a spell from their hand, that player exiles it. If the player does, he or she may cast another nonland card exiled with {this} without paying that card's mana cost";
+ staticText = "Whenever a player casts a spell from their hand, that player exiles it. If the player does, they may cast another nonland card exiled with {this} without paying that card's mana cost";
}
public KnowledgePoolEffect2(final KnowledgePoolEffect2 effect) {
diff --git a/Mage.Sets/src/mage/cards/k/KorvoldFaeCursedKing.java b/Mage.Sets/src/mage/cards/k/KorvoldFaeCursedKing.java
new file mode 100644
index 00000000000..2d6b7a4d255
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/k/KorvoldFaeCursedKing.java
@@ -0,0 +1,96 @@
+package mage.cards.k;
+
+import mage.MageInt;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.SacrificeControllerEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import mage.filter.FilterPermanent;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class KorvoldFaeCursedKing extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterPermanent("another permanent");
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ }
+
+ public KorvoldFaeCursedKing(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}{G}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.DRAGON);
+ this.subtype.add(SubType.NOBLE);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(4);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Whenever Korvold, Fae-Cursed King enters the battlefield or attacks, sacrifice another permanent.
+ this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(
+ new SacrificeControllerEffect(filter, 1, "")
+ ));
+
+ // Whenever you sacrifice a permanent, put a +1/+1 counter on Korvold and draw a card.
+ this.addAbility(new KorvoldFaeCursedKingAbility());
+ }
+
+ private KorvoldFaeCursedKing(final KorvoldFaeCursedKing card) {
+ super(card);
+ }
+
+ @Override
+ public KorvoldFaeCursedKing copy() {
+ return new KorvoldFaeCursedKing(this);
+ }
+}
+
+class KorvoldFaeCursedKingAbility extends TriggeredAbilityImpl {
+
+ KorvoldFaeCursedKingAbility() {
+ super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()));
+ this.addEffect(new DrawCardSourceControllerEffect(1));
+ }
+
+ private KorvoldFaeCursedKingAbility(final KorvoldFaeCursedKingAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public KorvoldFaeCursedKingAbility copy() {
+ return new KorvoldFaeCursedKingAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ return this.isControlledBy(event.getPlayerId());
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever you sacrifice a permanent, put a +1/+1 counter on {this} and draw a card.";
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/k/KoskunFalls.java b/Mage.Sets/src/mage/cards/k/KoskunFalls.java
index d285532a0f1..f1824cfaa4f 100644
--- a/Mage.Sets/src/mage/cards/k/KoskunFalls.java
+++ b/Mage.Sets/src/mage/cards/k/KoskunFalls.java
@@ -41,7 +41,7 @@ public final class KoskunFalls extends CardImpl {
effect.setText("sacrifice Koskun Falls unless you tap an untapped creature you control");
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.YOU, false));
- // Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you.
+ // Creatures can't attack you unless their controller pays {2} for each creature they control that's attacking you.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackYouUnlessPayManaAllEffect(new ManaCostsImpl("{2}"))));
}
diff --git a/Mage.Sets/src/mage/cards/k/KraulForagers.java b/Mage.Sets/src/mage/cards/k/KraulForagers.java
index 46f375ee324..2675053a0f5 100644
--- a/Mage.Sets/src/mage/cards/k/KraulForagers.java
+++ b/Mage.Sets/src/mage/cards/k/KraulForagers.java
@@ -9,7 +9,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -27,7 +27,7 @@ public final class KraulForagers extends CardImpl {
// Undergrowth — When Kraul Foragers enters the battlefield, you gain 1 life for each creature card in your graveyard.
this.addAbility(new EntersBattlefieldTriggeredAbility(
- new GainLifeEffect(new CardsInControllerGraveyardCount(new FilterCreatureCard())),
+ new GainLifeEffect(new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE)),
false, "Undergrowth — "
));
}
diff --git a/Mage.Sets/src/mage/cards/k/KrenkoMobBoss.java b/Mage.Sets/src/mage/cards/k/KrenkoMobBoss.java
index 8aca0b1634b..d9cdf289b94 100644
--- a/Mage.Sets/src/mage/cards/k/KrenkoMobBoss.java
+++ b/Mage.Sets/src/mage/cards/k/KrenkoMobBoss.java
@@ -1,10 +1,9 @@
-
package mage.cards.k;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.CardImpl;
@@ -12,25 +11,22 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
-import mage.constants.Zone;
-import mage.filter.common.FilterControlledCreaturePermanent;
-import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.filter.common.FilterControlledPermanent;
import mage.game.permanent.token.GoblinToken;
+import java.util.UUID;
+
/**
- *
* @author North
*/
public final class KrenkoMobBoss extends CardImpl {
- private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("the number of Goblins you control");
-
- static {
- filter.add(new SubtypePredicate(SubType.GOBLIN));
- }
+ private static final FilterControlledPermanent filter
+ = new FilterControlledPermanent(SubType.GOBLIN, "the number of Goblins you control");
+ private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
public KrenkoMobBoss(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.GOBLIN);
this.subtype.add(SubType.WARRIOR);
@@ -39,12 +35,12 @@ public final class KrenkoMobBoss extends CardImpl {
this.toughness = new MageInt(3);
// {tap}: create X 1/1 red Goblin creature tokens, where X is the number of Goblins you control.
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD,
- new CreateTokenEffect(new GoblinToken(), new PermanentsOnBattlefieldCount(filter)),
- new TapSourceCost()));
+ this.addAbility(new SimpleActivatedAbility(
+ new CreateTokenEffect(new GoblinToken(), xValue), new TapSourceCost()
+ ));
}
- public KrenkoMobBoss(final KrenkoMobBoss card) {
+ private KrenkoMobBoss(final KrenkoMobBoss card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/k/KrrikSonOfYawgmoth.java b/Mage.Sets/src/mage/cards/k/KrrikSonOfYawgmoth.java
new file mode 100644
index 00000000000..20e98faf09c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/k/KrrikSonOfYawgmoth.java
@@ -0,0 +1,102 @@
+package mage.cards.k;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.ObjectColor;
+import mage.abilities.Ability;
+import mage.abilities.common.SpellCastControllerTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ContinuousEffectImpl;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.keyword.LifelinkAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Layer;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.constants.SubLayer;
+import mage.constants.SuperType;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import mage.filter.FilterMana;
+import mage.filter.FilterSpell;
+import mage.filter.predicate.mageobject.ColorPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+/**
+ *
+ * @author ssouders412
+ */
+public final class KrrikSonOfYawgmoth extends CardImpl {
+
+ private static final FilterSpell filterSpell = new FilterSpell("a black spell");
+
+ static {
+ filterSpell.add(new ColorPredicate(ObjectColor.BLACK));
+ }
+
+ public KrrikSonOfYawgmoth(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B/P}{B/P}{B/P}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HORROR);
+ this.subtype.add(SubType.MINION);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // ({B/P} can be paid with either {B} or 2 life.)
+
+ // Lifelink
+ this.addAbility(LifelinkAbility.getInstance());
+
+ // For each {B} in a cost, you may pay 2 life rather than pay that mana.
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new KrrikSonOfYawgmothPhyrexianEffect()));
+
+ // Whenever you cast a black spell, put a +1/+1 counter on K'rrik, Son of Yawgmoth.
+ this.addAbility(new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), filterSpell, false));
+ }
+
+ private KrrikSonOfYawgmoth(final KrrikSonOfYawgmoth card) {
+ super(card);
+ }
+
+ @Override
+ public KrrikSonOfYawgmoth copy() {
+ return new KrrikSonOfYawgmoth(this);
+ }
+}
+
+class KrrikSonOfYawgmothPhyrexianEffect extends ContinuousEffectImpl {
+
+ public KrrikSonOfYawgmothPhyrexianEffect() {
+ super(Duration.WhileOnBattlefield, Layer.PlayerEffects, SubLayer.NA, Outcome.Benefit);
+ this.staticText = "for each {B} in a cost, you may pay 2 life rather than pay that mana";
+ }
+
+ public KrrikSonOfYawgmothPhyrexianEffect(final KrrikSonOfYawgmothPhyrexianEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public KrrikSonOfYawgmothPhyrexianEffect copy() {
+ return new KrrikSonOfYawgmothPhyrexianEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent sourcePermanent = game.getPermanent(source.getSourceId());
+ Player controller = game.getPlayer(source.getControllerId());
+ FilterMana phyrexianBlack = new FilterMana();
+
+ phyrexianBlack.setBlack(true);
+ if (controller != null && sourcePermanent != null) {
+ controller.addPhyrexianToColors(phyrexianBlack);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/k/KruphixGodOfHorizons.java b/Mage.Sets/src/mage/cards/k/KruphixGodOfHorizons.java
index 0bdd3250f79..c5bbad1ce63 100644
--- a/Mage.Sets/src/mage/cards/k/KruphixGodOfHorizons.java
+++ b/Mage.Sets/src/mage/cards/k/KruphixGodOfHorizons.java
@@ -1,12 +1,9 @@
-
package mage.cards.k;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.DevotionCount;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect;
@@ -17,8 +14,9 @@ import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class KruphixGodOfHorizons extends CardImpl {
@@ -33,20 +31,22 @@ public final class KruphixGodOfHorizons extends CardImpl {
// Indestructible
this.addAbility(IndestructibleAbility.getInstance());
+
// As long as your devotion to green and blue is less than seven, Kruhpix isn't a creature.
- Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.G, ColoredManaSymbol.U), 7);
- effect.setText("As long as your devotion to green and blue is less than seven, Kruhpix isn't a creature");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.GU, 7))
+ .addHint(DevotionCount.GU.getHint()));
// You have no maximum hand size.
- effect = new MaximumHandSizeControllerEffect(Integer.MAX_VALUE, Duration.WhileOnBattlefield, MaximumHandSizeControllerEffect.HandSizeModification.SET);
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ this.addAbility(new SimpleStaticAbility(new MaximumHandSizeControllerEffect(
+ Integer.MAX_VALUE, Duration.WhileOnBattlefield,
+ MaximumHandSizeControllerEffect.HandSizeModification.SET
+ )));
// If unused mana would empty from your mana pool, that mana becomes colorless instead.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new KruphixGodOfHorizonsEffect()));
+ this.addAbility(new SimpleStaticAbility(new KruphixGodOfHorizonsEffect()));
}
- public KruphixGodOfHorizons(final KruphixGodOfHorizons card) {
+ private KruphixGodOfHorizons(final KruphixGodOfHorizons card) {
super(card);
}
@@ -58,12 +58,12 @@ public final class KruphixGodOfHorizons extends CardImpl {
class KruphixGodOfHorizonsEffect extends ReplacementEffectImpl {
- public KruphixGodOfHorizonsEffect() {
+ KruphixGodOfHorizonsEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit);
staticText = "If you would lose unspent mana, that mana becomes colorless instead.";
}
- public KruphixGodOfHorizonsEffect(final KruphixGodOfHorizonsEffect effect) {
+ private KruphixGodOfHorizonsEffect(final KruphixGodOfHorizonsEffect effect) {
super(effect);
}
diff --git a/Mage.Sets/src/mage/cards/k/KumenasSpeaker.java b/Mage.Sets/src/mage/cards/k/KumenasSpeaker.java
index 58cc2dd7779..9626941ed44 100644
--- a/Mage.Sets/src/mage/cards/k/KumenasSpeaker.java
+++ b/Mage.Sets/src/mage/cards/k/KumenasSpeaker.java
@@ -1,22 +1,21 @@
-
package mage.cards.k;
-import java.util.UUID;
import mage.MageInt;
+import mage.MageObject;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.BoostSourceWhileControlsEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.Zone;
import mage.filter.FilterPermanent;
-import mage.filter.predicate.Predicates;
-import mage.filter.predicate.mageobject.SubtypePredicate;
-import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.filter.predicate.ObjectSourcePlayer;
+import mage.filter.predicate.ObjectSourcePlayerPredicate;
+import mage.game.Game;
+
+import java.util.UUID;
/**
- *
* @author TheElk801
*/
public final class KumenasSpeaker extends CardImpl {
@@ -24,10 +23,7 @@ public final class KumenasSpeaker extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("another Merfolk or an Island");
static {
- filter.add(AnotherPredicate.instance);
- filter.add(Predicates.or(
- new SubtypePredicate(SubType.ISLAND),
- new SubtypePredicate(SubType.MERFOLK)));
+ filter.add(KumenasSpeakerPredicate.instance);
}
public KumenasSpeaker(UUID ownerId, CardSetInfo setInfo) {
@@ -39,10 +35,10 @@ public final class KumenasSpeaker extends CardImpl {
this.toughness = new MageInt(1);
// Kumena's Omenspeaker gets +1/+1 as long as you control another Merfolk or Island.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceWhileControlsEffect(filter, 1, 1)));
+ this.addAbility(new SimpleStaticAbility(new BoostSourceWhileControlsEffect(filter, 1, 1)));
}
- public KumenasSpeaker(final KumenasSpeaker card) {
+ private KumenasSpeaker(final KumenasSpeaker card) {
super(card);
}
@@ -51,3 +47,17 @@ public final class KumenasSpeaker extends CardImpl {
return new KumenasSpeaker(this);
}
}
+
+enum KumenasSpeakerPredicate implements ObjectSourcePlayerPredicate> {
+ instance;
+
+ @Override
+ public boolean apply(ObjectSourcePlayer input, Game game) {
+ MageObject obj = input.getObject();
+ if (obj.getId().equals(input.getSourceId())) {
+ return obj.hasSubtype(SubType.ISLAND, game);
+ }
+ return obj.hasSubtype(SubType.ISLAND, game)
+ || obj.hasSubtype(SubType.MERFOLK, game);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/k/KunorosHoundOfAthreos.java b/Mage.Sets/src/mage/cards/k/KunorosHoundOfAthreos.java
new file mode 100644
index 00000000000..fe8e6d8b153
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/k/KunorosHoundOfAthreos.java
@@ -0,0 +1,118 @@
+package mage.cards.k;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
+import mage.abilities.keyword.LifelinkAbility;
+import mage.abilities.keyword.MenaceAbility;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.events.ZoneChangeEvent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class KunorosHoundOfAthreos extends CardImpl {
+
+ public KunorosHoundOfAthreos(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{B}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HOUND);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Vigilance
+ this.addAbility(VigilanceAbility.getInstance());
+
+ // Menace
+ this.addAbility(new MenaceAbility());
+
+ // Lifelink
+ this.addAbility(LifelinkAbility.getInstance());
+
+ // Creature cards in graveyards can't enter the battlefield.
+ this.addAbility(new SimpleStaticAbility(new KunorosHoundOfAthreosEnterEffect()));
+
+ // Players can't cast spells from graveyards.
+ this.addAbility(new SimpleStaticAbility(new KunorosHoundOfAthreosCastEffect()));
+ }
+
+ private KunorosHoundOfAthreos(final KunorosHoundOfAthreos card) {
+ super(card);
+ }
+
+ @Override
+ public KunorosHoundOfAthreos copy() {
+ return new KunorosHoundOfAthreos(this);
+ }
+}
+
+class KunorosHoundOfAthreosEnterEffect extends ContinuousRuleModifyingEffectImpl {
+
+ KunorosHoundOfAthreosEnterEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.Benefit);
+ staticText = "creature cards in graveyards can't enter the battlefield";
+ }
+
+ private KunorosHoundOfAthreosEnterEffect(final KunorosHoundOfAthreosEnterEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public KunorosHoundOfAthreosEnterEffect copy() {
+ return new KunorosHoundOfAthreosEnterEffect(this);
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.ZONE_CHANGE;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
+ if (zEvent.getToZone() != Zone.BATTLEFIELD
+ || zEvent.getFromZone() != Zone.GRAVEYARD) {
+ return false;
+ }
+ Card card = game.getCard(zEvent.getTargetId());
+ return card != null && card.isCreature();
+ }
+}
+
+class KunorosHoundOfAthreosCastEffect extends ContinuousRuleModifyingEffectImpl {
+
+ KunorosHoundOfAthreosCastEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.Benefit);
+ staticText = "players can't cast spells from graveyards";
+ }
+
+ private KunorosHoundOfAthreosCastEffect(final KunorosHoundOfAthreosCastEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public KunorosHoundOfAthreosCastEffect copy() {
+ return new KunorosHoundOfAthreosCastEffect(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) {
+ return game.getCard(event.getSourceId()) != null
+ && game.getState().getZone(event.getSourceId()) == Zone.GRAVEYARD;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/l/LaquatussChampion.java b/Mage.Sets/src/mage/cards/l/LaquatussChampion.java
index d8faca04877..d133fca50c8 100644
--- a/Mage.Sets/src/mage/cards/l/LaquatussChampion.java
+++ b/Mage.Sets/src/mage/cards/l/LaquatussChampion.java
@@ -1,4 +1,3 @@
-
package mage.cards.l;
import java.util.UUID;
@@ -7,8 +6,8 @@ import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.AdjustingSourceCosts;
import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.Effect;
import mage.abilities.effects.common.GainLifeTargetEffect;
import mage.abilities.effects.common.LoseLifeTargetEffect;
import mage.abilities.effects.common.RegenerateSourceEffect;
@@ -39,7 +38,7 @@ public final class LaquatussChampion extends CardImpl {
this.toughness = new MageInt(3);
// When Laquatus's Champion enters the battlefield, target player loses 6 life.
- Ability ability = new LaquatussChampionEntersBattlefieldTriggeredAbility();
+ Ability ability = new LaquatussChampionEntersBattlefieldTriggeredAbility(new LoseLifeTargetEffect(6));
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
// When Laquatus's Champion leaves the battlefield, that player gains 6 life.
@@ -58,29 +57,33 @@ public final class LaquatussChampion extends CardImpl {
}
}
-class LaquatussChampionEntersBattlefieldTriggeredAbility extends EntersBattlefieldTriggeredAbility implements AdjustingSourceCosts {
+class LaquatussChampionEntersBattlefieldTriggeredAbility extends EntersBattlefieldTriggeredAbility {
- public LaquatussChampionEntersBattlefieldTriggeredAbility() {
- super(new LoseLifeTargetEffect(6), false);
+ public LaquatussChampionEntersBattlefieldTriggeredAbility(Effect effect) {
+ super(effect, false);
}
- public LaquatussChampionEntersBattlefieldTriggeredAbility(LaquatussChampionEntersBattlefieldTriggeredAbility ability) {
+ public LaquatussChampionEntersBattlefieldTriggeredAbility(final LaquatussChampionEntersBattlefieldTriggeredAbility ability) {
super(ability);
}
+ @Override
+ public boolean activate(Game game, boolean noMana) {
+ if (super.activate(game, noMana)) {
+ Player player = game.getPlayer(getFirstTarget());
+ if (player != null) {
+ String key = CardUtil.getCardZoneString("targetPlayer", getSourceId(), game);
+ game.getState().setValue(key, player.getId());
+ }
+ return true;
+ }
+ return false;
+ }
+
@Override
public LaquatussChampionEntersBattlefieldTriggeredAbility copy() {
return new LaquatussChampionEntersBattlefieldTriggeredAbility(this);
}
-
- @Override
- public void adjustCosts(Ability ability, Game game) {
- Player player = game.getPlayer(ability.getFirstTarget());
- if (player != null) {
- String key = CardUtil.getCardZoneString("targetPlayer", this.getSourceId(), game);
- game.getState().setValue(key, player.getId());
- }
- }
}
class LaquatussChampionLeavesBattlefieldTriggeredAbility extends LeavesBattlefieldTriggeredAbility {
diff --git a/Mage.Sets/src/mage/cards/l/LashOfThorns.java b/Mage.Sets/src/mage/cards/l/LashOfThorns.java
new file mode 100644
index 00000000000..ecf29616228
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/l/LashOfThorns.java
@@ -0,0 +1,40 @@
+package mage.cards.l;
+
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.keyword.DeathtouchAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class LashOfThorns extends CardImpl {
+
+ public LashOfThorns(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}");
+
+ // Target creature gets +2/+1 and gains deathtouch until end of turn.
+ this.getSpellAbility().addEffect(new BoostTargetEffect(
+ 2, 1, Duration.EndOfTurn
+ ).setText("target creature gets +2/+1"));
+ this.getSpellAbility().addEffect(new GainAbilityTargetEffect(
+ DeathtouchAbility.getInstance(), Duration.EndOfTurn
+ ).setText("and gains deathtouch until end of turn"));
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent());
+ }
+
+ private LashOfThorns(final LashOfThorns card) {
+ super(card);
+ }
+
+ @Override
+ public LashOfThorns copy() {
+ return new LashOfThorns(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/l/LashknifeBarrier.java b/Mage.Sets/src/mage/cards/l/LashknifeBarrier.java
index 994ea460f78..7d7a3538ad0 100644
--- a/Mage.Sets/src/mage/cards/l/LashknifeBarrier.java
+++ b/Mage.Sets/src/mage/cards/l/LashknifeBarrier.java
@@ -1,7 +1,5 @@
-
package mage.cards.l;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@@ -18,15 +16,15 @@ import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
-/**
- *
- * @author LoneFox
+import java.util.UUID;
+/**
+ * @author LoneFox
*/
public final class LashknifeBarrier extends CardImpl {
public LashknifeBarrier(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
// When Lashknife Barrier enters the battlefield, draw a card.
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)));
@@ -79,7 +77,7 @@ class LashknifeBarrierEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent creature = game.getPermanent(event.getTargetId());
- return creature.isControlledBy(source.getControllerId());
+ return creature != null && creature.isControlledBy(source.getControllerId());
}
}
diff --git a/Mage.Sets/src/mage/cards/l/LavaBlister.java b/Mage.Sets/src/mage/cards/l/LavaBlister.java
index 445d35f513f..1ae8f345ef8 100644
--- a/Mage.Sets/src/mage/cards/l/LavaBlister.java
+++ b/Mage.Sets/src/mage/cards/l/LavaBlister.java
@@ -22,7 +22,7 @@ public final class LavaBlister extends CardImpl {
public LavaBlister(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}");
- // Destroy target nonbasic land unless its controller has Lava Blister deal 6 damage to him or her.
+ // Destroy target nonbasic land unless its controller has Lava Blister deal 6 damage to them.
this.getSpellAbility().addTarget(new TargetNonBasicLandPermanent());
this.getSpellAbility().addEffect(new LavaBlisterEffect());
}
@@ -41,7 +41,7 @@ class LavaBlisterEffect extends OneShotEffect {
public LavaBlisterEffect() {
super(Outcome.Detriment);
- this.staticText = "Destroy target nonbasic land unless its controller has {this} deal 6 damage to him or her";
+ this.staticText = "Destroy target nonbasic land unless its controller has {this} deal 6 damage to them";
}
public LavaBlisterEffect(final LavaBlisterEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/l/LavabornMuse.java b/Mage.Sets/src/mage/cards/l/LavabornMuse.java
index c43fa876035..06ed5dc6bae 100644
--- a/Mage.Sets/src/mage/cards/l/LavabornMuse.java
+++ b/Mage.Sets/src/mage/cards/l/LavabornMuse.java
@@ -28,11 +28,11 @@ public final class LavabornMuse extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(3);
- // At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, Lavaborn Muse deals 3 damage to him or her.
+ // At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, Lavaborn Muse deals 3 damage to that player.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3), TargetController.OPPONENT, false, true),
(Condition)new CardsInHandCondition(ComparisonType.FEWER_THAN, 3, null, TargetController.ACTIVE),
- "At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, {this} deals 3 damage to him or her."));
+ "At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, {this} deals 3 damage to that player."));
}
public LavabornMuse(final LavabornMuse card) {
diff --git a/Mage.Sets/src/mage/cards/l/Lavalanche.java b/Mage.Sets/src/mage/cards/l/Lavalanche.java
index 231134ea215..c98e939619c 100644
--- a/Mage.Sets/src/mage/cards/l/Lavalanche.java
+++ b/Mage.Sets/src/mage/cards/l/Lavalanche.java
@@ -28,7 +28,7 @@ public final class Lavalanche extends CardImpl {
public Lavalanche(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}{R}{G}");
- // Lavalanche deals X damage to target player and each creature he or she controls.
+ // Lavalanche deals X damage to target player and each creature they control.
this.getSpellAbility().addEffect(new LavalancheEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
diff --git a/Mage.Sets/src/mage/cards/l/LeadershipVacuum.java b/Mage.Sets/src/mage/cards/l/LeadershipVacuum.java
index 26f7231ecc7..c9667136196 100644
--- a/Mage.Sets/src/mage/cards/l/LeadershipVacuum.java
+++ b/Mage.Sets/src/mage/cards/l/LeadershipVacuum.java
@@ -15,7 +15,6 @@ import mage.players.Player;
import mage.target.TargetPlayer;
import java.util.UUID;
-import java.util.stream.Collectors;
/**
* @author TheElk801
@@ -52,7 +51,7 @@ class LeadershipVacuumEffect extends OneShotEffect {
}
LeadershipVacuumEffect() {
- super(Outcome.Benefit);
+ super(Outcome.Detriment);
staticText = "Target player returns each commander they control from the battlefield to the command zone.";
}
@@ -67,13 +66,13 @@ class LeadershipVacuumEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- Player player = game.getPlayer(source.getControllerId());
+ Player player = game.getPlayer(source.getFirstTarget());
if (player == null) {
return false;
}
- return player.moveCards(game.getBattlefield()
- .getAllActivePermanents(filter, source.getFirstTarget(), game)
- .stream()
- .collect(Collectors.toSet()), Zone.COMMAND, source, game);
+
+ return game.getBattlefield().getAllActivePermanents(filter, source.getFirstTarget(), game).stream()
+ .map(commander -> commander.moveToZone(Zone.COMMAND, source.getId(), game, true))
+ .reduce(true, Boolean::logicalAnd);
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/l/LeoninOfTheLostPride.java b/Mage.Sets/src/mage/cards/l/LeoninOfTheLostPride.java
new file mode 100644
index 00000000000..3d5719900f4
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/l/LeoninOfTheLostPride.java
@@ -0,0 +1,44 @@
+package mage.cards.l;
+
+import mage.MageInt;
+import mage.abilities.common.DiesTriggeredAbility;
+import mage.abilities.effects.common.ExileTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterCard;
+import mage.target.common.TargetCardInOpponentsGraveyard;
+
+import java.util.UUID;
+
+/**
+ * @author jmharmon
+ */
+
+public final class LeoninOfTheLostPride extends CardImpl {
+
+ public LeoninOfTheLostPride(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
+
+ this.subtype.add(SubType.CAT);
+ this.subtype.add(SubType.WARRIOR);
+
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(1);
+
+ // When Leonin of the Lost Pride dies, exile target card from an opponent’s graveyard.
+ DiesTriggeredAbility diesTriggeredAbility = new DiesTriggeredAbility(new ExileTargetEffect());
+ diesTriggeredAbility.addTarget(new TargetCardInOpponentsGraveyard(new FilterCard("card from an opponent's graveyard")));
+ this.addAbility(diesTriggeredAbility);
+ }
+
+ public LeoninOfTheLostPride(final LeoninOfTheLostPride card) {
+ super(card);
+ }
+
+ @Override
+ public LeoninOfTheLostPride copy() {
+ return new LeoninOfTheLostPride(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/l/LeylineOfAbundance.java b/Mage.Sets/src/mage/cards/l/LeylineOfAbundance.java
index 8e1ac037a78..a2e8594ea70 100644
--- a/Mage.Sets/src/mage/cards/l/LeylineOfAbundance.java
+++ b/Mage.Sets/src/mage/cards/l/LeylineOfAbundance.java
@@ -15,7 +15,7 @@ import mage.constants.SetTargetPointer;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.common.FilterControlledCreaturePermanent;
import java.util.UUID;
@@ -24,7 +24,7 @@ import java.util.UUID;
*/
public final class LeylineOfAbundance extends CardImpl {
- private static final FilterPermanent filter = new FilterCreaturePermanent("you tap a creature");
+ private static final FilterPermanent filter = new FilterControlledCreaturePermanent("you tap a creature");
public LeylineOfAbundance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}{G}");
diff --git a/Mage.Sets/src/mage/cards/l/Lhurgoyf.java b/Mage.Sets/src/mage/cards/l/Lhurgoyf.java
index 4d6594f74d7..3318925f48a 100644
--- a/Mage.Sets/src/mage/cards/l/Lhurgoyf.java
+++ b/Mage.Sets/src/mage/cards/l/Lhurgoyf.java
@@ -1,4 +1,3 @@
-
package mage.cards.l;
import java.util.UUID;
@@ -10,13 +9,13 @@ import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
+import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
@@ -27,7 +26,7 @@ import mage.players.Player;
public final class Lhurgoyf extends CardImpl {
public Lhurgoyf(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}");
this.subtype.add(SubType.LHURGOYF);
this.power = new MageInt(0);
@@ -73,7 +72,7 @@ class LhurgoyfEffect extends ContinuousEffectImpl {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
- number += player.getGraveyard().count(new FilterCreatureCard(), game);
+ number += player.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game);
}
}
diff --git a/Mage.Sets/src/mage/cards/l/LifesFinale.java b/Mage.Sets/src/mage/cards/l/LifesFinale.java
index 5c8d83a1384..181dedf212c 100644
--- a/Mage.Sets/src/mage/cards/l/LifesFinale.java
+++ b/Mage.Sets/src/mage/cards/l/LifesFinale.java
@@ -69,7 +69,7 @@ class LifesFinaleEffect extends OneShotEffect {
Player opponent = game.getPlayer(source.getFirstTarget());
Player player = game.getPlayer(source.getControllerId());
if (player != null && opponent != null) {
- TargetCardInLibrary target = new TargetCardInLibrary(0, 3, new FilterCreatureCard("creature cards from his library to put in his graveyard"));
+ TargetCardInLibrary target = new TargetCardInLibrary(0, 3, new FilterCreatureCard("creature cards from their library to put in their graveyard"));
if (player.searchLibrary(target, source, game, opponent.getId())) {
player.moveCards(new CardsImpl(target.getTargets()), Zone.GRAVEYARD, source, game);
}
diff --git a/Mage.Sets/src/mage/cards/l/LightningHelix.java b/Mage.Sets/src/mage/cards/l/LightningHelix.java
index dfc19e9ad4c..1688fce7fc5 100644
--- a/Mage.Sets/src/mage/cards/l/LightningHelix.java
+++ b/Mage.Sets/src/mage/cards/l/LightningHelix.java
@@ -17,6 +17,7 @@ public final class LightningHelix extends CardImpl {
public LightningHelix(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}{W}");
+ // Lightning Helix deals 3 damage to any target and you gain 3 life.
this.getSpellAbility().addTarget(new TargetAnyTarget());
this.getSpellAbility().addEffect(new DamageTargetEffect(3));
this.getSpellAbility().addEffect(new GainLifeEffect(3).concatBy("and"));
diff --git a/Mage.Sets/src/mage/cards/l/LilianaVess.java b/Mage.Sets/src/mage/cards/l/LilianaVess.java
index 63f4bf5d781..0e1c914e2ca 100644
--- a/Mage.Sets/src/mage/cards/l/LilianaVess.java
+++ b/Mage.Sets/src/mage/cards/l/LilianaVess.java
@@ -1,6 +1,8 @@
-
package mage.cards.l;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
@@ -11,20 +13,16 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.common.TargetCardInLibrary;
-import java.util.LinkedHashSet;
-import java.util.Set;
-import java.util.UUID;
-
/**
*
* @author BetaSteward_at_googlemail.com
@@ -80,7 +78,7 @@ class LilianaVessEffect extends OneShotEffect {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
- creatureCards.addAll(player.getGraveyard().getCards(new FilterCreatureCard(), game));
+ creatureCards.addAll(player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game));
}
}
controller.moveCards(creatureCards, Zone.BATTLEFIELD, source, game, false, false, false, null);
diff --git a/Mage.Sets/src/mage/cards/l/LilianasElite.java b/Mage.Sets/src/mage/cards/l/LilianasElite.java
index 48e7008950a..7d21313f2ae 100644
--- a/Mage.Sets/src/mage/cards/l/LilianasElite.java
+++ b/Mage.Sets/src/mage/cards/l/LilianasElite.java
@@ -1,4 +1,3 @@
-
package mage.cards.l;
import java.util.UUID;
@@ -11,10 +10,10 @@ import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
+import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -23,13 +22,13 @@ import mage.filter.common.FilterCreatureCard;
public final class LilianasElite extends CardImpl {
public LilianasElite(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.subtype.add(SubType.ZOMBIE);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Liliana's Elite gets +1/+1 for each creature card in your graveyard.
- DynamicValue amount = new CardsInControllerGraveyardCount(new FilterCreatureCard());
+ DynamicValue amount = new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE);
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(amount, amount, Duration.WhileOnBattlefield));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/l/LilianasIndignation.java b/Mage.Sets/src/mage/cards/l/LilianasIndignation.java
index cbdcff84a25..67d0d59c1c7 100644
--- a/Mage.Sets/src/mage/cards/l/LilianasIndignation.java
+++ b/Mage.Sets/src/mage/cards/l/LilianasIndignation.java
@@ -1,4 +1,3 @@
-
package mage.cards.l;
import java.util.Set;
@@ -13,7 +12,7 @@ import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
@@ -25,7 +24,7 @@ import mage.target.TargetPlayer;
public final class LilianasIndignation extends CardImpl {
public LilianasIndignation(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}");
// Put the top X cards of your library into your graveyard. Target player loses 2 life for each creature card put into your graveyard this way.
this.getSpellAbility().addEffect(new LilianasIndignationEffect());
@@ -70,7 +69,7 @@ class LilianasIndignationEffect extends OneShotEffect {
Set movedCards = controller.moveCardsToGraveyardWithInfo(cardsToGraveyard.getCards(game), source, game, Zone.LIBRARY);
Cards cardsMoved = new CardsImpl();
cardsMoved.addAll(movedCards);
- int creatures = cardsMoved.count(new FilterCreatureCard(), game);
+ int creatures = cardsMoved.count(StaticFilters.FILTER_CARD_CREATURE, game);
if (creatures > 0) {
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
if (targetPlayer != null) {
diff --git a/Mage.Sets/src/mage/cards/l/LimDulsHex.java b/Mage.Sets/src/mage/cards/l/LimDulsHex.java
index e49cdd390a6..5d16a313a54 100644
--- a/Mage.Sets/src/mage/cards/l/LimDulsHex.java
+++ b/Mage.Sets/src/mage/cards/l/LimDulsHex.java
@@ -25,7 +25,7 @@ public final class LimDulsHex extends CardImpl {
public LimDulsHex(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}");
- // At the beginning of your upkeep, for each player, Lim-Dul's Hex deals 1 damage to that player unless he or she pays {B} or {3}.
+ // At the beginning of your upkeep, for each player, Lim-Dul's Hex deals 1 damage to that player unless they pay {B} or {3}.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new LimDulsHexEffect(), TargetController.YOU, false));
}
@@ -43,7 +43,7 @@ class LimDulsHexEffect extends OneShotEffect {
public LimDulsHexEffect() {
super(Outcome.Damage);
- this.staticText = "for each player, {this} deals 1 damage to that player unless he or she pays {B} or {3}";
+ this.staticText = "for each player, {this} deals 1 damage to that player unless they pay {B} or {3}";
}
public LimDulsHexEffect(final LimDulsHexEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/l/LimitedResources.java b/Mage.Sets/src/mage/cards/l/LimitedResources.java
index fc97e014235..71ba1053d7b 100644
--- a/Mage.Sets/src/mage/cards/l/LimitedResources.java
+++ b/Mage.Sets/src/mage/cards/l/LimitedResources.java
@@ -31,7 +31,7 @@ public final class LimitedResources extends CardImpl {
public LimitedResources(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}");
- // When Limited Resources enters the battlefield, each player chooses five lands he or she controls and sacrifices the rest.
+ // When Limited Resources enters the battlefield, each player chooses five lands they control and sacrifices the rest.
this.addAbility(new EntersBattlefieldTriggeredAbility(new LimitedResourcesEffect(), false));
// Players can't play lands as long as ten or more lands are on the battlefield.
@@ -59,7 +59,7 @@ class LimitedResourcesEffect extends OneShotEffect {
public LimitedResourcesEffect() {
super(Outcome.Benefit);
- this.staticText = "each player chooses five lands he or she controls and sacrifices the rest";
+ this.staticText = "each player chooses five lands they control and sacrifices the rest";
}
public LimitedResourcesEffect(final LimitedResourcesEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/l/LindenTheSteadfastQueen.java b/Mage.Sets/src/mage/cards/l/LindenTheSteadfastQueen.java
new file mode 100644
index 00000000000..f016f227fae
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/l/LindenTheSteadfastQueen.java
@@ -0,0 +1,54 @@
+package mage.cards.l;
+
+import mage.MageInt;
+import mage.ObjectColor;
+import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.mageobject.ColorPredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class LindenTheSteadfastQueen extends CardImpl {
+
+ private static final FilterControlledCreaturePermanent filter
+ = new FilterControlledCreaturePermanent("white creature you control");
+
+ static {
+ filter.add(new ColorPredicate(ObjectColor.WHITE));
+ }
+
+ public LindenTheSteadfastQueen(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{W}{W}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.NOBLE);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Vigilance
+ this.addAbility(VigilanceAbility.getInstance());
+
+ // Whenever a white creature you control attacks, you gain 1 life.
+ this.addAbility(new AttacksCreatureYouControlTriggeredAbility(new GainLifeEffect(1), false, filter));
+ }
+
+ private LindenTheSteadfastQueen(final LindenTheSteadfastQueen card) {
+ super(card);
+ }
+
+ @Override
+ public LindenTheSteadfastQueen copy() {
+ return new LindenTheSteadfastQueen(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/l/LinessaZephyrMage.java b/Mage.Sets/src/mage/cards/l/LinessaZephyrMage.java
index 17167aa7b9c..d8cb2687632 100644
--- a/Mage.Sets/src/mage/cards/l/LinessaZephyrMage.java
+++ b/Mage.Sets/src/mage/cards/l/LinessaZephyrMage.java
@@ -57,7 +57,7 @@ public final class LinessaZephyrMage extends CardImpl {
ability.setTargetAdjuster(XCMCPermanentAdjuster.instance);
this.addAbility(ability);
- // Grandeur - Discard another card named Linessa, Zephyr Mage: Target player returns a creature he or she controls to its owner's hand, then repeats this process for an artifact, an enchantment, and a land.
+ // Grandeur - Discard another card named Linessa, Zephyr Mage: Target player returns a creature they control to its owner's hand, then repeats this process for an artifact, an enchantment, and a land.
ability = new GrandeurAbility(new LinessaZephyrMageEffect(), "Linessa, Zephyr Mage");
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
@@ -77,7 +77,7 @@ class LinessaZephyrMageEffect extends OneShotEffect {
LinessaZephyrMageEffect() {
super(Outcome.ReturnToHand);
- this.staticText = "Target player returns a creature he or she controls to its owner's hand, then repeats this process for an artifact, an enchantment, and a land";
+ this.staticText = "Target player returns a creature they control to its owner's hand, then repeats this process for an artifact, an enchantment, and a land";
}
LinessaZephyrMageEffect(final LinessaZephyrMageEffect effect) {
@@ -95,7 +95,7 @@ class LinessaZephyrMageEffect extends OneShotEffect {
if (controller != null) {
Player targetPlayer = game.getPlayer(source.getFirstTarget());
if (targetPlayer != null) {
- // Target player returns a creature he or she controls to its owner's hand,
+ // Target player returns a creature they control to its owner's hand,
Target target = new TargetControlledCreaturePermanent();
target.setNotTarget(true);
if (target.choose(Outcome.ReturnToHand, targetPlayer.getId(), source.getSourceId(), game)) {
diff --git a/Mage.Sets/src/mage/cards/l/LivingDeath.java b/Mage.Sets/src/mage/cards/l/LivingDeath.java
index 032aa651d8f..904c560c385 100644
--- a/Mage.Sets/src/mage/cards/l/LivingDeath.java
+++ b/Mage.Sets/src/mage/cards/l/LivingDeath.java
@@ -1,4 +1,3 @@
-
package mage.cards.l;
import java.util.HashMap;
@@ -16,7 +15,6 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -30,7 +28,7 @@ public final class LivingDeath extends CardImpl {
public LivingDeath(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}{B}");
- // Each player exiles all creature cards from their graveyard, then sacrifices all creatures he or she controls, then puts all cards he or she exiled this way onto the battlefield.
+ // Each player exiles all creature cards from their graveyard, then sacrifices all creatures they control, then puts all cards they exiled this way onto the battlefield.
this.getSpellAbility().addEffect(new LivingDeathEffect());
}
@@ -48,7 +46,7 @@ class LivingDeathEffect extends OneShotEffect {
public LivingDeathEffect() {
super(Outcome.Benefit);
- this.staticText = "Each player exiles all creature cards from their graveyard, then sacrifices all creatures he or she controls, then puts all cards he or she exiled this way onto the battlefield";
+ this.staticText = "Each player exiles all creature cards from their graveyard, then sacrifices all creatures they control, then puts all cards they exiled this way onto the battlefield";
}
public LivingDeathEffect(final LivingDeathEffect effect) {
@@ -66,13 +64,12 @@ class LivingDeathEffect extends OneShotEffect {
MageObject sourceObject = game.getObject(source.getSourceId());
if (controller != null && sourceObject != null) {
Map> exiledCards = new HashMap<>();
-
+
// Move creature cards from graveyard to exile
-
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
- Set cardsPlayer = player.getGraveyard().getCards(new FilterCreatureCard(), game);
+ Set cardsPlayer = player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game);
if (!cardsPlayer.isEmpty()) {
exiledCards.put(player.getId(), cardsPlayer);
player.moveCards(cardsPlayer, Zone.EXILED, source, game);
@@ -80,22 +77,20 @@ class LivingDeathEffect extends OneShotEffect {
}
}
game.applyEffects();
-
+
// Sacrifice all creatures
-
for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game)) {
permanent.sacrifice(source.getSourceId(), game);
}
game.applyEffects();
-
+
// Exiled cards are put onto the battlefield at the same time under their owner's control
-
Set cardsToReturnFromExile = new HashSet<>();
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
Set cardsPlayer = exiledCards.get(playerId);
- if (cardsPlayer != null
+ if (cardsPlayer != null
&& !cardsPlayer.isEmpty()) {
cardsToReturnFromExile.addAll(cardsPlayer);
}
diff --git a/Mage.Sets/src/mage/cards/l/LivingEnd.java b/Mage.Sets/src/mage/cards/l/LivingEnd.java
index 32450f13e91..8868bb5357e 100644
--- a/Mage.Sets/src/mage/cards/l/LivingEnd.java
+++ b/Mage.Sets/src/mage/cards/l/LivingEnd.java
@@ -1,4 +1,3 @@
-
package mage.cards.l;
import java.util.HashMap;
@@ -17,7 +16,6 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -36,7 +34,7 @@ public final class LivingEnd extends CardImpl {
// Suspend 3-{2}{B}{B}
this.addAbility(new SuspendAbility(3, new ManaCostsImpl("{2}{B}{B}"), this));
// Each player exiles all creature cards from their graveyard, then sacrifices all creatures
- // he or she controls, then puts all cards he or she exiled this way onto the battlefield.
+ // they control, then puts all cards they exiled this way onto the battlefield.
this.getSpellAbility().addEffect(new LivingEndEffect());
}
@@ -55,7 +53,7 @@ class LivingEndEffect extends OneShotEffect {
public LivingEndEffect() {
super(Outcome.Benefit);
- this.staticText = "Each player exiles all creature cards from their graveyard, then sacrifices all creatures he or she controls, then puts all cards he or she exiled this way onto the battlefield";
+ this.staticText = "Each player exiles all creature cards from their graveyard, then sacrifices all creatures they control, then puts all cards they exiled this way onto the battlefield";
}
public LivingEndEffect(final LivingEndEffect effect) {
@@ -77,7 +75,7 @@ class LivingEndEffect extends OneShotEffect {
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
- Set cardsPlayer = player.getGraveyard().getCards(new FilterCreatureCard(), game);
+ Set cardsPlayer = player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game);
if (!cardsPlayer.isEmpty()) {
exiledCards.put(player.getId(), cardsPlayer);
player.moveCards(cardsPlayer, Zone.EXILED, source, game);
diff --git a/Mage.Sets/src/mage/cards/l/LivingLore.java b/Mage.Sets/src/mage/cards/l/LivingLore.java
index 85b5d1144f9..1b568b8e651 100644
--- a/Mage.Sets/src/mage/cards/l/LivingLore.java
+++ b/Mage.Sets/src/mage/cards/l/LivingLore.java
@@ -1,4 +1,3 @@
-
package mage.cards.l;
import java.util.UUID;
@@ -36,12 +35,14 @@ public final class LivingLore extends CardImpl {
this.toughness = new MageInt(0);
// As Living Lore enters the battlefield, exile an instant or sorcery card from your graveyard.
- this.addAbility(new AsEntersBattlefieldAbility(new LivingLoreExileEffect(), "exile an instant or sorcery card from your graveyard"));
+ this.addAbility(new AsEntersBattlefieldAbility(new LivingLoreExileEffect(),
+ "exile an instant or sorcery card from your graveyard"));
// Living Lore's power and toughness are each equal to the exiled card's converted mana cost.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new LivingLoreSetPowerToughnessSourceEffect()));
- // Whenever Living Lore deals combat damage, you may sacrifice it. If you do, you may cast the exiled card without paying its mana cost.
+ // Whenever Living Lore deals combat damage, you may sacrifice it. If you do,
+ // you may cast the exiled card without paying its mana cost.
this.addAbility(new DealsCombatDamageTriggeredAbility(new LivingLoreSacrificeEffect(), true));
}
@@ -58,7 +59,7 @@ public final class LivingLore extends CardImpl {
class LivingLoreExileEffect extends OneShotEffect {
public LivingLoreExileEffect() {
- super(Outcome.Exile);
+ super(Outcome.Benefit);
staticText = "exile an instant or sorcery card from your graveyard";
}
@@ -76,12 +77,15 @@ class LivingLoreExileEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanentEntering(source.getSourceId());
if (sourcePermanent != null && controller != null) {
- TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(new FilterInstantOrSorceryCard("instant or sorcery card from your graveyard"));
+ TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(
+ new FilterInstantOrSorceryCard("instant or sorcery card from your graveyard"));
if (controller.chooseTarget(outcome, target, source, game)) {
- UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), game.getState().getZoneChangeCounter(source.getSourceId()) + 1);
+ UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(),
+ game.getState().getZoneChangeCounter(source.getSourceId()) + 1);
Card card = controller.getGraveyard().get(target.getFirstTarget(), game);
if (card != null) {
- controller.moveCardsToExile(card, source, game, true, exileId, sourcePermanent.getIdName());
+ controller.moveCardsToExile(card, source, game, true, exileId,
+ sourcePermanent.getIdName());
}
}
return true;
@@ -142,8 +146,9 @@ class LivingLoreSetPowerToughnessSourceEffect extends ContinuousEffectImpl {
class LivingLoreSacrificeEffect extends OneShotEffect {
public LivingLoreSacrificeEffect() {
- super(Outcome.Benefit);
- this.staticText = "you may sacrifice it. If you do, you may cast the exiled card without paying its mana cost";
+ super(Outcome.PlayForFree);
+ this.staticText = "you may sacrifice it. If you do, you may cast "
+ + "the exiled card without paying its mana cost";
}
public LivingLoreSacrificeEffect(final LivingLoreSacrificeEffect effect) {
@@ -161,9 +166,12 @@ class LivingLoreSacrificeEffect extends OneShotEffect {
if (controller != null) {
MageObject mageObject = source.getSourceObject(game);
Permanent permanent = game.getPermanent(source.getSourceId());
- if (permanent != null && mageObject != null && new MageObjectReference(permanent, game).refersTo(mageObject, game)) {
+ if (permanent != null
+ && mageObject != null
+ && new MageObjectReference(permanent, game).refersTo(mageObject, game)) {
if (permanent.sacrifice(source.getSourceId(), game)) {
- UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
+ UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(),
+ source.getSourceObjectZoneChangeCounter());
if (exileId != null) {
ExileZone exileZone = game.getExile().getExileZone(exileId);
Card exiledCard = null;
@@ -175,7 +183,10 @@ class LivingLoreSacrificeEffect extends OneShotEffect {
}
if (exiledCard != null) {
if (exiledCard.getSpellAbility().canChooseTarget(game)) {
- controller.cast(exiledCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + exiledCard.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(exiledCard, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + exiledCard.getId(), null);
}
}
}
diff --git a/Mage.Sets/src/mage/cards/l/LlawanCephalidEmpress.java b/Mage.Sets/src/mage/cards/l/LlawanCephalidEmpress.java
index ed0cb60905d..9821dd9e9cc 100644
--- a/Mage.Sets/src/mage/cards/l/LlawanCephalidEmpress.java
+++ b/Mage.Sets/src/mage/cards/l/LlawanCephalidEmpress.java
@@ -1,7 +1,6 @@
package mage.cards.l;
-import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.ObjectColor;
@@ -23,8 +22,9 @@ import mage.game.Game;
import mage.game.events.GameEvent;
import mage.players.Player;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class LlawanCephalidEmpress extends CardImpl {
@@ -38,9 +38,9 @@ public final class LlawanCephalidEmpress extends CardImpl {
}
public LlawanCephalidEmpress(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
addSuperType(SuperType.LEGENDARY);
- this.subtype.add(SubType.CEPHALID);
+ this.subtype.add(SubType.CEPHALID, SubType.NOBLE);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
@@ -90,7 +90,7 @@ class LlawanCephalidRuleModifyingEffect extends ContinuousRuleModifyingEffectImp
public boolean apply(Game game, Ability source) {
return true;
}
-
+
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
MageObject mageObject = game.getObject(source.getSourceId());
@@ -99,12 +99,12 @@ class LlawanCephalidRuleModifyingEffect extends ContinuousRuleModifyingEffectImp
}
return null;
}
-
+
@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) {
Player controller = game.getPlayer(source.getControllerId());
diff --git a/Mage.Sets/src/mage/cards/l/Lobotomy.java b/Mage.Sets/src/mage/cards/l/Lobotomy.java
index c3decfd9799..784a5d4e14b 100644
--- a/Mage.Sets/src/mage/cards/l/Lobotomy.java
+++ b/Mage.Sets/src/mage/cards/l/Lobotomy.java
@@ -111,7 +111,7 @@ class LobotomyEffect extends OneShotEffect {
}
// search cards in Library
- // If the player has no nonland cards in their hand, you can still search that player's library and have him or her shuffle it.
+ // If the player has no nonland cards in their hand, you can still search that player's library and have that player shuffle it.
if (chosenCard != null || controller.chooseUse(outcome, "Search library anyway?", source, game)) {
TargetCardInLibrary targetCardsLibrary = new TargetCardInLibrary(0, Integer.MAX_VALUE, filterNamedCards);
controller.searchLibrary(targetCardsLibrary, source, game, targetPlayer.getId());
diff --git a/Mage.Sets/src/mage/cards/l/LochDragon.java b/Mage.Sets/src/mage/cards/l/LochDragon.java
new file mode 100644
index 00000000000..aedf384cff8
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/l/LochDragon.java
@@ -0,0 +1,45 @@
+package mage.cards.l;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility;
+import mage.abilities.costs.common.DiscardCardCost;
+import mage.abilities.effects.common.DoIfCostPaid;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class LochDragon extends CardImpl {
+
+ public LochDragon(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U/R}{U/R}{U/R}{U/R}");
+
+ this.subtype.add(SubType.DRAGON);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(2);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Whenever Loch Dragon enters the battlefield or attacks, you may discard a card. If you do, draw a card.
+ this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(
+ new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new DiscardCardCost())
+ ));
+ }
+
+ private LochDragon(final LochDragon card) {
+ super(card);
+ }
+
+ @Override
+ public LochDragon copy() {
+ return new LochDragon(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/l/LochmereSerpent.java b/Mage.Sets/src/mage/cards/l/LochmereSerpent.java
new file mode 100644
index 00000000000..80d89e826fa
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/l/LochmereSerpent.java
@@ -0,0 +1,82 @@
+package mage.cards.l;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.ActivateAsSorceryActivatedAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.ExileTargetEffect;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect;
+import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect;
+import mage.abilities.keyword.FlashAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterControlledPermanent;
+import mage.target.common.TargetCardInOpponentsGraveyard;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class LochmereSerpent extends CardImpl {
+
+ private static final FilterControlledPermanent filter1
+ = new FilterControlledPermanent(SubType.ISLAND, "an Island");
+ private static final FilterControlledPermanent filter2
+ = new FilterControlledPermanent(SubType.SWAMP, "a Swamp");
+
+ public LochmereSerpent(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{B}");
+
+ this.subtype.add(SubType.SERPENT);
+ this.power = new MageInt(7);
+ this.toughness = new MageInt(7);
+
+ // Flash
+ this.addAbility(FlashAbility.getInstance());
+
+ // {U}, Sacrifice an Island: Lochmere Serpent can't be blocked this turn.
+ Ability ability = new SimpleActivatedAbility(
+ new CantBeBlockedSourceEffect(Duration.EndOfTurn), new ManaCostsImpl("{U}")
+ );
+ ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter1)));
+ this.addAbility(ability);
+
+ // {B}, Sacrifice a Swamp: You gain 1 life and draw a card.
+ ability = new SimpleActivatedAbility(new GainLifeEffect(1), new ManaCostsImpl("{B}"));
+ ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and"));
+ ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2)));
+ this.addAbility(ability);
+
+ // {U}{B}: Exile five target cards from an opponent's graveyard. Return Lochmere Serpent from your graveyard to your hand. Activate this ability only any time you could cast a sorcery.
+ ability = new ActivateAsSorceryActivatedAbility(
+ Zone.GRAVEYARD,
+ new ExileTargetEffect().setText("Exile five target cards from an opponent's graveyard."),
+ new ManaCostsImpl("{U}{B}")
+ );
+ ability.addEffect(new ReturnSourceFromGraveyardToHandEffect());
+ ability.addTarget(new TargetCardInOpponentsGraveyard(
+ 5, 5, StaticFilters.FILTER_CARD, true
+ ));
+ this.addAbility(ability);
+ }
+
+ private LochmereSerpent(final LochmereSerpent card) {
+ super(card);
+ }
+
+ @Override
+ public LochmereSerpent copy() {
+ return new LochmereSerpent(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/l/LocthwainGargoyle.java b/Mage.Sets/src/mage/cards/l/LocthwainGargoyle.java
new file mode 100644
index 00000000000..33372594479
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/l/LocthwainGargoyle.java
@@ -0,0 +1,48 @@
+package mage.cards.l;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class LocthwainGargoyle extends CardImpl {
+
+ public LocthwainGargoyle(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}");
+
+ this.subtype.add(SubType.GARGOYLE);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(3);
+
+ // {4}: Locthwain Gargoyle gets +2/+0 and gains flying until end of turn.
+ Ability ability = new SimpleActivatedAbility(new BoostSourceEffect(
+ 2, 0, Duration.EndOfTurn).setText("{this} gets +2/+0"
+ ), new GenericManaCost(4));
+ ability.addEffect(new GainAbilitySourceEffect(
+ FlyingAbility.getInstance(), Duration.EndOfTurn
+ ).setText("and gains flying until end of turn"));
+ this.addAbility(ability);
+ }
+
+ private LocthwainGargoyle(final LocthwainGargoyle card) {
+ super(card);
+ }
+
+ @Override
+ public LocthwainGargoyle copy() {
+ return new LocthwainGargoyle(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/l/LocthwainPaladin.java b/Mage.Sets/src/mage/cards/l/LocthwainPaladin.java
new file mode 100644
index 00000000000..ab4ffa5d211
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/l/LocthwainPaladin.java
@@ -0,0 +1,50 @@
+package mage.cards.l;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.condition.common.AdamantCondition;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.keyword.MenaceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.watchers.common.ManaSpentToCastWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class LocthwainPaladin extends CardImpl {
+
+ public LocthwainPaladin(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(2);
+
+ // Menace
+ this.addAbility(new MenaceAbility());
+
+ // Adamant — If at least three black mana was spent to cast this spell, Locthwain Paladin enters the battlefield with a +1/+1 counter on it.
+ this.addAbility(new EntersBattlefieldAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
+ AdamantCondition.BLACK, "
Adamant — " +
+ "If at least three black mana was spent to cast this spell, " +
+ "{this} enters the battlefield with a +1/+1 counter on it.", ""
+ ), new ManaSpentToCastWatcher());
+ }
+
+ private LocthwainPaladin(final LocthwainPaladin card) {
+ super(card);
+ }
+
+ @Override
+ public LocthwainPaladin copy() {
+ return new LocthwainPaladin(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/l/LonesomeUnicorn.java b/Mage.Sets/src/mage/cards/l/LonesomeUnicorn.java
new file mode 100644
index 00000000000..fefbe07474b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/l/LonesomeUnicorn.java
@@ -0,0 +1,42 @@
+package mage.cards.l;
+
+import mage.MageInt;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.game.permanent.token.KnightToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class LonesomeUnicorn extends AdventureCard {
+
+ public LonesomeUnicorn(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{4}{W}", "Rider in Need", "{2}{W}");
+
+ this.subtype.add(SubType.UNICORN);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Vigilance
+ this.addAbility(VigilanceAbility.getInstance());
+
+ // Rider in Need
+ // Create a 2/2 white Knight creature token with vigilance.
+ this.getSpellCard().getSpellAbility().addEffect(new CreateTokenEffect(new KnightToken()));
+ }
+
+ private LonesomeUnicorn(final LonesomeUnicorn card) {
+ super(card);
+ }
+
+ @Override
+ public LonesomeUnicorn copy() {
+ return new LonesomeUnicorn(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/l/LonghornFirebeast.java b/Mage.Sets/src/mage/cards/l/LonghornFirebeast.java
index 275d4c77c39..7e836cf7346 100644
--- a/Mage.Sets/src/mage/cards/l/LonghornFirebeast.java
+++ b/Mage.Sets/src/mage/cards/l/LonghornFirebeast.java
@@ -31,7 +31,7 @@ public final class LonghornFirebeast extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(2);
- // When Longhorn Firebeast enters the battlefield, any opponent may have it deal 5 damage to him or her. If a player does, sacrifice Longhorn Firebeast.
+ // When Longhorn Firebeast enters the battlefield, any opponent may have it deal 5 damage to them. If a player does, sacrifice Longhorn Firebeast.
this.addAbility(new EntersBattlefieldTriggeredAbility(new LonghornFirebeastEffect(), false));
}
@@ -49,7 +49,7 @@ class LonghornFirebeastEffect extends OneShotEffect {
public LonghornFirebeastEffect() {
super(Outcome.Neutral);
- staticText = "any opponent may have it deal 5 damage to him or her. If a player does, sacrifice {this}";
+ staticText = "any opponent may have it deal 5 damage to them. If a player does, sacrifice {this}";
}
LonghornFirebeastEffect(final LonghornFirebeastEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/l/LordOfTheVoid.java b/Mage.Sets/src/mage/cards/l/LordOfTheVoid.java
index 85b62e47159..ecf3396e0a8 100644
--- a/Mage.Sets/src/mage/cards/l/LordOfTheVoid.java
+++ b/Mage.Sets/src/mage/cards/l/LordOfTheVoid.java
@@ -15,7 +15,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
@@ -76,8 +76,8 @@ class LordOfTheVoidEffect extends OneShotEffect {
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 7));
controller.moveCards(cards, Zone.EXILED, source, game);
- if (!cards.getCards(new FilterCreatureCard(), game).isEmpty()) {
- TargetCard target = new TargetCard(Zone.EXILED, new FilterCreatureCard());
+ if (!cards.getCards(StaticFilters.FILTER_CARD_CREATURE, game).isEmpty()) {
+ TargetCard target = new TargetCard(Zone.EXILED, StaticFilters.FILTER_CARD_CREATURE);
if (controller.chooseTarget(outcome, cards, target, source, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/cards/l/LostLegion.java b/Mage.Sets/src/mage/cards/l/LostLegion.java
new file mode 100644
index 00000000000..9c6ec9dacc8
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/l/LostLegion.java
@@ -0,0 +1,38 @@
+package mage.cards.l;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.keyword.ScryEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class LostLegion extends CardImpl {
+
+ public LostLegion(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}");
+
+ this.subtype.add(SubType.SPIRIT);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // When Lost Legion enters the battlefield, scry 2.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new ScryEffect(2)));
+ }
+
+ private LostLegion(final LostLegion card) {
+ super(card);
+ }
+
+ @Override
+ public LostLegion copy() {
+ return new LostLegion(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/l/LostOrderOfJarkeld.java b/Mage.Sets/src/mage/cards/l/LostOrderOfJarkeld.java
index 012b523cc42..44b3f31f12d 100644
--- a/Mage.Sets/src/mage/cards/l/LostOrderOfJarkeld.java
+++ b/Mage.Sets/src/mage/cards/l/LostOrderOfJarkeld.java
@@ -1,26 +1,30 @@
package mage.cards.l;
import mage.MageInt;
-import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.dynamicvalue.DynamicValue;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.ChooseOpponentEffect;
import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
-import mage.filter.StaticFilters;
-import mage.game.Game;
-
import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.dynamicvalue.AdditiveDynamicValue;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.StaticValue;
+import mage.abilities.effects.Effect;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.game.Game;
+import mage.players.Player;
/**
* @author TheElk801
*/
public final class LostOrderOfJarkeld extends CardImpl {
+ protected FilterCreaturePermanent filter = new FilterCreaturePermanent();
+
public LostOrderOfJarkeld(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}");
@@ -36,8 +40,7 @@ public final class LostOrderOfJarkeld extends CardImpl {
this.addAbility(new SimpleStaticAbility(
Zone.ALL,
new SetPowerToughnessSourceEffect(
- LostOrderOfJarkeldValue.instance, Duration.Custom, SubLayer.CharacteristicDefining_7a
- )
+ new AdditiveDynamicValue(new CreaturesControlledByChosenPlayer(), new StaticValue(1)), Duration.EndOfGame)
));
}
@@ -51,28 +54,32 @@ public final class LostOrderOfJarkeld extends CardImpl {
}
}
-enum LostOrderOfJarkeldValue implements DynamicValue {
- instance;
+class CreaturesControlledByChosenPlayer implements DynamicValue {
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
- if (game.getPermanent(sourceAbility.getSourceId()) == null) {
- return 1;
+ if (sourceAbility != null) {
+ UUID playerId = (UUID) game.getState().getValue(sourceAbility.getSourceId() + ChooseOpponentEffect.VALUE_KEY);
+ Player chosenPlayer = game.getPlayer(playerId);
+ if (chosenPlayer != null) {
+ return game.getBattlefield().countAll(new FilterCreaturePermanent(), chosenPlayer.getId(), game);
+ }
}
- Object obj = game.getState().getValue(sourceAbility.getSourceId().toString() + ChooseOpponentEffect.VALUE_KEY);
- if (!(obj instanceof UUID)) {
- return 1;
- }
- return 1 + game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, (UUID) obj, game).size();
+ return 0;
}
@Override
public DynamicValue copy() {
- return instance;
+ return new CreaturesControlledByChosenPlayer();
}
@Override
public String getMessage() {
- return "1 plus the number of creatures the chosen player controls.";
+ return "1 plus the number of creatures controlled by chosen player";
+ }
+
+ @Override
+ public String toString() {
+ return "1";
}
}
diff --git a/Mage.Sets/src/mage/cards/l/LovestruckBeast.java b/Mage.Sets/src/mage/cards/l/LovestruckBeast.java
new file mode 100644
index 00000000000..8c4904ccfb0
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/l/LovestruckBeast.java
@@ -0,0 +1,88 @@
+package mage.cards.l;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.RestrictionEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.PowerPredicate;
+import mage.filter.predicate.mageobject.ToughnessPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.token.HumanToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class LovestruckBeast extends AdventureCard {
+
+ public LovestruckBeast(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{2}{G}", "Heart's Desire", "{G}");
+
+ this.subtype.add(SubType.BEAST);
+ this.subtype.add(SubType.NOBLE);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(5);
+
+ // Lovestruck Beast can't attack unless you control a 1/1 creature.
+ this.addAbility(new SimpleStaticAbility(new LovestruckBeastEffect()));
+
+ // Heart's Desire
+ // Create a 1/1 white Human creature token.
+ this.getSpellCard().getSpellAbility().addEffect(new CreateTokenEffect(new HumanToken()));
+ }
+
+ private LovestruckBeast(final LovestruckBeast card) {
+ super(card);
+ }
+
+ @Override
+ public LovestruckBeast copy() {
+ return new LovestruckBeast(this);
+ }
+}
+
+class LovestruckBeastEffect extends RestrictionEffect {
+
+ private static final FilterPermanent filter = new FilterCreaturePermanent();
+
+ static {
+ filter.add(new PowerPredicate(ComparisonType.EQUAL_TO, 1));
+ filter.add(new ToughnessPredicate(ComparisonType.EQUAL_TO, 1));
+ }
+
+ LovestruckBeastEffect() {
+ super(Duration.WhileOnBattlefield);
+ staticText = "{this} can't attack unless you control a 1/1 creature";
+ }
+
+ private LovestruckBeastEffect(final LovestruckBeastEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public LovestruckBeastEffect copy() {
+ return new LovestruckBeastEffect(this);
+ }
+
+ @Override
+ public boolean canAttack(Game game, boolean canUseChooseDialogs) {
+ return false;
+ }
+
+ @Override
+ public boolean applies(Permanent permanent, Ability source, Game game) {
+ return permanent.getId().equals(source.getSourceId())
+ && game.getBattlefield().countAll(filter, source.getControllerId(), game) <= 0;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/l/LuckyClover.java b/Mage.Sets/src/mage/cards/l/LuckyClover.java
new file mode 100644
index 00000000000..08ef868750e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/l/LuckyClover.java
@@ -0,0 +1,45 @@
+package mage.cards.l;
+
+import mage.abilities.common.SpellCastControllerTriggeredAbility;
+import mage.abilities.effects.common.CopyTargetSpellEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterSpell;
+import mage.filter.common.FilterInstantOrSorcerySpell;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class LuckyClover extends CardImpl {
+
+ private static final FilterSpell filter
+ = new FilterInstantOrSorcerySpell("an Adventure instant or sorcery spell");
+
+ static {
+ filter.add(new SubtypePredicate(SubType.ADVENTURE));
+ }
+
+ public LuckyClover(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
+
+ // Whenever you cast an Adventure instant or sorcery spell, copy it. You may choose new targets for the copy.
+ this.addAbility(new SpellCastControllerTriggeredAbility(
+ new CopyTargetSpellEffect(true).withSpellName("it"),
+ filter, false, true
+ ));
+ }
+
+ private LuckyClover(final LuckyClover card) {
+ super(card);
+ }
+
+ @Override
+ public LuckyClover copy() {
+ return new LuckyClover(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/l/LudevicNecroAlchemist.java b/Mage.Sets/src/mage/cards/l/LudevicNecroAlchemist.java
index 0dfd90b3e27..45991117b8a 100644
--- a/Mage.Sets/src/mage/cards/l/LudevicNecroAlchemist.java
+++ b/Mage.Sets/src/mage/cards/l/LudevicNecroAlchemist.java
@@ -1,11 +1,11 @@
package mage.cards.l;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.effects.OneShotEffect;
+import mage.abilities.hint.ConditionHint;
import mage.abilities.keyword.PartnerAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -14,8 +14,9 @@ import mage.game.Game;
import mage.players.Player;
import mage.watchers.common.PlayerLostLifeWatcher;
+import java.util.UUID;
+
/**
- *
* @author spjspj
*/
public final class LudevicNecroAlchemist extends CardImpl {
@@ -31,11 +32,10 @@ public final class LudevicNecroAlchemist extends CardImpl {
// At the beginning of each player's end step, that player may draw a card if a player other than you lost life this turn.
this.addAbility(new BeginningOfEndStepTriggeredAbility(
- Zone.BATTLEFIELD,
new LudevicNecroAlchemistEffect(),
TargetController.EACH_PLAYER,
- new LudevicNecroAlchemistCondition(),
- false));
+ false)
+ .addHint(new ConditionHint(LudevicNecroAlchemistCondition.instance, "Player other than you lost life this turn")));
// Partner
this.addAbility(PartnerAbility.getInstance());
@@ -51,17 +51,17 @@ public final class LudevicNecroAlchemist extends CardImpl {
}
}
-class LudevicNecroAlchemistCondition implements Condition {
+enum LudevicNecroAlchemistCondition implements Condition {
+
+ instance;
@Override
public boolean apply(Game game, Ability source) {
PlayerLostLifeWatcher watcher = game.getState().getWatcher(PlayerLostLifeWatcher.class);
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null
- && watcher != null
- && watcher.getLifeLost(controller.getId()) == 0) {
- for (UUID playerId : controller.getInRange()) {
- if (watcher.getLifeLost(playerId) > 0) {
+ if (controller != null && watcher != null) {
+ for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
+ if (!playerId.equals(controller.getId()) && watcher.getLifeLost(playerId) > 0) {
return true;
}
}
@@ -79,7 +79,7 @@ class LudevicNecroAlchemistEffect extends OneShotEffect {
public LudevicNecroAlchemistEffect() {
super(Outcome.DrawCard);
- staticText = "that player may draw a card";
+ staticText = "that player may draw a card if a player other than you lost life this turn";
}
public LudevicNecroAlchemistEffect(final LudevicNecroAlchemistEffect effect) {
@@ -93,6 +93,13 @@ class LudevicNecroAlchemistEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
+ // Ludevic’s triggered ability triggers at the beginning of each player’s end step, including yours,
+ // even if no player has lost life that turn. Whether or not a player has lost life is checked
+ // only as the triggered ability resolves. (2016-11-08)
+ if (!LudevicNecroAlchemistCondition.instance.apply(game, source)) {
+ return false;
+ }
+
Player player = game.getPlayer(game.getActivePlayerId());
if (player != null
&& player.chooseUse(Outcome.DrawCard, "Draw a card?", source, game)) {
diff --git a/Mage.Sets/src/mage/cards/m/MaceOfTheValiant.java b/Mage.Sets/src/mage/cards/m/MaceOfTheValiant.java
new file mode 100644
index 00000000000..9755eccfd1e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MaceOfTheValiant.java
@@ -0,0 +1,60 @@
+package mage.cards.m;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.CountersSourceCount;
+import mage.abilities.effects.common.continuous.BoostEquippedEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.keyword.EquipAbility;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.AttachmentType;
+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 MaceOfTheValiant extends CardImpl {
+
+ private static final DynamicValue xValue = new CountersSourceCount(CounterType.CHARGE);
+
+ public MaceOfTheValiant(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{W}");
+
+ this.subtype.add(SubType.EQUIPMENT);
+
+ // Equipped creature gets +1/+1 for each charge counter on Mace of the Valiant and has vigilance.
+ Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(xValue, xValue));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ VigilanceAbility.getInstance(), AttachmentType.EQUIPMENT
+ ).setText("and has vigilance"));
+ this.addAbility(ability);
+
+ // Whenever a creature enters the battlefield under your control, put a charge counter on Mace of the Valiant.
+ this.addAbility(new EntersBattlefieldControlledTriggeredAbility(
+ new AddCountersSourceEffect(CounterType.CHARGE.createInstance()),
+ StaticFilters.FILTER_PERMANENT_A_CREATURE
+ ));
+
+ // Equip {3}
+ this.addAbility(new EquipAbility(3));
+ }
+
+ private MaceOfTheValiant(final MaceOfTheValiant card) {
+ super(card);
+ }
+
+ @Override
+ public MaceOfTheValiant copy() {
+ return new MaceOfTheValiant(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MadRatter.java b/Mage.Sets/src/mage/cards/m/MadRatter.java
new file mode 100644
index 00000000000..aa38a136333
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MadRatter.java
@@ -0,0 +1,38 @@
+package mage.cards.m;
+
+import mage.MageInt;
+import mage.abilities.common.DrawSecondCardTriggeredAbility;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.game.permanent.token.RatToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class MadRatter extends CardImpl {
+
+ public MadRatter(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
+
+ this.subtype.add(SubType.GOBLIN);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(2);
+
+ // Whenever you draw your second card each turn, create two 1/1 black Rat creature tokens.
+ this.addAbility(new DrawSecondCardTriggeredAbility(new CreateTokenEffect(new RatToken(), 2), false));
+ }
+
+ private MadRatter(final MadRatter card) {
+ super(card);
+ }
+
+ @Override
+ public MadRatter copy() {
+ return new MadRatter(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MadScienceFairProject.java b/Mage.Sets/src/mage/cards/m/MadScienceFairProject.java
index 139d464fde0..871c231ed8c 100644
--- a/Mage.Sets/src/mage/cards/m/MadScienceFairProject.java
+++ b/Mage.Sets/src/mage/cards/m/MadScienceFairProject.java
@@ -29,7 +29,7 @@ public final class MadScienceFairProject extends CardImpl {
public MadScienceFairProject(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
- // {T}: Roll a six-sided die. On a 3 or lower, target player adds {C}. Otherwise, that player adds one mana of any color he or she chooses.
+ // {T}: Roll a six-sided die. On a 3 or lower, target player adds {C}. Otherwise, that player adds one mana of any color they choose.
this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new MadScienceFairManaEffect(), new TapSourceCost()));
}
@@ -47,7 +47,7 @@ class MadScienceFairManaEffect extends ManaEffect {
public MadScienceFairManaEffect() {
super();
- this.staticText = "Roll a six-sided die. On a 3 or lower, target player adds {C}. Otherwise, that player adds one mana of any color he or she chooses";
+ this.staticText = "Roll a six-sided die. On a 3 or lower, target player adds {C}. Otherwise, that player adds one mana of any color they choose";
}
public MadScienceFairManaEffect(final MadScienceFairManaEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/m/MaelstromArchangel.java b/Mage.Sets/src/mage/cards/m/MaelstromArchangel.java
index becbffcba6c..fe3106b78c2 100644
--- a/Mage.Sets/src/mage/cards/m/MaelstromArchangel.java
+++ b/Mage.Sets/src/mage/cards/m/MaelstromArchangel.java
@@ -1,4 +1,3 @@
-
package mage.cards.m;
import java.util.UUID;
@@ -90,7 +89,10 @@ class MaelstromArchangelCastEffect extends OneShotEffect {
}
}
if (cardToCast != null) {
- controller.cast(cardToCast.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + cardToCast.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(cardToCast, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + cardToCast.getId(), null);
}
}
return true;
diff --git a/Mage.Sets/src/mage/cards/m/MagebaneArmor.java b/Mage.Sets/src/mage/cards/m/MagebaneArmor.java
index 2f320ff8fcf..794fc2f3c4e 100644
--- a/Mage.Sets/src/mage/cards/m/MagebaneArmor.java
+++ b/Mage.Sets/src/mage/cards/m/MagebaneArmor.java
@@ -1,7 +1,5 @@
-
package mage.cards.m;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.StaticAbility;
import mage.abilities.common.SimpleStaticAbility;
@@ -13,25 +11,22 @@ import mage.abilities.keyword.EquipAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.AttachmentType;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.game.permanent.Permanent;
+import java.util.UUID;
+
/**
- *
* @author North
*/
public final class MagebaneArmor extends CardImpl {
public MagebaneArmor(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +2/+4 and loses flying.
@@ -99,7 +94,7 @@ class MagebaneArmorPreventionEffect extends PreventionEffectImpl {
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Permanent equipment = game.getPermanent(source.getSourceId());
if (equipment != null && equipment.getAttachedTo() != null) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, equipment.getAttachedTo(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(equipment.getAttachedTo(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
event.setAmount(0);
@@ -114,10 +109,8 @@ class MagebaneArmorPreventionEffect extends PreventionEffectImpl {
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game) && !((DamageEvent) event).isCombatDamage()) {
Permanent equipment = game.getPermanent(source.getSourceId());
- if (equipment != null && equipment.getAttachedTo() != null
- && event.getTargetId().equals(equipment.getAttachedTo())) {
- return true;
- }
+ return equipment != null && equipment.getAttachedTo() != null
+ && event.getTargetId().equals(equipment.getAttachedTo());
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/m/MagisterOfWorth.java b/Mage.Sets/src/mage/cards/m/MagisterOfWorth.java
index 4a0067ac5cf..436b85b0d54 100644
--- a/Mage.Sets/src/mage/cards/m/MagisterOfWorth.java
+++ b/Mage.Sets/src/mage/cards/m/MagisterOfWorth.java
@@ -1,4 +1,3 @@
-
package mage.cards.m;
import java.util.UUID;
@@ -13,11 +12,11 @@ import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.game.Game;
@@ -30,7 +29,7 @@ import mage.players.Player;
public final class MagisterOfWorth extends CardImpl {
public MagisterOfWorth(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{W}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{B}");
this.subtype.add(SubType.ANGEL);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
@@ -120,7 +119,7 @@ class MagisterOfWorthReturnFromGraveyardEffect extends OneShotEffect {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
- player.moveCards(player.getGraveyard().getCards(new FilterCreatureCard(), game), Zone.BATTLEFIELD, source, game);
+ player.moveCards(player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game), Zone.BATTLEFIELD, source, game);
}
}
return true;
diff --git a/Mage.Sets/src/mage/cards/m/MagneticMountain.java b/Mage.Sets/src/mage/cards/m/MagneticMountain.java
index 04cb129d096..b386dc1bcef 100644
--- a/Mage.Sets/src/mage/cards/m/MagneticMountain.java
+++ b/Mage.Sets/src/mage/cards/m/MagneticMountain.java
@@ -41,7 +41,7 @@ public final class MagneticMountain extends CardImpl {
// Blue creatures don't untap during their controllers' untap steps.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepAllEffect(Duration.WhileOnBattlefield, TargetController.ANY, filter)));
- // At the beginning of each player's upkeep, that player may choose any number of tapped blue creatures he or she controls and pay {4} for each creature chosen this way. If the player does, untap those creatures.
+ // At the beginning of each player's upkeep, that player may choose any number of tapped blue creatures they control and pay {4} for each creature chosen this way. If the player does, untap those creatures.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new MagneticMountainEffect(), TargetController.ANY, false));
}
@@ -66,7 +66,7 @@ class MagneticMountainEffect extends OneShotEffect {
MagneticMountainEffect() {
super(Outcome.Benefit);
- staticText = "that player may choose any number of tapped blue creatures he or she controls and pay {4} for each creature chosen this way. If the player does, untap those creatures.";
+ staticText = "that player may choose any number of tapped blue creatures they control and pay {4} for each creature chosen this way. If the player does, untap those creatures.";
}
MagneticMountainEffect(MagneticMountainEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/m/MagusOfTheArena.java b/Mage.Sets/src/mage/cards/m/MagusOfTheArena.java
index bcce6118b00..77ffc45fc38 100644
--- a/Mage.Sets/src/mage/cards/m/MagusOfTheArena.java
+++ b/Mage.Sets/src/mage/cards/m/MagusOfTheArena.java
@@ -35,7 +35,7 @@ public final class MagusOfTheArena extends CardImpl {
this.power = new MageInt(5);
this.toughness = new MageInt(5);
- // {3}, {tap}: Tap target creature you control and target creature of an opponent's choice he or she controls. Those creatures fight each other.
+ // {3}, {tap}: Tap target creature you control and target creature of an opponent's choice they control. Those creatures fight each other.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MagusOfTheArenaEffect(), new GenericManaCost(3));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetControlledCreaturePermanent());
@@ -57,7 +57,7 @@ class MagusOfTheArenaEffect extends OneShotEffect {
MagusOfTheArenaEffect() {
super(Outcome.Benefit);
- this.staticText = "Tap target creature you control and target creature of an opponent's choice he or she controls. Those creatures fight each other";
+ this.staticText = "Tap target creature you control and target creature of an opponent's choice they control. Those creatures fight each other";
}
MagusOfTheArenaEffect(final MagusOfTheArenaEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/m/MagusOfTheJar.java b/Mage.Sets/src/mage/cards/m/MagusOfTheJar.java
index 017e90b3862..d76c8f3526b 100644
--- a/Mage.Sets/src/mage/cards/m/MagusOfTheJar.java
+++ b/Mage.Sets/src/mage/cards/m/MagusOfTheJar.java
@@ -38,7 +38,7 @@ public final class MagusOfTheJar extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(3);
- // {tap}, Sacrifice Magus of the Jar: Each player exiles all cards from their hand face down and draws seven cards. At the beginning of the next end step, each player discards their hand and returns to their hand each card he or she exiled this way.
+ // {tap}, Sacrifice Magus of the Jar: Each player exiles all cards from their hand face down and draws seven cards. At the beginning of the next end step, each player discards their hand and returns to their hand each card they exiled this way.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MagusoftheJarEffect(), new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
this.addAbility(ability);
@@ -59,7 +59,7 @@ class MagusoftheJarEffect extends OneShotEffect {
public MagusoftheJarEffect() {
super(Outcome.DrawCard);
- staticText = "Each player exiles all cards from their hand face down and draws seven cards. At the beginning of the next end step, each player discards their hand and returns to their hand each card he or she exiled this way.";
+ staticText = "Each player exiles all cards from their hand face down and draws seven cards. At the beginning of the next end step, each player discards their hand and returns to their hand each card they exiled this way.";
}
public MagusoftheJarEffect(final MagusoftheJarEffect effect) {
@@ -108,7 +108,7 @@ class MagusoftheJarDelayedEffect extends OneShotEffect {
public MagusoftheJarDelayedEffect() {
super(Outcome.DrawCard);
- staticText = "At the beginning of the next end step, each player discards their hand and returns to their hand each card he or she exiled this way";
+ staticText = "At the beginning of the next end step, each player discards their hand and returns to their hand each card they exiled this way";
}
public MagusoftheJarDelayedEffect(final MagusoftheJarDelayedEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/m/MalevolentNoble.java b/Mage.Sets/src/mage/cards/m/MalevolentNoble.java
new file mode 100644
index 00000000000..4c7f6ff3bf4
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MalevolentNoble.java
@@ -0,0 +1,73 @@
+package mage.cards.m;
+
+import mage.MageInt;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.costs.mana.GenericManaCost;
+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.common.FilterControlledPermanent;
+import mage.filter.predicate.ObjectSourcePlayer;
+import mage.filter.predicate.ObjectSourcePlayerPredicate;
+import mage.game.Game;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class MalevolentNoble extends CardImpl {
+
+ private static final FilterControlledPermanent filter
+ = new FilterControlledPermanent("an artifact or another creature");
+
+ static {
+ filter.add(MalevolentNoblePredicate.instance);
+ }
+
+ public MalevolentNoble(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.NOBLE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // {2}, Sacrifice an artifact or another creature: Put a +1/+1 counter on Malevolent Noble.
+ Ability ability = new SimpleActivatedAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new GenericManaCost(2)
+ );
+ ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter)));
+ this.addAbility(ability);
+ }
+
+ private MalevolentNoble(final MalevolentNoble card) {
+ super(card);
+ }
+
+ @Override
+ public MalevolentNoble copy() {
+ return new MalevolentNoble(this);
+ }
+}
+
+enum MalevolentNoblePredicate implements ObjectSourcePlayerPredicate> {
+ instance;
+
+ @Override
+ public boolean apply(ObjectSourcePlayer input, Game game) {
+ MageObject obj = input.getObject();
+ if (obj.getId().equals(input.getSourceId())) {
+ return obj.isArtifact();
+ }
+ return obj.isArtifact()
+ || obj.isCreature();
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MalignantGrowth.java b/Mage.Sets/src/mage/cards/m/MalignantGrowth.java
index 85edc354d69..3256638b3b9 100644
--- a/Mage.Sets/src/mage/cards/m/MalignantGrowth.java
+++ b/Mage.Sets/src/mage/cards/m/MalignantGrowth.java
@@ -36,7 +36,7 @@ public final class MalignantGrowth extends CardImpl {
TargetController.YOU, false
));
- // At the beginning of each opponent's draw step, that player draws an additional card for each growth counter on Malignant Growth, then Malignant Growth deals damage to the player equal to the number of cards he or she drew this way.
+ // At the beginning of each opponent's draw step, that player draws an additional card for each growth counter on Malignant Growth, then Malignant Growth deals damage to the player equal to the number of cards they drew this way.
this.addAbility(new BeginningOfDrawTriggeredAbility(
new MalignantGrowthEffect(), TargetController.OPPONENT, false
));
diff --git a/Mage.Sets/src/mage/cards/m/ManaBreach.java b/Mage.Sets/src/mage/cards/m/ManaBreach.java
index 7c882bbb75b..af49af7e04b 100644
--- a/Mage.Sets/src/mage/cards/m/ManaBreach.java
+++ b/Mage.Sets/src/mage/cards/m/ManaBreach.java
@@ -29,7 +29,7 @@ public final class ManaBreach extends CardImpl {
public ManaBreach(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}");
- // Whenever a player casts a spell, that player returns a land he or she controls to its owner's hand.
+ // Whenever a player casts a spell, that player returns a land they control to its owner's hand.
this.addAbility(new SpellCastAllTriggeredAbility(new ManaBreachEffect(), StaticFilters.FILTER_SPELL, false, SetTargetPointer.PLAYER));
}
@@ -47,7 +47,7 @@ class ManaBreachEffect extends OneShotEffect {
public ManaBreachEffect() {
super(Outcome.Detriment);
- staticText="that player returns a land he or she controls to its owner's hand.";
+ staticText="that player returns a land they control to its owner's hand.";
}
public boolean apply(Game game, Ability source) {
diff --git a/Mage.Sets/src/mage/cards/m/MandateOfPeace.java b/Mage.Sets/src/mage/cards/m/MandateOfPeace.java
new file mode 100644
index 00000000000..06c0f637341
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MandateOfPeace.java
@@ -0,0 +1,129 @@
+package mage.cards.m;
+
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Stream;
+
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility;
+import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.TurnPhase;
+import mage.game.Game;
+import mage.game.combat.Combat;
+import mage.game.events.GameEvent;
+import mage.game.stack.Spell;
+
+/**
+ *
+ * @author goesta
+ */
+public final class MandateOfPeace extends CardImpl {
+
+ public MandateOfPeace(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");
+ // Cast this spell only during combat.
+ this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(TurnPhase.COMBAT));
+ // Your opponents can't cast spells this turn.
+ this.getSpellAbility().addEffect(new MandateOfPeaceOpponentsCantCastSpellsEffect());
+ // End the combat phase.
+ this.getSpellAbility().addEffect(new MandateOfPeaceEndCombatEffect());
+ }
+
+ private MandateOfPeace(final MandateOfPeace card) {
+ super(card);
+ }
+
+ @Override
+ public MandateOfPeace copy() {
+ return new MandateOfPeace(this);
+ }
+}
+
+class MandateOfPeaceOpponentsCantCastSpellsEffect extends ContinuousRuleModifyingEffectImpl {
+
+ public MandateOfPeaceOpponentsCantCastSpellsEffect() {
+ super(Duration.EndOfTurn, Outcome.Benefit);
+ staticText = "Your opponents can't cast spells this turn.";
+ }
+
+ public MandateOfPeaceOpponentsCantCastSpellsEffect(final MandateOfPeaceOpponentsCantCastSpellsEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public MandateOfPeaceOpponentsCantCastSpellsEffect copy() {
+ return new MandateOfPeaceOpponentsCantCastSpellsEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public String getInfoMessage(Ability source, GameEvent event, Game game) {
+ MageObject mageObject = game.getObject(source.getSourceId());
+ if (mageObject != null) {
+ return "You can't cast spells this turn (" + mageObject.getIdName() + ").";
+ }
+ return null;
+ }
+
+ @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) {
+ return game.getOpponents(source.getControllerId()).contains(event.getPlayerId());
+ }
+
+}
+
+class MandateOfPeaceEndCombatEffect extends OneShotEffect {
+
+ public MandateOfPeaceEndCombatEffect() {
+ super(Outcome.Benefit);
+ this.staticText = "End the combat phase. (Remove all attackers and blockers from combat. Exile all spells and abilities from the stack, including this spell.)";
+ }
+
+ public MandateOfPeaceEndCombatEffect(OneShotEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Combat combat = game.getCombat();
+ List attackerIds = combat.getAttackers();
+ List blockerIds = combat.getBlockers();
+ Stream.concat(blockerIds.stream(), attackerIds.stream())
+ .map(id -> game.getPermanent(id))
+ .filter(e -> e != null)
+ .forEach(permanent -> permanent.removeFromCombat(game));
+
+ game.getStack().stream()
+ .filter(stackObject -> stackObject instanceof Spell)
+ .forEach(stackObject -> ((Spell) stackObject).moveToExile(null, "", null, game));
+
+ game.getStack().stream()
+ .filter(stackObject -> stackObject instanceof Ability)
+ .forEach(stackObject -> game.getStack().counter(stackObject.getId(), source.getSourceId(), game));
+
+ combat.endCombat(game);
+ return true;
+ }
+
+ @Override
+ public Effect copy() {
+ return new MandateOfPeaceEndCombatEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MantleOfTides.java b/Mage.Sets/src/mage/cards/m/MantleOfTides.java
new file mode 100644
index 00000000000..efde9dae20c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MantleOfTides.java
@@ -0,0 +1,50 @@
+package mage.cards.m;
+
+import mage.abilities.Ability;
+import mage.abilities.common.DrawSecondCardTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.continuous.BoostEquippedEffect;
+import mage.abilities.keyword.EquipAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.target.common.TargetControlledCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class MantleOfTides extends CardImpl {
+
+ public MantleOfTides(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{U}");
+
+ this.subtype.add(SubType.EQUIPMENT);
+
+ // Equipped creature gets +1/+2.
+ this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(1, 2)));
+
+ // Whenever you draw your second card each turn, attach Mantle of Tides to target creature you control.
+ Ability ability = new DrawSecondCardTriggeredAbility(new AttachEffect(
+ Outcome.Benefit, "attach {this} to target creature you control"
+ ), false);
+ ability.addTarget(new TargetControlledCreaturePermanent());
+ this.addAbility(ability);
+
+ // Equip {3}
+ this.addAbility(new EquipAbility(3));
+ }
+
+ private MantleOfTides(final MantleOfTides card) {
+ super(card);
+ }
+
+ @Override
+ public MantleOfTides copy() {
+ return new MantleOfTides(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MaraleafPixie.java b/Mage.Sets/src/mage/cards/m/MaraleafPixie.java
new file mode 100644
index 00000000000..a18a32fa7a2
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MaraleafPixie.java
@@ -0,0 +1,42 @@
+package mage.cards.m;
+
+import mage.MageInt;
+import mage.abilities.keyword.FlyingAbility;
+import mage.abilities.mana.BlueManaAbility;
+import mage.abilities.mana.GreenManaAbility;
+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 MaraleafPixie extends CardImpl {
+
+ public MaraleafPixie(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{U}");
+
+ this.subtype.add(SubType.FAERIE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // {T}: Add {G} or {U}.
+ this.addAbility(new GreenManaAbility());
+ this.addAbility(new BlueManaAbility());
+ }
+
+ private MaraleafPixie(final MaraleafPixie card) {
+ super(card);
+ }
+
+ @Override
+ public MaraleafPixie copy() {
+ return new MaraleafPixie(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MaraleafRider.java b/Mage.Sets/src/mage/cards/m/MaraleafRider.java
new file mode 100644
index 00000000000..25f1baba2bf
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MaraleafRider.java
@@ -0,0 +1,49 @@
+package mage.cards.m;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.effects.common.combat.MustBeBlockedByTargetSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.common.FilterControlledPermanent;
+import mage.target.common.TargetControlledPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class MaraleafRider extends CardImpl {
+
+ private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.FOOD, "a Food");
+
+ public MaraleafRider(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
+
+ this.subtype.add(SubType.ELF);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(1);
+
+ // Sacrifice a Food: Target creature blocks Maraleaf Rider this turn if able.
+ Ability ability = new SimpleActivatedAbility(
+ new MustBeBlockedByTargetSourceEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter))
+ );
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+ }
+
+ private MaraleafRider(final MaraleafRider card) {
+ super(card);
+ }
+
+ @Override
+ public MaraleafRider copy() {
+ return new MaraleafRider(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MarshmistTitan.java b/Mage.Sets/src/mage/cards/m/MarshmistTitan.java
index e932459f67b..71df001f009 100644
--- a/Mage.Sets/src/mage/cards/m/MarshmistTitan.java
+++ b/Mage.Sets/src/mage/cards/m/MarshmistTitan.java
@@ -1,7 +1,5 @@
-
package mage.cards.m;
-import java.util.UUID;
import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability;
@@ -11,33 +9,29 @@ import mage.abilities.dynamicvalue.common.DevotionCount;
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.ColoredManaSymbol;
-import mage.constants.CostModificationType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.game.Game;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class MarshmistTitan extends CardImpl {
public MarshmistTitan(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{6}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{B}");
this.subtype.add(SubType.GIANT);
this.power = new MageInt(4);
this.toughness = new MageInt(5);
// Marshmist Titan costs {X} less to cast, where X is your devotion to black.
- this.addAbility(new SimpleStaticAbility(Zone.STACK, new MarshmistTitanCostReductionEffect()));
+ this.addAbility(new SimpleStaticAbility(Zone.STACK, new MarshmistTitanCostReductionEffect())
+ .addHint(DevotionCount.B.getHint()));
}
- public MarshmistTitan(final MarshmistTitan card) {
+ private MarshmistTitan(final MarshmistTitan card) {
super(card);
}
@@ -49,38 +43,33 @@ public final class MarshmistTitan extends CardImpl {
class MarshmistTitanCostReductionEffect extends CostModificationEffectImpl {
- public MarshmistTitanCostReductionEffect() {
+ MarshmistTitanCostReductionEffect() {
super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST);
- staticText = "{this} costs {X} less to cast, where X is your devotion to black (Each {B} in the mana costs of permanents you control counts toward your devotion to black.) ";
+ staticText = "This spell costs {X} less to cast, where X is your devotion to black. " +
+ "(Each {B} in the mana costs of permanents you control counts toward your devotion to black.) ";
}
- public MarshmistTitanCostReductionEffect(final MarshmistTitanCostReductionEffect effect) {
+ private MarshmistTitanCostReductionEffect(final MarshmistTitanCostReductionEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
- SpellAbility spellAbility = (SpellAbility)abilityToModify;
+ SpellAbility spellAbility = (SpellAbility) abilityToModify;
Mana mana = spellAbility.getManaCostsToPay().getMana();
- if (mana.getGeneric() > 0) {
- int count = new DevotionCount(ColoredManaSymbol.B).calculate(game, source, this);
- int newCount = mana.getGeneric() - count;
- if (newCount < 0) {
- newCount = 0;
- }
- mana.setGeneric(newCount);
- spellAbility.getManaCostsToPay().load(mana.toString());
- return true;
+ if (mana.getGeneric() == 0) {
+ return false;
}
- return false;
+ int count = DevotionCount.B.calculate(game, source, this);
+ mana.setGeneric(Math.max(mana.getGeneric() - count, 0));
+ spellAbility.getManaCostsToPay().load(mana.toString());
+ return true;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
- if (abilityToModify.getSourceId().equals(source.getSourceId()) && (abilityToModify instanceof SpellAbility)) {
- return true;
- }
- return false;
+ return abilityToModify instanceof SpellAbility
+ && abilityToModify.getSourceId().equals(source.getSourceId());
}
@Override
diff --git a/Mage.Sets/src/mage/cards/m/MaskOfIntolerance.java b/Mage.Sets/src/mage/cards/m/MaskOfIntolerance.java
index beeb2fc7838..82d2a799904 100644
--- a/Mage.Sets/src/mage/cards/m/MaskOfIntolerance.java
+++ b/Mage.Sets/src/mage/cards/m/MaskOfIntolerance.java
@@ -26,10 +26,10 @@ public final class MaskOfIntolerance extends CardImpl {
public MaskOfIntolerance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
- // At the beginning of each player's upkeep, if there are four or more basic land types among lands that player controls, Mask of Intolerance deals 3 damage to him or her.
+ // At the beginning of each player's upkeep, if there are four or more basic land types among lands that player controls, Mask of Intolerance deals 3 damage to that player.
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3), TargetController.ANY, false);
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new MaskOfIntoleranceCondition(),
- "At the beginning of each player's upkeep, if there are four or more basic land types among lands that player controls, {this} deals 3 damage to him or her."));
+ "At the beginning of each player's upkeep, if there are four or more basic land types among lands that player controls, {this} deals 3 damage to that player."));
}
public MaskOfIntolerance(final MaskOfIntolerance card) {
diff --git a/Mage.Sets/src/mage/cards/m/MasterOfPredicaments.java b/Mage.Sets/src/mage/cards/m/MasterOfPredicaments.java
index b8a47edfc72..8387d6309ee 100644
--- a/Mage.Sets/src/mage/cards/m/MasterOfPredicaments.java
+++ b/Mage.Sets/src/mage/cards/m/MasterOfPredicaments.java
@@ -1,4 +1,3 @@
-
package mage.cards.m;
import java.util.UUID;
@@ -35,8 +34,12 @@ public final class MasterOfPredicaments extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
- // Whenever Master of Predicaments deals combat damage to a player, choose a card in your hand. That player guesses whether the card's converted mana cost is greater than 4. If the player guessed wrong, you may cast the card without paying its mana cost.
- this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new MasterOfPredicamentsEffect(), false, true));
+ // Whenever Master of Predicaments deals combat damage to a player,
+ // choose a card in your hand. That player guesses whether the card's
+ // converted mana cost is greater than 4. If the player guessed wrong,
+ // you may cast the card without paying its mana cost.
+ this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(
+ new MasterOfPredicamentsEffect(), false, true));
}
public MasterOfPredicaments(final MasterOfPredicaments card) {
@@ -52,8 +55,10 @@ public final class MasterOfPredicaments extends CardImpl {
class MasterOfPredicamentsEffect extends OneShotEffect {
public MasterOfPredicamentsEffect() {
- super(Outcome.PutCardInPlay);
- this.staticText = "choose a card in your hand. That player guesses whether the card's converted mana cost is greater than 4. If the player guessed wrong, you may cast the card without paying its mana cost";
+ super(Outcome.PlayForFree);
+ this.staticText = "choose a card in your hand. That player guesses whether "
+ + "the card's converted mana cost is greater than 4. If the player "
+ + "guessed wrong, you may cast the card without paying its mana cost";
}
public MasterOfPredicamentsEffect(final MasterOfPredicamentsEffect effect) {
@@ -73,7 +78,7 @@ class MasterOfPredicamentsEffect extends OneShotEffect {
Card cardFromHand = null;
if (controller.getHand().size() > 1) {
TargetCard target = new TargetCardInHand(new FilterCard());
- if (controller.choose(outcome, controller.getHand(), target, game)) {
+ if (controller.choose(Outcome.PlayForFree, controller.getHand(), target, game)) {
cardFromHand = game.getCard(target.getFirstTarget());
}
} else {
@@ -87,11 +92,14 @@ class MasterOfPredicamentsEffect extends OneShotEffect {
return false;
}
boolean guessWrong;
- if (attackedPlayer.chooseUse(Outcome.Detriment, "Is the chosen card's converted mana cost greater than 4?", source, game)) {
- game.informPlayers(attackedPlayer.getLogName() + " guessed that the chosen card's converted mana cost is greater than 4");
+ if (attackedPlayer.chooseUse(Outcome.Detriment, "Is the chosen card's converted "
+ + "mana cost greater than 4?", source, game)) {
+ game.informPlayers(attackedPlayer.getLogName() + " guessed that the chosen "
+ + "card's converted mana cost is greater than 4");
guessWrong = cardFromHand.getConvertedManaCost() <= 4;
} else {
- game.informPlayers(attackedPlayer.getLogName() + " guessed that the chosen card's converted mana cost is not greater than 4");
+ game.informPlayers(attackedPlayer.getLogName() + " guessed that the chosen "
+ + "card's converted mana cost is not greater than 4");
guessWrong = cardFromHand.getConvertedManaCost() > 4;
}
game.informPlayers(attackedPlayer.getLogName() + " guessed " + (guessWrong ? "wrong" : "right"));
@@ -99,8 +107,12 @@ class MasterOfPredicamentsEffect extends OneShotEffect {
if (cardFromHand.isLand()) {
// If the revealed card is a land, you can't cast it. So nothing happens
} else {
- if (controller.chooseUse(outcome, "Cast " + cardFromHand.getName() + " without paying its mana cost?", source, game)) {
- controller.cast(cardFromHand.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ if (controller.chooseUse(outcome, "Cast " + cardFromHand.getName()
+ + " without paying its mana cost?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + cardFromHand.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(cardFromHand, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + cardFromHand.getId(), null);
}
}
diff --git a/Mage.Sets/src/mage/cards/m/MasterOfWaves.java b/Mage.Sets/src/mage/cards/m/MasterOfWaves.java
index ba24cada0a5..b936b77b902 100644
--- a/Mage.Sets/src/mage/cards/m/MasterOfWaves.java
+++ b/Mage.Sets/src/mage/cards/m/MasterOfWaves.java
@@ -1,7 +1,5 @@
-
package mage.cards.m;
-import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -13,24 +11,24 @@ import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
import mage.filter.common.FilterCreaturePermanent;
-import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.permanent.token.MasterOfWavesElementalToken;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class MasterOfWaves extends CardImpl {
- private static final FilterCreaturePermanent filterBoost = new FilterCreaturePermanent("Elemental creatures");
- static {
- filterBoost.add(new SubtypePredicate(SubType.ELEMENTAL));
- }
+ private static final FilterCreaturePermanent filterBoost
+ = new FilterCreaturePermanent(SubType.ELEMENTAL, "Elemental creatures");
public MasterOfWaves(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
this.subtype.add(SubType.MERFOLK);
this.subtype.add(SubType.WIZARD);
@@ -39,14 +37,17 @@ public final class MasterOfWaves extends CardImpl {
// Protection from red
this.addAbility(ProtectionAbility.from(ObjectColor.RED));
+
// Elemental creatures you control get +1/+1.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filterBoost, false)));
+ this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(
+ 1, 1, Duration.WhileOnBattlefield, filterBoost, false
+ )));
+
// When Master of Waves enters the battlefield, create a number of 1/0 blue Elemental creature tokens equal to your devotion to blue.
// (Each {U} in the mana costs of permanents you control counts toward your devotion to blue.)
- Effect effect = new CreateTokenEffect(new MasterOfWavesElementalToken(), new DevotionCount(ColoredManaSymbol.U));
+ Effect effect = new CreateTokenEffect(new MasterOfWavesElementalToken(), DevotionCount.U);
effect.setText("create a number of 1/0 blue Elemental creature tokens equal to your devotion to blue. (Each {U} in the mana costs of permanents you control counts toward your devotion to blue.)");
- this.addAbility(new EntersBattlefieldTriggeredAbility(effect));
-
+ this.addAbility(new EntersBattlefieldTriggeredAbility(effect).addHint(DevotionCount.U.getHint()));
}
public MasterOfWaves(final MasterOfWaves card) {
diff --git a/Mage.Sets/src/mage/cards/m/MemoryDrain.java b/Mage.Sets/src/mage/cards/m/MemoryDrain.java
new file mode 100644
index 00000000000..de489955b6e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MemoryDrain.java
@@ -0,0 +1,35 @@
+package mage.cards.m;
+
+import mage.abilities.effects.common.CounterTargetEffect;
+import mage.abilities.effects.keyword.ScryEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.target.TargetSpell;
+
+import java.util.UUID;
+
+/**
+ * @author jmharmon
+ */
+
+public final class MemoryDrain extends CardImpl {
+
+ public MemoryDrain(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{U}");
+
+ // Counter target spell. Scry 2.
+ this.getSpellAbility().addEffect(new CounterTargetEffect());
+ this.getSpellAbility().addTarget(new TargetSpell());
+ this.getSpellAbility().addEffect(new ScryEffect(2));
+ }
+
+ public MemoryDrain(final MemoryDrain card) {
+ super(card);
+ }
+
+ @Override
+ public MemoryDrain copy() {
+ return new MemoryDrain(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MemoryJar.java b/Mage.Sets/src/mage/cards/m/MemoryJar.java
index ba0be0711a0..c9937c675b2 100644
--- a/Mage.Sets/src/mage/cards/m/MemoryJar.java
+++ b/Mage.Sets/src/mage/cards/m/MemoryJar.java
@@ -34,7 +34,7 @@ public final class MemoryJar extends CardImpl {
// {T}, Sacrifice Memory Jar: Each player exiles all cards from their hand face down and draws seven cards.
// At the beginning of the next end step, each player discards their hand and returns to their hand each
- //card he or she exiled this way.
+ //card they exiled this way.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MemoryJarEffect(), new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
this.addAbility(ability);
@@ -55,7 +55,7 @@ class MemoryJarEffect extends OneShotEffect {
public MemoryJarEffect() {
super(Outcome.DrawCard);
- staticText = "Each player exiles all cards from their hand face down and draws seven cards. At the beginning of the next end step, each player discards their hand and returns to their hand each card he or she exiled this way.";
+ staticText = "Each player exiles all cards from their hand face down and draws seven cards. At the beginning of the next end step, each player discards their hand and returns to their hand each card they exiled this way.";
}
public MemoryJarEffect(final MemoryJarEffect effect) {
@@ -104,7 +104,7 @@ class MemoryJarDelayedEffect extends OneShotEffect {
public MemoryJarDelayedEffect() {
super(Outcome.DrawCard);
- staticText = "At the beginning of the next end step, each player discards their hand and returns to their hand each card he or she exiled this way";
+ staticText = "At the beginning of the next end step, each player discards their hand and returns to their hand each card they exiled this way";
}
public MemoryJarDelayedEffect(final MemoryJarDelayedEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/m/MemoryTheft.java b/Mage.Sets/src/mage/cards/m/MemoryTheft.java
new file mode 100644
index 00000000000..e302ecfeef9
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MemoryTheft.java
@@ -0,0 +1,87 @@
+package mage.cards.m;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+import mage.filter.FilterCard;
+import mage.filter.StaticFilters;
+import mage.filter.predicate.mageobject.AdventurePredicate;
+import mage.filter.predicate.other.OwnerIdPredicate;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.TargetCard;
+import mage.target.common.TargetCardInExile;
+import mage.target.common.TargetOpponent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class MemoryTheft extends CardImpl {
+
+ public MemoryTheft(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}");
+
+ // Target opponent reveals their hand. You choose a nonland card from it. That player discards that card. You may put a card that has an Adventure that player owns from exile into that player's graveyard.
+ this.getSpellAbility().addEffect(
+ new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_NON_LAND, TargetController.ANY)
+ );
+ this.getSpellAbility().addEffect(new MemoryTheftEffect());
+ this.getSpellAbility().addTarget(new TargetOpponent());
+ }
+
+ private MemoryTheft(final MemoryTheft card) {
+ super(card);
+ }
+
+ @Override
+ public MemoryTheft copy() {
+ return new MemoryTheft(this);
+ }
+}
+
+class MemoryTheftEffect extends OneShotEffect {
+
+ MemoryTheftEffect() {
+ super(Outcome.Benefit);
+ staticText = "Target opponent reveals their hand. You choose a nonland card from it. " +
+ "That player discards that card. You may put a card that has an Adventure " +
+ "that player owns from exile into that player's graveyard.";
+ }
+
+ private MemoryTheftEffect(final MemoryTheftEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public MemoryTheftEffect copy() {
+ return new MemoryTheftEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Player player = game.getPlayer(source.getFirstTarget());
+ if (controller == null || player == null) {
+ return false;
+ }
+ FilterCard filter = new FilterCard("card owned by " + player.getName() + " that has an Adventure");
+ filter.add(AdventurePredicate.instance);
+ filter.add(new OwnerIdPredicate(player.getId()));
+ TargetCard target = new TargetCardInExile(0, 1, filter, null, true);
+ if (!target.canChoose(source.getSourceId(), source.getControllerId(), game)
+ || !controller.choose(outcome, target, source.getSourceId(), game)) {
+ return false;
+ }
+ Card card = game.getCard(target.getFirstTarget());
+ return controller.moveCards(card, Zone.GRAVEYARD, source, game);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/m/MerchantOfTheVale.java b/Mage.Sets/src/mage/cards/m/MerchantOfTheVale.java
new file mode 100644
index 00000000000..be27716805d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MerchantOfTheVale.java
@@ -0,0 +1,52 @@
+package mage.cards.m;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.DiscardCardCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DoIfCostPaid;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class MerchantOfTheVale extends AdventureCard {
+
+ public MerchantOfTheVale(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.INSTANT}, "{2}{R}", "Haggle", "{R}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.PEASANT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // {2}{R}, Discard a card: Draw a card.
+ Ability ability = new SimpleActivatedAbility(
+ new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{2}{R}")
+ );
+ ability.addCost(new DiscardCardCost());
+ this.addAbility(ability);
+
+ // Haggle
+ // You may discard a card. If you do, draw a card.
+ this.getSpellCard().getSpellAbility().addEffect(new DoIfCostPaid(
+ new DrawCardSourceControllerEffect(1), new DiscardCardCost()
+ ));
+ }
+
+ private MerchantOfTheVale(final MerchantOfTheVale card) {
+ super(card);
+ }
+
+ @Override
+ public MerchantOfTheVale copy() {
+ return new MerchantOfTheVale(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MerfolkSecretkeeper.java b/Mage.Sets/src/mage/cards/m/MerfolkSecretkeeper.java
new file mode 100644
index 00000000000..291c438190b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MerfolkSecretkeeper.java
@@ -0,0 +1,40 @@
+package mage.cards.m;
+
+import mage.MageInt;
+import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.target.TargetPlayer;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class MerfolkSecretkeeper extends AdventureCard {
+
+ public MerfolkSecretkeeper(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{U}", "Venture Deeper", "{U}");
+
+ this.subtype.add(SubType.MERFOLK);
+ this.subtype.add(SubType.WIZARD);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(4);
+
+ // Venture Deeper
+ // Target player puts the top four cards of their library into their graveyard.
+ this.getSpellCard().getSpellAbility().addEffect(new PutLibraryIntoGraveTargetEffect(4));
+ this.getSpellCard().getSpellAbility().addTarget(new TargetPlayer());
+ }
+
+ private MerfolkSecretkeeper(final MerfolkSecretkeeper card) {
+ super(card);
+ }
+
+ @Override
+ public MerfolkSecretkeeper copy() {
+ return new MerfolkSecretkeeper(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MerfolkSovereign.java b/Mage.Sets/src/mage/cards/m/MerfolkSovereign.java
index f2637dd00de..c39b6fbaaf8 100644
--- a/Mage.Sets/src/mage/cards/m/MerfolkSovereign.java
+++ b/Mage.Sets/src/mage/cards/m/MerfolkSovereign.java
@@ -1,8 +1,5 @@
-
-
package mage.cards.m;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -20,8 +17,9 @@ import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author BetaSteward_at_googlemail.com
*/
public final class MerfolkSovereign extends CardImpl {
@@ -35,8 +33,8 @@ public final class MerfolkSovereign extends CardImpl {
}
public MerfolkSovereign(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}{U}");
- this.subtype.add(SubType.MERFOLK);
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}");
+ this.subtype.add(SubType.MERFOLK, SubType.NOBLE);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
diff --git a/Mage.Sets/src/mage/cards/m/Merseine.java b/Mage.Sets/src/mage/cards/m/Merseine.java
index cec4a052dce..9cec6b16355 100644
--- a/Mage.Sets/src/mage/cards/m/Merseine.java
+++ b/Mage.Sets/src/mage/cards/m/Merseine.java
@@ -51,7 +51,7 @@ public final class Merseine extends CardImpl {
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepEnchantedEffect(),
new SourceHasCounterCondition(CounterType.NET)).setText("Enchanted creature doesn't untap during its controller's untap step if Merseine has a net counter on it")));
- // Pay enchanted creature's mana cost: Remove a net counter from Merseine. Any player may activate this ability, but only if he or she controls the enchanted creature.
+ // Pay enchanted creature's mana cost: Remove a net counter from Merseine. Any player may activate this ability, but only if they control the enchanted creature.
SimpleActivatedAbility ability = new MerseineActivatedAbility();
ability.setMayActivate(TargetController.ANY);
this.addAbility(ability);
@@ -96,7 +96,7 @@ class MerseineActivatedAbility extends SimpleActivatedAbility {
@Override
public String getRule() {
- return "Pay enchanted creature's mana cost: Remove a net counter from Merseine. Any player may activate this ability, but only if he or she controls the enchanted creature.";
+ return "Pay enchanted creature's mana cost: Remove a net counter from Merseine. Any player may activate this ability, but only if they control the enchanted creature.";
}
}
diff --git a/Mage.Sets/src/mage/cards/m/MesmericFiend.java b/Mage.Sets/src/mage/cards/m/MesmericFiend.java
index 73631029031..2735f2d5b1b 100644
--- a/Mage.Sets/src/mage/cards/m/MesmericFiend.java
+++ b/Mage.Sets/src/mage/cards/m/MesmericFiend.java
@@ -28,12 +28,12 @@ import mage.util.CardUtil;
* @author LevelX2
*/
public final class MesmericFiend extends CardImpl {
-
+
public MesmericFiend(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.subtype.add(SubType.NIGHTMARE);
this.subtype.add(SubType.HORROR);
-
+
this.power = new MageInt(1);
this.toughness = new MageInt(1);
@@ -45,11 +45,11 @@ public final class MesmericFiend extends CardImpl {
// When Mesmeric Fiend leaves the battlefield, return the exiled card to its owner's hand.
this.addAbility(new LeavesBattlefieldTriggeredAbility(new MesmericFiendLeaveEffect(), false));
}
-
+
public MesmericFiend(final MesmericFiend card) {
super(card);
}
-
+
@Override
public MesmericFiend copy() {
return new MesmericFiend(this);
@@ -57,26 +57,26 @@ public final class MesmericFiend extends CardImpl {
}
class MesmericFiendExileEffect extends OneShotEffect {
-
+
public MesmericFiendExileEffect() {
super(Outcome.Exile);
this.staticText = "target opponent reveals their hand and you choose a nonland card from it. Exile that card";
}
-
+
public MesmericFiendExileEffect(final MesmericFiendExileEffect effect) {
super(effect);
}
-
+
@Override
public MesmericFiendExileEffect copy() {
return new MesmericFiendExileEffect(this);
}
-
+
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player opponent = game.getPlayer(source.getFirstTarget());
- Permanent sourcePermanent = (Permanent) source.getSourceObject(game);
+ Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (controller != null
&& opponent != null
&& sourcePermanent != null) {
@@ -97,21 +97,21 @@ class MesmericFiendExileEffect extends OneShotEffect {
}
class MesmericFiendLeaveEffect extends OneShotEffect {
-
+
public MesmericFiendLeaveEffect() {
super(Outcome.ReturnToHand);
this.staticText = "return the exiled card to its owner's hand";
}
-
+
public MesmericFiendLeaveEffect(final MesmericFiendLeaveEffect effect) {
super(effect);
}
-
+
@Override
public MesmericFiendLeaveEffect copy() {
return new MesmericFiendLeaveEffect(this);
}
-
+
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
diff --git a/Mage.Sets/src/mage/cards/m/MesmericSliver.java b/Mage.Sets/src/mage/cards/m/MesmericSliver.java
index 492d6bfbba8..1933f66e3d6 100644
--- a/Mage.Sets/src/mage/cards/m/MesmericSliver.java
+++ b/Mage.Sets/src/mage/cards/m/MesmericSliver.java
@@ -40,7 +40,7 @@ public final class MesmericSliver extends CardImpl {
Ability ability = new EntersBattlefieldTriggeredAbility(new FatesealEffect(1), true);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new GainAbilityAllEffect(ability, Duration.WhileOnBattlefield,
- filterSliver, "All Slivers have \"When this permanent enters the battlefield, you may fateseal 1.\" (To fateseal 1, its controller looks at the top card of an opponent's library, then he or she may put that card on the bottom of that library.)")));
+ filterSliver, "All Slivers have \"When this permanent enters the battlefield, you may fateseal 1.\" (To fateseal 1, its controller looks at the top card of an opponent's library, then they may put that card on the bottom of that library.)")));
}
public MesmericSliver(final MesmericSliver card) {
diff --git a/Mage.Sets/src/mage/cards/m/MidnightClock.java b/Mage.Sets/src/mage/cards/m/MidnightClock.java
new file mode 100644
index 00000000000..5b798709302
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MidnightClock.java
@@ -0,0 +1,141 @@
+package mage.cards.m;
+
+import mage.abilities.Ability;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.ExileSourceEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.mana.BlueManaAbility;
+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.TargetController;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class MidnightClock extends CardImpl {
+
+ public MidnightClock(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{U}");
+
+ // {T}: Add {U}.
+ this.addAbility(new BlueManaAbility());
+
+ // {2}{U}: Put an hour counter on Midnight Clock.
+ this.addAbility(new SimpleActivatedAbility(
+ new AddCountersSourceEffect(CounterType.HOUR.createInstance()), new ManaCostsImpl("{2}{U}")
+ ));
+
+ // At the beginning of each upkeep, put an hour counter on Midnight Clock.
+ this.addAbility(new BeginningOfUpkeepTriggeredAbility(
+ new AddCountersSourceEffect(CounterType.HOUR.createInstance()), TargetController.ANY, false
+ ));
+
+ // When the twelfth hour counter is put on Midnight Clock, shuffle your hand and graveyard into your library, then draw seven cards. Exile Midnight Clock.
+ this.addAbility(new MidnightClockTriggeredAbility());
+ }
+
+ private MidnightClock(final MidnightClock card) {
+ super(card);
+ }
+
+ @Override
+ public MidnightClock copy() {
+ return new MidnightClock(this);
+ }
+}
+
+class MidnightClockTriggeredAbility extends TriggeredAbilityImpl {
+
+ MidnightClockTriggeredAbility() {
+ super(Zone.ALL, new MidnightClockEffect(), false);
+ }
+
+ private MidnightClockTriggeredAbility(final MidnightClockTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.COUNTER_ADDED;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ if (event.getTargetId().equals(getSourceId())
+ && event.getData().equals(CounterType.HOUR.getName())) {
+ int amountAdded = event.getAmount();
+ int hourCounters = amountAdded;
+ Permanent sourcePermanent = game.getPermanent(getSourceId());
+ if (sourcePermanent == null) {
+ sourcePermanent = game.getPermanentEntering(getSourceId());
+ }
+ if (sourcePermanent != null) {
+ hourCounters = sourcePermanent.getCounters(game).getCount(CounterType.HOUR);
+ }
+ return hourCounters - amountAdded < 12
+ && 12 <= hourCounters;
+ }
+ return false;
+ }
+
+ @Override
+ public MidnightClockTriggeredAbility copy() {
+ return new MidnightClockTriggeredAbility(this);
+ }
+
+ @Override
+ public String getRule() {
+ return "When the twelfth hour counter is put on {this}, " +
+ "shuffle your hand and graveyard into your library, " +
+ "then draw seven cards. Exile {this}.";
+ }
+}
+
+class MidnightClockEffect extends OneShotEffect {
+
+ private static final Effect effect = new ExileSourceEffect();
+
+ MidnightClockEffect() {
+ super(Outcome.Benefit);
+ }
+
+ private MidnightClockEffect(final MidnightClockEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public MidnightClockEffect copy() {
+ return new MidnightClockEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ Cards cards = new CardsImpl(player.getHand());
+ cards.addAll(player.getGraveyard());
+ player.putCardsOnTopOfLibrary(cards, game, source, false);
+ player.shuffleLibrary(source, game);
+ player.drawCards(7, game);
+ return effect.apply(game, source);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/m/MindBomb.java b/Mage.Sets/src/mage/cards/m/MindBomb.java
index c7b71a15e59..f1d0a392b47 100644
--- a/Mage.Sets/src/mage/cards/m/MindBomb.java
+++ b/Mage.Sets/src/mage/cards/m/MindBomb.java
@@ -25,7 +25,7 @@ public final class MindBomb extends CardImpl {
public MindBomb(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}");
- // Each player may discard up to three cards. Mind Bomb deals damage to each player equal to 3 minus the number of cards he or she discarded this way.
+ // Each player may discard up to three cards. Mind Bomb deals damage to each player equal to 3 minus the number of cards they discarded this way.
this.getSpellAbility().addEffect(new MindBombEffect());
}
@@ -44,7 +44,7 @@ class MindBombEffect extends OneShotEffect {
public MindBombEffect() {
super(Outcome.Neutral);
this.staticText = "Each player may discard up to three cards."
- + " {this} deals damage to each player equal to 3 minus the number of cards he or she discarded this way";
+ + " {this} deals damage to each player equal to 3 minus the number of cards they discarded this way";
}
public MindBombEffect(final MindBombEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/m/MindGrind.java b/Mage.Sets/src/mage/cards/m/MindGrind.java
index ba9c059dcf7..038e427e1b4 100644
--- a/Mage.Sets/src/mage/cards/m/MindGrind.java
+++ b/Mage.Sets/src/mage/cards/m/MindGrind.java
@@ -26,7 +26,7 @@ public final class MindGrind extends CardImpl {
public MindGrind(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}{B}");
- // Each opponent reveals cards from the top of their library until he or she reveals X land cards, then puts all cards revealed this way into their graveyard. X can't be 0.
+ // Each opponent reveals cards from the top of their library until they reveal X land cards, then puts all cards revealed this way into their graveyard. X can't be 0.
this.getSpellAbility().addEffect(new MindGrindEffect());
for (VariableCost cost : this.getSpellAbility().getManaCosts().getVariableCosts()) {
if (cost instanceof VariableManaCost) {
@@ -50,7 +50,7 @@ class MindGrindEffect extends OneShotEffect {
public MindGrindEffect() {
super(Outcome.Discard);
- this.staticText = "Each opponent reveals cards from the top of their library until he or she reveals X land cards, then puts all cards revealed this way into their graveyard. X can't be 0";
+ this.staticText = "Each opponent reveals cards from the top of their library until they reveal X land cards, then puts all cards revealed this way into their graveyard. X can't be 0";
}
public MindGrindEffect(final MindGrindEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/m/MindMaggots.java b/Mage.Sets/src/mage/cards/m/MindMaggots.java
index a53f2ceb1eb..e98e414ce8b 100644
--- a/Mage.Sets/src/mage/cards/m/MindMaggots.java
+++ b/Mage.Sets/src/mage/cards/m/MindMaggots.java
@@ -1,88 +1,88 @@
-package mage.cards.m;
-
-import java.util.UUID;
-import mage.MageInt;
-import mage.abilities.Ability;
-import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.counter.AddCountersSourceEffect;
-import mage.cards.Card;
-import mage.constants.SubType;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.counters.CounterType;
-import mage.filter.common.FilterCreatureCard;
-import mage.game.Game;
-import mage.players.Player;
-import mage.target.common.TargetCardInHand;
-
-/**
- *
- * @author jeffwadsworth
- */
-public final class MindMaggots extends CardImpl {
-
- public MindMaggots(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
-
- this.subtype.add(SubType.INSECT);
- this.power = new MageInt(2);
- this.toughness = new MageInt(2);
-
- // When Mind Maggots enters the battlefield, discard any number of creature cards.
- // For each card discarded this way, put two +1/+1 counters on Mind Maggots.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new MindMaggotsEffect()));
-
- }
-
- public MindMaggots(final MindMaggots card) {
- super(card);
- }
-
- @Override
- public MindMaggots copy() {
- return new MindMaggots(this);
- }
-}
-
-class MindMaggotsEffect extends OneShotEffect {
-
- MindMaggotsEffect() {
- super(Outcome.BoostCreature);
- this.staticText = "discard any number of creature cards. For each card discarded this way, put two +1/+1 counters on {this}";
- }
-
- MindMaggotsEffect(final MindMaggotsEffect effect) {
- super(effect);
- }
-
- @Override
- public MindMaggotsEffect copy() {
- return new MindMaggotsEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- int numToDiscard = controller.getAmount(0,
- controller.getHand().getCards(new FilterCreatureCard(), game).size(),
- "Discard how many creature cards?",
- game);
- TargetCardInHand target = new TargetCardInHand(numToDiscard, new FilterCreatureCard());
- if (controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) {
- for (UUID targetId : target.getTargets()) {
- Card card = game.getCard(targetId);
- if (card != null
- && controller.discard(card, source, game)) {
- new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)).apply(game, source);
- }
- }
- }
- return true;
- }
- return false;
- }
-}
+package mage.cards.m;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.cards.Card;
+import mage.constants.SubType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.counters.CounterType;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.common.TargetCardInHand;
+
+/**
+ *
+ * @author jeffwadsworth
+ */
+public final class MindMaggots extends CardImpl {
+
+ public MindMaggots(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
+
+ this.subtype.add(SubType.INSECT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // When Mind Maggots enters the battlefield, discard any number of creature cards.
+ // For each card discarded this way, put two +1/+1 counters on Mind Maggots.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new MindMaggotsEffect()));
+
+ }
+
+ public MindMaggots(final MindMaggots card) {
+ super(card);
+ }
+
+ @Override
+ public MindMaggots copy() {
+ return new MindMaggots(this);
+ }
+}
+
+class MindMaggotsEffect extends OneShotEffect {
+
+ MindMaggotsEffect() {
+ super(Outcome.BoostCreature);
+ this.staticText = "discard any number of creature cards. For each card discarded this way, put two +1/+1 counters on {this}";
+ }
+
+ MindMaggotsEffect(final MindMaggotsEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public MindMaggotsEffect copy() {
+ return new MindMaggotsEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller != null) {
+ int numToDiscard = controller.getAmount(0,
+ controller.getHand().getCards(StaticFilters.FILTER_CARD_CREATURE, game).size(),
+ "Discard how many creature cards?",
+ game);
+ TargetCardInHand target = new TargetCardInHand(numToDiscard, StaticFilters.FILTER_CARD_CREATURE);
+ if (controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) {
+ for (UUID targetId : target.getTargets()) {
+ Card card = game.getCard(targetId);
+ if (card != null
+ && controller.discard(card, source, game)) {
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)).apply(game, source);
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MindWhip.java b/Mage.Sets/src/mage/cards/m/MindWhip.java
index 499372e0b11..d3eea1bf1ae 100644
--- a/Mage.Sets/src/mage/cards/m/MindWhip.java
+++ b/Mage.Sets/src/mage/cards/m/MindWhip.java
@@ -41,11 +41,11 @@ public final class MindWhip extends CardImpl {
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
- // At the beginning of the upkeep of enchanted creature's controller, that player may pay {3}. If he or she doesn't, Mind Whip deals 2 damage to that player and you tap that creature.
+ // At the beginning of the upkeep of enchanted creature's controller, that player may pay {3}. If they don't, Mind Whip deals 2 damage to that player and you tap that creature.
Effect effect = new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new MindWhipEffect(),
new ManaCostsImpl("{3}"),
"");
- effect.setText("that player may pay {3}. If he or she doesn't, {this} deals 2 damage to that player and you tap that creature.");
+ effect.setText("that player may pay {3}. If they don't, {this} deals 2 damage to that player and you tap that creature.");
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
effect,
TargetController.CONTROLLER_ATTACHED_TO, false));
diff --git a/Mage.Sets/src/mage/cards/m/MindclawShaman.java b/Mage.Sets/src/mage/cards/m/MindclawShaman.java
index 8c1f9e3e016..86fe0265723 100644
--- a/Mage.Sets/src/mage/cards/m/MindclawShaman.java
+++ b/Mage.Sets/src/mage/cards/m/MindclawShaman.java
@@ -37,7 +37,8 @@ public final class MindclawShaman extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- // When Mindclaw Shaman enters the battlefield, target opponent reveals their hand. You may cast an instant or sorcery card from it without paying its mana cost.
+ // When Mindclaw Shaman enters the battlefield, target opponent reveals their hand.
+ // You may cast an instant or sorcery card from it without paying its mana cost.
Ability ability = new EntersBattlefieldTriggeredAbility(new MindclawShamanEffect(), false);
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
@@ -64,8 +65,9 @@ class MindclawShamanEffect extends OneShotEffect {
}
public MindclawShamanEffect() {
- super(Outcome.Discard);
- this.staticText = "target opponent reveals their hand. You may cast an instant or sorcery card from it without paying its mana cost";
+ super(Outcome.PlayForFree);
+ this.staticText = "target opponent reveals their hand. You may cast "
+ + "an instant or sorcery card from it without paying its mana cost";
}
public MindclawShamanEffect(final MindclawShamanEffect effect) {
@@ -88,13 +90,18 @@ class MindclawShamanEffect extends OneShotEffect {
if (controller != null) {
TargetCard target = new TargetCard(Zone.HAND, filter);
target.setNotTarget(true);
- if (controller.choose(Outcome.Benefit, targetOpponent.getHand(), target, game)) {
+ if (controller.choose(Outcome.PlayForFree, targetOpponent.getHand(), target, game)) {
Card chosenCard = targetOpponent.getHand().get(target.getFirstTarget(), game);
if (chosenCard != null) {
- if (controller.chooseUse(Outcome.Benefit, "Cast the chosen card?", source, game)) {
- controller.cast(chosenCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ if (controller.chooseUse(Outcome.PlayForFree, "Cast the chosen card without "
+ + "paying its mana cost?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + chosenCard.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(chosenCard, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + chosenCard.getId(), null);
} else {
- game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " canceled casting the card.");
+ game.informPlayers(sourceObject.getLogName() + ": "
+ + controller.getLogName() + " canceled casting the card.");
}
}
}
diff --git a/Mage.Sets/src/mage/cards/m/MindleechMass.java b/Mage.Sets/src/mage/cards/m/MindleechMass.java
index 85f4dca3e97..41704f0e832 100644
--- a/Mage.Sets/src/mage/cards/m/MindleechMass.java
+++ b/Mage.Sets/src/mage/cards/m/MindleechMass.java
@@ -1,4 +1,3 @@
-
package mage.cards.m;
import java.util.UUID;
@@ -38,7 +37,8 @@ public final class MindleechMass extends CardImpl {
// Trample
this.addAbility(TrampleAbility.getInstance());
- // Whenever Mindleech Mass deals combat damage to a player, you may look at that player's hand. If you do, you may cast a nonland card in it without paying that card's mana cost.
+ // Whenever Mindleech Mass deals combat damage to a player, you may look at that
+ // player's hand. If you do, you may cast a nonland card in it without paying that card's mana cost.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new MindleechMassEffect(), true, true));
}
@@ -56,7 +56,8 @@ class MindleechMassEffect extends OneShotEffect {
public MindleechMassEffect() {
super(Outcome.PlayForFree);
- this.staticText = "you may look at that player's hand. If you do, you may cast a nonland card in it without paying that card's mana cost";
+ this.staticText = "you may look at that player's hand. If you do, "
+ + "you may cast a nonland card in it without paying that card's mana cost";
}
public MindleechMassEffect(final MindleechMassEffect effect) {
@@ -82,7 +83,10 @@ class MindleechMassEffect extends OneShotEffect {
if (controller.chooseTarget(Outcome.PlayForFree, cardsInHand, target, source, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
}
diff --git a/Mage.Sets/src/mage/cards/m/MindsDilation.java b/Mage.Sets/src/mage/cards/m/MindsDilation.java
index b3a7c6381f2..05f70814924 100644
--- a/Mage.Sets/src/mage/cards/m/MindsDilation.java
+++ b/Mage.Sets/src/mage/cards/m/MindsDilation.java
@@ -1,4 +1,3 @@
-
package mage.cards.m;
import java.util.List;
@@ -32,9 +31,11 @@ public final class MindsDilation extends CardImpl {
public MindsDilation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{5}{U}{U}");
- // Whenever an opponent casts their first spell each turn, that player exiles the top card of their library. If it's a nonland card,
+ // Whenever an opponent casts their first spell each turn,
+ // that player exiles the top card of their library. If it's a nonland card,
// you may cast it without paying its mana cost.
- this.addAbility(new MindsDilationTriggeredAbility(new MindsDilationEffect(), false), new SpellsCastWatcher());
+ this.addAbility(new MindsDilationTriggeredAbility(new MindsDilationEffect(),
+ false), new SpellsCastWatcher());
}
public MindsDilation(final MindsDilation card) {
@@ -81,16 +82,19 @@ class MindsDilationTriggeredAbility extends SpellCastOpponentTriggeredAbility {
@Override
public String getRule() {
- return "Whenever an opponent casts their first spell each turn, that player exiles the top card of their library."
- + " If it's a nonland card, you may cast it without paying its mana cost.";
+ return "Whenever an opponent casts their first spell each turn, "
+ + "that player exiles the top card of their library."
+ + " If it's a nonland card, you may cast it without "
+ + "paying its mana cost.";
}
}
class MindsDilationEffect extends OneShotEffect {
MindsDilationEffect() {
- super(Outcome.Benefit);
- this.staticText = "that player exiles the top card of their library. If it's a nonland card, you may cast it without paying its mana cost";
+ super(Outcome.PlayForFree);
+ this.staticText = "that player exiles the top card of their library. "
+ + "If it's a nonland card, you may cast it without paying its mana cost";
}
MindsDilationEffect(final MindsDilationEffect effect) {
@@ -107,13 +111,20 @@ class MindsDilationEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source));
- if (controller != null && sourceObject != null && opponent != null) {
+ if (controller != null
+ && sourceObject != null
+ && opponent != null) {
if (opponent.getLibrary().hasCards()) {
Card card = opponent.getLibrary().getFromTop(game);
- if (card != null && opponent.moveCards(card, Zone.EXILED, source, game)) {
+ if (card != null
+ && opponent.moveCards(card, Zone.EXILED, source, game)) {
if (!card.isLand()) {
- if (controller.chooseUse(outcome, "Cast " + card.getLogName() + " without paying its mana cost from exile?", source, game)) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ if (controller.chooseUse(outcome, "Cast " + card.getLogName()
+ + " without paying its mana cost from exile?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
}
diff --git a/Mage.Sets/src/mage/cards/m/Mindshrieker.java b/Mage.Sets/src/mage/cards/m/Mindshrieker.java
index 371ed1ebc61..b8effb0479e 100644
--- a/Mage.Sets/src/mage/cards/m/Mindshrieker.java
+++ b/Mage.Sets/src/mage/cards/m/Mindshrieker.java
@@ -1,7 +1,5 @@
-
package mage.cards.m;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -12,17 +10,14 @@ import mage.abilities.keyword.FlyingAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.SubType;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
+import java.util.UUID;
+
/**
- *
* @author BetaSteward
*/
public final class Mindshrieker extends CardImpl {
@@ -35,7 +30,9 @@ public final class Mindshrieker extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(1);
+ // Flying
this.addAbility(FlyingAbility.getInstance());
+
// {2}: Target player puts the top card of their library into their graveyard. Mindshrieker gets +X/+X until end of turn, where X is that card's converted mana cost.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MindshriekerEffect(), new ManaCostsImpl("{2}"));
ability.addTarget(new TargetPlayer());
@@ -56,7 +53,7 @@ public final class Mindshrieker extends CardImpl {
class MindshriekerEffect extends OneShotEffect {
public MindshriekerEffect() {
- super(Outcome.BoostCreature);
+ super(Outcome.Detriment);
staticText = "Target player puts the top card of their library into their graveyard. {this} gets +X/+X until end of turn, where X is that card's converted mana cost";
}
diff --git a/Mage.Sets/src/mage/cards/m/MiresGrasp.java b/Mage.Sets/src/mage/cards/m/MiresGrasp.java
new file mode 100644
index 00000000000..0205aea176c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MiresGrasp.java
@@ -0,0 +1,47 @@
+package mage.cards.m;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+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 MiresGrasp extends CardImpl {
+
+ public MiresGrasp(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}");
+
+ this.subtype.add(SubType.AURA);
+
+ // Enchant creature
+ TargetPermanent auraTarget = new TargetCreaturePermanent();
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // Enchanted creature gets -3/-3.
+ this.addAbility(new SimpleStaticAbility(new BoostEnchantedEffect(-3, -3)));
+ }
+
+ private MiresGrasp(final MiresGrasp card) {
+ super(card);
+ }
+
+ @Override
+ public MiresGrasp copy() {
+ return new MiresGrasp(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MirkoVoskMindDrinker.java b/Mage.Sets/src/mage/cards/m/MirkoVoskMindDrinker.java
index 26f0f6d73dd..85b98ca10ef 100644
--- a/Mage.Sets/src/mage/cards/m/MirkoVoskMindDrinker.java
+++ b/Mage.Sets/src/mage/cards/m/MirkoVoskMindDrinker.java
@@ -32,7 +32,7 @@ public final class MirkoVoskMindDrinker extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
- // Whenever Mirko Vosk, Mind Drinker deals combat damage to a player, that player reveals cards from the top of their library until he or she reveals four land cards, then puts those cards into their graveyard.
+ // Whenever Mirko Vosk, Mind Drinker deals combat damage to a player, that player reveals cards from the top of their library until they reveal four land cards, then puts those cards into their graveyard.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new MirkoVoskMindDrinkerEffect(), false, true));
}
@@ -51,7 +51,7 @@ class MirkoVoskMindDrinkerEffect extends OneShotEffect {
public MirkoVoskMindDrinkerEffect() {
super(Outcome.Benefit);
- this.staticText = "that player reveals cards from the top of their library until he or she reveals four land cards, then puts those cards into their graveyard";
+ this.staticText = "that player reveals cards from the top of their library until they reveal four land cards, then puts those cards into their graveyard";
}
public MirkoVoskMindDrinkerEffect(final MirkoVoskMindDrinkerEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/m/MirrorMadPhantasm.java b/Mage.Sets/src/mage/cards/m/MirrorMadPhantasm.java
index c539ca9fa66..34511c34805 100644
--- a/Mage.Sets/src/mage/cards/m/MirrorMadPhantasm.java
+++ b/Mage.Sets/src/mage/cards/m/MirrorMadPhantasm.java
@@ -35,7 +35,7 @@ public final class MirrorMadPhantasm extends CardImpl {
this.toughness = new MageInt(1);
this.addAbility(FlyingAbility.getInstance());
- // {1}{U}: Mirror-Mad Phantasm's owner shuffles it into their library. If that player does, he or she reveals cards from the top of that library until a card named Mirror-Mad Phantasm is revealed. That player puts that card onto the battlefield and all other cards revealed this way into their graveyard.
+ // {1}{U}: Mirror-Mad Phantasm's owner shuffles it into their library. If that player does, they reveal cards from the top of that library until a card named Mirror-Mad Phantasm is revealed. That player puts that card onto the battlefield and all other cards revealed this way into their graveyard.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new MirrorMadPhantasmEffect(), new ManaCostsImpl("{1}{U}")));
}
@@ -54,7 +54,7 @@ class MirrorMadPhantasmEffect extends OneShotEffect {
public MirrorMadPhantasmEffect() {
super(Outcome.Detriment);
- this.staticText = "{this}'s owner shuffles it into their library. If that player does, he or she reveals cards from the top of that library until a card named Mirror-Mad Phantasm is revealed. That player puts that card onto the battlefield and all other cards revealed this way into their graveyard";
+ this.staticText = "{this}'s owner shuffles it into their library. If that player does, they reveal cards from the top of that library until a card named Mirror-Mad Phantasm is revealed. That player puts that card onto the battlefield and all other cards revealed this way into their graveyard";
}
public MirrorMadPhantasmEffect(final MirrorMadPhantasmEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/m/Mirrormade.java b/Mage.Sets/src/mage/cards/m/Mirrormade.java
new file mode 100644
index 00000000000..4a82c19e0d6
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/Mirrormade.java
@@ -0,0 +1,34 @@
+package mage.cards.m;
+
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.effects.common.CopyPermanentEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.StaticFilters;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class Mirrormade extends CardImpl {
+
+ public Mirrormade(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}{U}");
+
+ // You may have Mirrormade enter the battlefield as a copy of any artifact or enchantment on the battlefield.
+ this.addAbility(new EntersBattlefieldAbility(
+ new CopyPermanentEffect(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT), true
+ ));
+ }
+
+ private Mirrormade(final Mirrormade card) {
+ super(card);
+ }
+
+ @Override
+ public Mirrormade copy() {
+ return new Mirrormade(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MirrorwingDragon.java b/Mage.Sets/src/mage/cards/m/MirrorwingDragon.java
index 73e4af0c51d..72b2f41ddea 100644
--- a/Mage.Sets/src/mage/cards/m/MirrorwingDragon.java
+++ b/Mage.Sets/src/mage/cards/m/MirrorwingDragon.java
@@ -38,7 +38,7 @@ public final class MirrorwingDragon extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever a player casts an instant or sorcery spell that targets only Mirrorwing Dragon,
- // that player copies that spell for each other creature he or she controls that the spell could target.
+ // that player copies that spell for each other creature they control that the spell could target.
// Each copy targets a different one of those creatures.
this.addAbility(new MirrorwingDragonCopyTriggeredAbility());
}
@@ -105,7 +105,7 @@ class MirrorwingDragonCopyTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
return "Whenever a player casts an instant or sorcery spell that targets only {this}, "
- + "that player copies that spell for each other creature he or she controls that the spell could target. "
+ + "that player copies that spell for each other creature they control that the spell could target. "
+ "Each copy targets a different one of those creatures.";
}
}
@@ -114,7 +114,7 @@ class MirrorwingDragonCopySpellEffect extends CopySpellForEachItCouldTargetEffec
public MirrorwingDragonCopySpellEffect() {
this(new FilterControlledCreaturePermanent());
- this.staticText = "that player copies that spell for each other creature he or she controls that the spell could target. Each copy targets a different one of those creatures.";
+ this.staticText = "that player copies that spell for each other creature they control that the spell could target. Each copy targets a different one of those creatures.";
}
public MirrorwingDragonCopySpellEffect(MirrorwingDragonCopySpellEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/m/MisersCage.java b/Mage.Sets/src/mage/cards/m/MisersCage.java
index 9a344eee5dd..5d70e48ce0b 100644
--- a/Mage.Sets/src/mage/cards/m/MisersCage.java
+++ b/Mage.Sets/src/mage/cards/m/MisersCage.java
@@ -22,7 +22,7 @@ public final class MisersCage extends CardImpl {
public MisersCage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
- // At the beginning of each opponent's upkeep, if that player has five or more cards in hand, Misers' Cage deals 2 damage to him or her.
+ // At the beginning of each opponent's upkeep, if that player has five or more cards in hand, Misers' Cage deals 2 damage to that player.
this.addAbility(new MisersCageTriggeredAbility());
}
diff --git a/Mage.Sets/src/mage/cards/m/Misfortune.java b/Mage.Sets/src/mage/cards/m/Misfortune.java
index c3e0b8ec8ba..b63fa0601c5 100644
--- a/Mage.Sets/src/mage/cards/m/Misfortune.java
+++ b/Mage.Sets/src/mage/cards/m/Misfortune.java
@@ -26,7 +26,7 @@ public final class Misfortune extends CardImpl {
public Misfortune(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}{R}{G}");
- // An opponent chooses one - You put a +1/+1 counter on each creature you control and gain 4 life; or you put a -1/-1 counter on each creature that player controls and Misfortune deals 4 damage to him or her.
+ // An opponent chooses one - You put a +1/+1 counter on each creature you control and gain 4 life; or you put a -1/-1 counter on each creature that player controls and Misfortune deals 4 damage to that player.
this.getSpellAbility().addEffect(new MisfortuneEffect());
this.getSpellAbility().addTarget(new TargetOpponent(true));
}
@@ -48,7 +48,7 @@ class MisfortuneEffect extends OneShotEffect {
staticText = "An opponent chooses one - "
+ "You put a +1/+1 counter on each creature you control and gain "
+ "4 life; or you put a -1/-1 counter on each creature that player "
- + "controls and Misfortune deals 4 damage to him or her";
+ + "controls and Misfortune deals 4 damage to that player";
}
public MisfortuneEffect(final MisfortuneEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/m/MistfordRiverTurtle.java b/Mage.Sets/src/mage/cards/m/MistfordRiverTurtle.java
new file mode 100644
index 00000000000..3bfb928789e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MistfordRiverTurtle.java
@@ -0,0 +1,58 @@
+package mage.cards.m;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.filter.predicate.permanent.AttackingPredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class MistfordRiverTurtle extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterCreaturePermanent("another target attacking non-Human creature");
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ filter.add(AttackingPredicate.instance);
+ filter.add(Predicates.not(new SubtypePredicate(SubType.HUMAN)));
+ }
+
+ public MistfordRiverTurtle(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
+
+ this.subtype.add(SubType.TURTLE);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(5);
+
+ // Whenever Mistford River Turtle attacks, another target attacking non-Human creature can't be blocked this turn.
+ Ability ability = new AttacksTriggeredAbility(new CantBeBlockedTargetEffect(Duration.EndOfTurn)
+ .setText("another target attacking non-Human creature can't be blocked this turn"), false);
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(ability);
+ }
+
+ private MistfordRiverTurtle(final MistfordRiverTurtle card) {
+ super(card);
+ }
+
+ @Override
+ public MistfordRiverTurtle copy() {
+ return new MistfordRiverTurtle(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MizzixOfTheIzmagnus.java b/Mage.Sets/src/mage/cards/m/MizzixOfTheIzmagnus.java
index 4a598ae096b..a77d19bbb93 100644
--- a/Mage.Sets/src/mage/cards/m/MizzixOfTheIzmagnus.java
+++ b/Mage.Sets/src/mage/cards/m/MizzixOfTheIzmagnus.java
@@ -1,4 +1,3 @@
-
package mage.cards.m;
import java.util.UUID;
@@ -111,7 +110,7 @@ class MizzixOfTheIzmagnusCostReductionEffect extends CostModificationEffectImpl
Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId());
if (spell != null) {
return StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY.match(spell, source.getSourceId(), source.getControllerId(), game);
- } else if (((SpellAbility) abilityToModify).isCheckPlayableMode()) {
+ } else if (game.inCheckPlayableState()) {
// Spell is not on the stack yet, but possible playable spells are determined
Card sourceCard = game.getCard(abilityToModify.getSourceId());
return sourceCard != null && StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY.match(sourceCard, source.getSourceId(), source.getControllerId(), game);
diff --git a/Mage.Sets/src/mage/cards/m/MizzixsMastery.java b/Mage.Sets/src/mage/cards/m/MizzixsMastery.java
index f4a146756bb..d36052acf34 100644
--- a/Mage.Sets/src/mage/cards/m/MizzixsMastery.java
+++ b/Mage.Sets/src/mage/cards/m/MizzixsMastery.java
@@ -28,13 +28,17 @@ public final class MizzixsMastery extends CardImpl {
public MizzixsMastery(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}");
- // Exile target card that's an instant or sorcery from your graveyard. For each card exiled this way, copy it, and you may cast the copy without paying its mana cost. Exile Mizzix's Mastery.
+ // Exile target card that's an instant or sorcery from your graveyard.
+ // For each card exiled this way, copy it, and you may cast the copy
+ // without paying its mana cost. Exile Mizzix's Mastery.
this.getSpellAbility().addEffect(new MizzixsMasteryEffect());
- this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterInstantOrSorceryCard("card that's an instant or sorcery from your graveyard")));
+ this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(
+ new FilterInstantOrSorceryCard("card that's an instant or sorcery from your graveyard")));
this.getSpellAbility().addEffect(ExileSpellEffect.getInstance());
// Overload {5}{R}{R}{R}
- Ability ability = new OverloadAbility(this, new MizzixsMasteryOverloadEffect(), new ManaCostsImpl("{5}{R}{R}{R}"));
+ Ability ability = new OverloadAbility(this, new MizzixsMasteryOverloadEffect(),
+ new ManaCostsImpl("{5}{R}{R}{R}"));
ability.addEffect(ExileSpellEffect.getInstance());
this.addAbility(ability);
}
@@ -53,7 +57,9 @@ class MizzixsMasteryEffect extends OneShotEffect {
public MizzixsMasteryEffect() {
super(Outcome.PlayForFree);
- this.staticText = "Exile target card that's an instant or sorcery from your graveyard. For each card exiled this way, copy it, and you may cast the copy without paying its mana cost";
+ this.staticText = "Exile target card that's an instant or sorcery from your "
+ + "graveyard. For each card exiled this way, copy it, and you "
+ + "may cast the copy without paying its mana cost";
}
public MizzixsMasteryEffect(final MizzixsMasteryEffect effect) {
@@ -74,8 +80,12 @@ class MizzixsMasteryEffect extends OneShotEffect {
if (controller.moveCards(card, Zone.EXILED, source, game)) {
Card cardCopy = game.copyCard(card, source, source.getControllerId());
if (cardCopy.getSpellAbility().canChooseTarget(game)
- && controller.chooseUse(outcome, "Cast copy of " + card.getName() + " without paying its mana cost?", source, game)) {
- controller.cast(cardCopy.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ && controller.chooseUse(outcome, "Cast copy of "
+ + card.getName() + " without paying its mana cost?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + cardCopy.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(cardCopy, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + cardCopy.getId(), null);
}
}
}
@@ -89,7 +99,9 @@ class MizzixsMasteryOverloadEffect extends OneShotEffect {
public MizzixsMasteryOverloadEffect() {
super(Outcome.PlayForFree);
- this.staticText = "Exile each card that's an instant or sorcery from your graveyard. For each card exiled this way, copy it, and you may cast the copy without paying its mana cost. Exile {this}";
+ this.staticText = "Exile each card that's an instant or sorcery from "
+ + "your graveyard. For each card exiled this way, copy it, "
+ + "and you may cast the copy without paying its mana cost. Exile {this}";
}
public MizzixsMasteryOverloadEffect(final MizzixsMasteryOverloadEffect effect) {
@@ -105,7 +117,8 @@ class MizzixsMasteryOverloadEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- Set cardsToExile = controller.getGraveyard().getCards(new FilterInstantOrSorceryCard(), source.getId(), source.getControllerId(), game);
+ Set cardsToExile = controller.getGraveyard().getCards(
+ new FilterInstantOrSorceryCard(), source.getId(), source.getControllerId(), game);
if (!cardsToExile.isEmpty()) {
if (controller.moveCards(cardsToExile, Zone.EXILED, source, game)) {
Cards copiedCards = new CardsImpl();
@@ -114,18 +127,25 @@ class MizzixsMasteryOverloadEffect extends OneShotEffect {
}
boolean continueCasting = true;
while (continueCasting && controller.isInGame()) {
- TargetCard targetCard = new TargetCard(0, 1, Zone.EXILED, new FilterCard("copied card to cast without paying its mana cost?"));
+ TargetCard targetCard = new TargetCard(0, 1, Zone.EXILED,
+ new FilterCard("copied card to cast without paying its mana cost?"));
targetCard.setNotTarget(true);
- if (controller.choose(outcome, copiedCards, targetCard, game)) {
+ if (controller.choose(Outcome.PlayForFree, copiedCards, targetCard, game)) {
Card selectedCard = game.getCard(targetCard.getFirstTarget());
- if (selectedCard != null && selectedCard.getSpellAbility().canChooseTarget(game)) {
- if (controller.cast(selectedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
+ if (selectedCard != null
+ && selectedCard.getSpellAbility().canChooseTarget(game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + selectedCard.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(selectedCard, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + selectedCard.getId(), null);
+ if (cardWasCast) {
copiedCards.remove(selectedCard);
}
}
}
continueCasting = !copiedCards.isEmpty()
- && controller.chooseUse(outcome, "Cast one of the copied cards without paying its mana cost?", source, game);
+ && controller.chooseUse(Outcome.PlayForFree, "Cast one of the copied "
+ + "cards without paying its mana cost?", source, game);
}
}
}
diff --git a/Mage.Sets/src/mage/cards/m/MnemonicBetrayal.java b/Mage.Sets/src/mage/cards/m/MnemonicBetrayal.java
index 757e38dd836..07101bdc0d9 100644
--- a/Mage.Sets/src/mage/cards/m/MnemonicBetrayal.java
+++ b/Mage.Sets/src/mage/cards/m/MnemonicBetrayal.java
@@ -3,18 +3,20 @@ package mage.cards.m;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.effects.AsThoughEffectImpl;
+import mage.abilities.effects.AsThoughManaEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileSpellEffect;
import mage.cards.*;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
+import mage.players.ManaPoolItem;
import mage.players.Player;
+import mage.util.CardUtil;
+
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
-import mage.abilities.effects.AsThoughManaEffect;
-import mage.players.ManaPoolItem;
/**
* @author TheElk801
@@ -156,7 +158,7 @@ class MnemonicBetrayalAnyColorEffect extends AsThoughEffectImpl implements AsTho
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
- objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
if (objectId.equals(card.getId())
&& card.getZoneChangeCounter(game) <= zoneCounter + 1
&& affectedControllerId.equals(source.getControllerId())) {
diff --git a/Mage.Sets/src/mage/cards/m/MogisGodOfSlaughter.java b/Mage.Sets/src/mage/cards/m/MogisGodOfSlaughter.java
index eef7327fa95..52ddc25983f 100644
--- a/Mage.Sets/src/mage/cards/m/MogisGodOfSlaughter.java
+++ b/Mage.Sets/src/mage/cards/m/MogisGodOfSlaughter.java
@@ -1,33 +1,26 @@
-
package mage.cards.m;
-import java.util.Locale;
-import java.util.UUID;
import mage.MageInt;
-import mage.MageObject;
import mage.abilities.Ability;
-import mage.abilities.Mode;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.costs.Cost;
-import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.dynamicvalue.common.DevotionCount;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
-import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
+import mage.filter.StaticFilters;
import mage.game.Game;
+import mage.game.permanent.Permanent;
import mage.players.Player;
+import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
-import mage.util.CardUtil;
+
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class MogisGodOfSlaughter extends CardImpl {
@@ -42,21 +35,20 @@ public final class MogisGodOfSlaughter extends CardImpl {
// Indestructible
this.addAbility(IndestructibleAbility.getInstance());
- // As long as your devotion to black and red is less than seven, Mogis isn't a creature.
- Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.B, ColoredManaSymbol.R), 7);
- effect.setText("As long as your devotion to black and red is less than seven, Mogis isn't a creature");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
- // At the beginning of each opponent's upkeep, Mogis deals 2 damage to that player unless he or she sacrifices a creature.
- effect = new DoUnlessTargetPaysCost(new DamageTargetEffect(2, true, "that player"),
- new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)),
- "Sacrifice a creature? (otherwise you get 2 damage)");
- effect.setText("Mogis deals 2 damage to that player unless he or she sacrifices a creature");
- Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.OPPONENT, false, true);
+ // As long as your devotion to black and red is less than seven, Mogis isn't a creature.
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.BR, 7))
+ .addHint(DevotionCount.BR.getHint()));
+
+ // At the beginning of each opponent's upkeep, Mogis deals 2 damage to that player unless they sacrifice a creature.
+ Ability ability = new BeginningOfUpkeepTriggeredAbility(
+ Zone.BATTLEFIELD, new MogisGodOfSlaughterEffect(),
+ TargetController.OPPONENT, false, true
+ );
this.addAbility(ability);
}
- public MogisGodOfSlaughter(final MogisGodOfSlaughter card) {
+ private MogisGodOfSlaughter(final MogisGodOfSlaughter card) {
super(card);
}
@@ -66,76 +58,35 @@ public final class MogisGodOfSlaughter extends CardImpl {
}
}
-class DoUnlessTargetPaysCost extends OneShotEffect {
+class MogisGodOfSlaughterEffect extends OneShotEffect {
- private final OneShotEffect executingEffect;
- private final Cost cost;
- private final String userMessage;
-
- public DoUnlessTargetPaysCost(OneShotEffect effect, Cost cost) {
- this(effect, cost, null);
+ MogisGodOfSlaughterEffect() {
+ super(Outcome.Damage);
+ staticText = "{this} deals 2 damage to that player unless they sacrifice a creature";
}
- public DoUnlessTargetPaysCost(OneShotEffect effect, Cost cost, String userMessage) {
- super(Outcome.Benefit);
- this.executingEffect = effect;
- this.cost = cost;
- this.userMessage = userMessage;
- }
-
- public DoUnlessTargetPaysCost(final DoUnlessTargetPaysCost effect) {
+ private MogisGodOfSlaughterEffect(final MogisGodOfSlaughterEffect effect) {
super(effect);
- this.executingEffect = (OneShotEffect) effect.executingEffect.copy();
- this.cost = effect.cost.copy();
- this.userMessage = effect.userMessage;
+ }
+
+ @Override
+ public MogisGodOfSlaughterEffect copy() {
+ return new MogisGodOfSlaughterEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
- Player player = game.getPlayer(targetPointer.getFirst(game, source));
- MageObject mageObject = game.getObject(source.getSourceId());
- if (player != null && mageObject != null) {
- String message = userMessage;
- if (message == null) {
- message = getCostText() + " to prevent " + executingEffect.getText(source.getModes().getMode()) + '?';
- }
- message = CardUtil.replaceSourceName(message, mageObject.getLogName());
- cost.clearPaid();
- if (cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(executingEffect.getOutcome(), message, source, game)) {
- cost.pay(source, game, source.getSourceId(), player.getId(), false, null);
- }
- if (!cost.isPaid()) {
- executingEffect.setTargetPointer(this.targetPointer);
- return executingEffect.apply(game, source);
- }
- return true;
+ Player player = game.getPlayer(game.getActivePlayerId());
+ if (player == null || game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, game.getActivePlayerId(), game) == 0) {
+ return false;
}
- return false;
- }
-
- @Override
- public String getText(Mode mode) {
- if (!staticText.isEmpty()) {
- return staticText;
+ TargetPermanent target = new TargetControlledCreaturePermanent(1);
+ target.setNotTarget(true);
+ if (!player.chooseUse(outcome, "Sacrifice a creature to prevent 2 damage?", source, game)
+ || !player.choose(outcome, target, source.getSourceId(), game)) {
+ return player.damage(2, source.getSourceId(), game) > 0;
}
- return executingEffect.getText(mode) + "unless they" +
- getCostText();
+ Permanent permanent = game.getPermanent(target.getFirstTarget());
+ return permanent != null && permanent.sacrifice(source.getSourceId(), game);
}
-
- private String getCostText() {
- StringBuilder sb = new StringBuilder();
- String costText = cost.getText();
- if (costText != null
- && !costText.toLowerCase(Locale.ENGLISH).startsWith("discard")
- && !costText.toLowerCase(Locale.ENGLISH).startsWith("sacrifice")
- && !costText.toLowerCase(Locale.ENGLISH).startsWith("remove")) {
- sb.append("pay ");
- }
- return sb.append(costText).toString();
- }
-
- @Override
- public DoUnlessTargetPaysCost copy() {
- return new DoUnlessTargetPaysCost(this);
- }
-}
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/m/MogissMarauder.java b/Mage.Sets/src/mage/cards/m/MogissMarauder.java
index d797c3fd005..fd64155517d 100644
--- a/Mage.Sets/src/mage/cards/m/MogissMarauder.java
+++ b/Mage.Sets/src/mage/cards/m/MogissMarauder.java
@@ -1,4 +1,3 @@
-
package mage.cards.m;
import mage.MageInt;
@@ -11,7 +10,6 @@ import mage.abilities.keyword.IntimidateAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.ColoredManaSymbol;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.game.Game;
@@ -35,15 +33,21 @@ public final class MogissMarauder extends CardImpl {
// When Mogis's Marauder enters the battlefield, up to X target creatures each gain intimidate and haste, where X is your devotion to black.
Ability ability = new EntersBattlefieldTriggeredAbility(
- new GainAbilityTargetEffect(IntimidateAbility.getInstance(), Duration.EndOfTurn,
- "up to X target creatures each gain intimidate"), false);
- ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn,
- "and haste until end of turn, where X is your devotion to black"));
+ new GainAbilityTargetEffect(
+ IntimidateAbility.getInstance(), Duration.EndOfTurn,
+ "up to X target creatures each gain intimidate"
+ ), false
+ );
+ ability.addEffect(new GainAbilityTargetEffect(
+ HasteAbility.getInstance(), Duration.EndOfTurn,
+ "and haste until end of turn, where X is your devotion to black"
+ ));
ability.setTargetAdjuster(MogissMarauderAdjuster.instance);
+ ability.addHint(DevotionCount.B.getHint());
this.addAbility(ability);
}
- public MogissMarauder(final MogissMarauder card) {
+ private MogissMarauder(final MogissMarauder card) {
super(card);
}
@@ -59,7 +63,7 @@ enum MogissMarauderAdjuster implements TargetAdjuster {
@Override
public void adjustTargets(Ability ability, Game game) {
ability.getTargets().clear();
- int numbTargets = new DevotionCount(ColoredManaSymbol.B).calculate(game, ability, null);
+ int numbTargets = DevotionCount.B.calculate(game, ability, null);
if (numbTargets > 0) {
ability.addTarget(new TargetCreaturePermanent(0, numbTargets));
}
diff --git a/Mage.Sets/src/mage/cards/m/MoltenInfluence.java b/Mage.Sets/src/mage/cards/m/MoltenInfluence.java
index 05acc1f376a..c22c88ea996 100644
--- a/Mage.Sets/src/mage/cards/m/MoltenInfluence.java
+++ b/Mage.Sets/src/mage/cards/m/MoltenInfluence.java
@@ -23,7 +23,7 @@ public final class MoltenInfluence extends CardImpl {
public MoltenInfluence(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}");
- // Counter target instant or sorcery spell unless its controller has Molten Influence deal 4 damage to him or her.
+ // Counter target instant or sorcery spell unless its controller has Molten Influence deal 4 damage to them.
this.getSpellAbility().addTarget(new TargetSpell(StaticFilters.FILTER_SPELL_INSTANT_OR_SORCERY));
this.getSpellAbility().addEffect(new MoltenInfluenceEffect());
@@ -43,7 +43,7 @@ class MoltenInfluenceEffect extends OneShotEffect {
public MoltenInfluenceEffect() {
super(Outcome.Detriment);
- this.staticText = "Counter target instant or sorcery spell unless its controller has {this} deal 4 damage to him or her";
+ this.staticText = "Counter target instant or sorcery spell unless its controller has {this} deal 4 damage to them";
}
public MoltenInfluenceEffect(final MoltenInfluenceEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/m/MomirVigSimicVisionary.java b/Mage.Sets/src/mage/cards/m/MomirVigSimicVisionary.java
index f2b5c9361b7..fca77d6cc56 100644
--- a/Mage.Sets/src/mage/cards/m/MomirVigSimicVisionary.java
+++ b/Mage.Sets/src/mage/cards/m/MomirVigSimicVisionary.java
@@ -1,4 +1,3 @@
-
package mage.cards.m;
import java.util.Set;
@@ -18,7 +17,7 @@ import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterSpell;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
@@ -43,7 +42,7 @@ public final class MomirVigSimicVisionary extends CardImpl {
}
public MomirVigSimicVisionary(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{U}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ELF);
this.subtype.add(SubType.WIZARD);
@@ -52,7 +51,7 @@ public final class MomirVigSimicVisionary extends CardImpl {
this.toughness = new MageInt(2);
// Whenever you cast a green creature spell, you may search your library for a creature card and reveal it. If you do, shuffle your library and put that card on top of it.
- Effect effect = new SearchLibraryPutOnLibraryEffect(new TargetCardInLibrary(new FilterCreatureCard()), true, true);
+ Effect effect = new SearchLibraryPutOnLibraryEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_CREATURE), true, true);
effect.setText("you may search your library for a creature card and reveal it. If you do, shuffle your library and put that card on top of it");
this.addAbility(new SpellCastControllerTriggeredAbility(effect, filter, true));
diff --git a/Mage.Sets/src/mage/cards/m/Moonhold.java b/Mage.Sets/src/mage/cards/m/Moonhold.java
index 97926e3e4ca..df0c7252f2b 100644
--- a/Mage.Sets/src/mage/cards/m/Moonhold.java
+++ b/Mage.Sets/src/mage/cards/m/Moonhold.java
@@ -34,7 +34,7 @@ public final class Moonhold extends CardImpl {
// Target player can't play land cards this turn if {R} was spent to cast Moonhold and can't play creature cards this turn if {W} was spent to cast it.
ContinuousRuleModifyingEffect effect = new MoonholdEffect();
ContinuousRuleModifyingEffect effect2 = new MoonholdEffect2();
- effect.setText("Target player can't play lands this turn if {R} was spent to cast {this}");
+ effect.setText("Target player can't play lands this turn if {R} was spent to cast this spell");
effect2.setText("and can't cast creature spells this turn if {W} was spent to cast it.");
this.getSpellAbility().addEffect(new ConditionalContinuousRuleModifyingEffect(
effect,
diff --git a/Mage.Sets/src/mage/cards/m/MoonlitScavengers.java b/Mage.Sets/src/mage/cards/m/MoonlitScavengers.java
new file mode 100644
index 00000000000..e3a38722921
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MoonlitScavengers.java
@@ -0,0 +1,61 @@
+package mage.cards.m;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
+import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterArtifactOrEnchantmentPermanent;
+import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.target.common.TargetOpponentsCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class MoonlitScavengers extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterArtifactOrEnchantmentPermanent();
+
+ static {
+ filter.add(new ControllerPredicate(TargetController.YOU));
+ }
+
+ private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter);
+
+ public MoonlitScavengers(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}");
+
+ this.subtype.add(SubType.MERFOLK);
+ this.subtype.add(SubType.ROGUE);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(5);
+
+ // When Moonlit Scavengers enters the battlefield, if you control an artifact or enchantment, return target creature an opponent controls to its owner's hand.
+ Ability ability = new ConditionalInterveningIfTriggeredAbility(
+ new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect()), condition,
+ "When {this} enters the battlefield, if you control an artifact or enchantment, " +
+ "return target creature an opponent controls to its owner's hand."
+ );
+ ability.addTarget(new TargetOpponentsCreaturePermanent());
+ this.addAbility(ability);
+ }
+
+ private MoonlitScavengers(final MoonlitScavengers card) {
+ super(card);
+ }
+
+ @Override
+ public MoonlitScavengers copy() {
+ return new MoonlitScavengers(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MorgueTheft.java b/Mage.Sets/src/mage/cards/m/MorgueTheft.java
index d588c17c38c..0fc63ad40cf 100644
--- a/Mage.Sets/src/mage/cards/m/MorgueTheft.java
+++ b/Mage.Sets/src/mage/cards/m/MorgueTheft.java
@@ -1,4 +1,3 @@
-
package mage.cards.m;
import java.util.UUID;
@@ -9,7 +8,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TimingRule;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard;
/**
@@ -17,17 +16,16 @@ import mage.target.common.TargetCardInYourGraveyard;
* @author cbt33
*/
public final class MorgueTheft extends CardImpl {
-
- public MorgueTheft(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{B}");
+ public MorgueTheft(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}");
// Return target creature card from your graveyard to your hand.
this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect());
- this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard()));
+ this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE));
// Flashback {4}{B}
this.addAbility(new FlashbackAbility(new ManaCostsImpl("{4}{B}"), TimingRule.SORCERY));
-
+
}
public MorgueTheft(final MorgueTheft card) {
diff --git a/Mage.Sets/src/mage/cards/m/MortalCombat.java b/Mage.Sets/src/mage/cards/m/MortalCombat.java
index 4869fd235d9..eb3db1f6f43 100644
--- a/Mage.Sets/src/mage/cards/m/MortalCombat.java
+++ b/Mage.Sets/src/mage/cards/m/MortalCombat.java
@@ -1,4 +1,3 @@
-
package mage.cards.m;
import java.util.UUID;
@@ -11,7 +10,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
@@ -22,7 +21,7 @@ import mage.players.Player;
public final class MortalCombat extends CardImpl {
public MortalCombat(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}");
// At the beginning of your upkeep, if twenty or more creature cards are in your graveyard, you win the game.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
@@ -42,12 +41,10 @@ public final class MortalCombat extends CardImpl {
}
class TwentyGraveyardCreatureCondition implements Condition {
-
- private static final FilterCreatureCard filter = new FilterCreatureCard();
-
+
@Override
- public boolean apply(Game game, Ability source) {
+ public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
- return player != null && player.getGraveyard().count(filter, game) >= 20;
+ return player != null && player.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game) >= 20;
}
}
diff --git a/Mage.Sets/src/mage/cards/m/MtendaLion.java b/Mage.Sets/src/mage/cards/m/MtendaLion.java
new file mode 100644
index 00000000000..cdda0600843
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MtendaLion.java
@@ -0,0 +1,78 @@
+package mage.cards.m;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.costs.Cost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.PreventCombatDamageBySourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.game.Game;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class MtendaLion extends CardImpl {
+
+ public MtendaLion(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}");
+
+ this.subtype.add(SubType.CAT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(1);
+
+ // Whenever Mtenda Lion attacks, defending player may pay {U}. If that player does, prevent all combat damage that would be dealt by Mtenda Lion this turn.
+ this.addAbility(new AttacksTriggeredAbility(new MtendaLionEffect(), false));
+ }
+
+ private MtendaLion(final MtendaLion card) {
+ super(card);
+ }
+
+ @Override
+ public MtendaLion copy() {
+ return new MtendaLion(this);
+ }
+}
+
+class MtendaLionEffect extends OneShotEffect {
+
+ MtendaLionEffect() {
+ super(Outcome.Benefit);
+ staticText = "defending player may pay {U}. If that player does, " +
+ "prevent all combat damage that would be dealt by {this} this turn.";
+ }
+
+ private MtendaLionEffect(final MtendaLionEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public MtendaLionEffect copy() {
+ return new MtendaLionEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(game.getCombat().getDefendingPlayerId(source.getSourceId(), game));
+ if (player == null) {
+ return false;
+ }
+ Cost cost = new ManaCostsImpl("{U}");
+ if (!player.chooseUse(outcome, "Pay {U} to prevent damage?", source, game)
+ || !cost.pay(source, game, source.getSourceId(), player.getId(), false)) {
+ return false;
+ }
+ game.addEffect(new PreventCombatDamageBySourceEffect(Duration.EndOfTurn), source);
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/Mudslide.java b/Mage.Sets/src/mage/cards/m/Mudslide.java
index 6ea2392ef34..e100b8b43fb 100644
--- a/Mage.Sets/src/mage/cards/m/Mudslide.java
+++ b/Mage.Sets/src/mage/cards/m/Mudslide.java
@@ -41,7 +41,7 @@ public final class Mudslide extends CardImpl {
// Creatures without flying don't untap during their controllers' untap steps.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepAllEffect(Duration.WhileOnBattlefield, TargetController.ANY, filterCreature)));
- // At the beginning of each player's upkeep, that player may choose any number of tapped creatures without flying he or she controls and pay {2} for each creature chosen this way. If the player does, untap those creatures.
+ // At the beginning of each player's upkeep, that player may choose any number of tapped creatures without flying they control and pay {2} for each creature chosen this way. If the player does, untap those creatures.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new MudslideEffect(), TargetController.ANY, false));
}
@@ -66,7 +66,7 @@ class MudslideEffect extends OneShotEffect {
MudslideEffect() {
super(Outcome.Benefit);
- staticText = "that player may choose any number of tapped creatures without flying he or she controls and pay {2} for each creature chosen this way. If the player does, untap those creatures.";
+ staticText = "that player may choose any number of tapped creatures without flying they control and pay {2} for each creature chosen this way. If the player does, untap those creatures.";
}
MudslideEffect(MudslideEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/m/MurderOfCrows.java b/Mage.Sets/src/mage/cards/m/MurderOfCrows.java
index e583917511d..8b02356dc6b 100644
--- a/Mage.Sets/src/mage/cards/m/MurderOfCrows.java
+++ b/Mage.Sets/src/mage/cards/m/MurderOfCrows.java
@@ -64,7 +64,7 @@ class MurderOfCrowsEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
if (player != null && player.chooseUse(Outcome.DrawCard, "Do you wish to draw a card? If you do, discard a card.", source, game)) {
if (player.drawCards(1, game) > 0) {
- player.discard(1, source, game);
+ player.discard(1, false, source, game);
}
return true;
}
diff --git a/Mage.Sets/src/mage/cards/m/MurderousRider.java b/Mage.Sets/src/mage/cards/m/MurderousRider.java
new file mode 100644
index 00000000000..7e7864389f9
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MurderousRider.java
@@ -0,0 +1,54 @@
+package mage.cards.m;
+
+import mage.MageInt;
+import mage.abilities.common.DiesTriggeredAbility;
+import mage.abilities.effects.common.DestroyTargetEffect;
+import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
+import mage.abilities.keyword.LifelinkAbility;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.target.common.TargetCreatureOrPlaneswalker;
+import java.util.UUID;
+import mage.abilities.effects.common.PutOnLibrarySourceEffect;
+
+/**
+ * @author TheElk801
+ */
+public final class MurderousRider extends AdventureCard {
+
+ public MurderousRider(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.INSTANT}, "{1}{B}{B}", "Swift End", "{1}{B}{B}");
+
+ this.subtype.add(SubType.ZOMBIE);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // Lifelink
+ this.addAbility(LifelinkAbility.getInstance());
+
+ // When Murderous Rider dies, put it on the bottom of its owner's library.
+ this.addAbility(new DiesTriggeredAbility(new PutOnLibrarySourceEffect(
+ false, "put it on the bottom of its owner's library"
+ ), false));
+
+ // Swift End
+ // Destroy target creature or planeswalker. You lose 2 life.
+ this.getSpellCard().getSpellAbility().addEffect(new DestroyTargetEffect());
+ this.getSpellCard().getSpellAbility().addEffect(
+ new LoseLifeSourceControllerEffect(2).setText("You lose 2 life.")
+ );
+ this.getSpellCard().getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker());
+ }
+
+ private MurderousRider(final MurderousRider card) {
+ super(card);
+ }
+
+ @Override
+ public MurderousRider copy() {
+ return new MurderousRider(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MyriadLandscape.java b/Mage.Sets/src/mage/cards/m/MyriadLandscape.java
index be5c3e2e26c..a88e3285de0 100644
--- a/Mage.Sets/src/mage/cards/m/MyriadLandscape.java
+++ b/Mage.Sets/src/mage/cards/m/MyriadLandscape.java
@@ -88,8 +88,8 @@ class TargetCardInLibrarySharingLandType extends TargetCardInLibrary {
}
@Override
- public boolean canTarget(UUID id, Cards cards, Game game) {
- if (super.canTarget(id, cards, game)) {
+ public boolean canTarget(UUID playerId, UUID id, Ability source, Cards cards, Game game) {
+ if (super.canTarget(playerId, id, source, cards, game)) {
if (!getTargets().isEmpty()) {
// check if new target shares a Land Type
SubTypeList landTypes = new SubTypeList();
diff --git a/Mage.Sets/src/mage/cards/m/MysteriousPathlighter.java b/Mage.Sets/src/mage/cards/m/MysteriousPathlighter.java
new file mode 100644
index 00000000000..a9a8333706e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MysteriousPathlighter.java
@@ -0,0 +1,97 @@
+package mage.cards.m;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ReplacementEffectImpl;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.AdventureCard;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.game.Game;
+import mage.game.events.EntersTheBattlefieldEvent;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.PermanentCard;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class MysteriousPathlighter extends CardImpl {
+
+ public MysteriousPathlighter(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
+
+ this.subtype.add(SubType.FAERIE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Each creature you control that has an Adventure enters the battlefield with an additional +1/+1 counter on it.
+ this.addAbility(new SimpleStaticAbility(new MysteriousPathlighterEffect()));
+ }
+
+ private MysteriousPathlighter(final MysteriousPathlighter card) {
+ super(card);
+ }
+
+ @Override
+ public MysteriousPathlighter copy() {
+ return new MysteriousPathlighter(this);
+ }
+}
+
+class MysteriousPathlighterEffect extends ReplacementEffectImpl {
+
+ MysteriousPathlighterEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.BoostCreature);
+ this.staticText = "Each creature you control that has an Adventure " +
+ "enters the battlefield with an additional +1/+1 counter on it";
+ }
+
+ private MysteriousPathlighterEffect(MysteriousPathlighterEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget();
+ return permanent instanceof PermanentCard
+ && ((PermanentCard) permanent).getCard() instanceof AdventureCard
+ && permanent.isControlledBy(source.getControllerId())
+ && permanent.isCreature();
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return false;
+ }
+
+ @Override
+ public boolean replaceEvent(GameEvent event, Ability source, Game game) {
+ Permanent target = ((EntersTheBattlefieldEvent) event).getTarget();
+ if (target != null) {
+ target.addCounters(CounterType.P1P1.createInstance(), source, game, event.getAppliedEffects());
+ }
+ return false;
+ }
+
+ @Override
+ public MysteriousPathlighterEffect copy() {
+ return new MysteriousPathlighterEffect(this);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/m/MysticBarrier.java b/Mage.Sets/src/mage/cards/m/MysticBarrier.java
index a4cdd926392..91d724fe046 100644
--- a/Mage.Sets/src/mage/cards/m/MysticBarrier.java
+++ b/Mage.Sets/src/mage/cards/m/MysticBarrier.java
@@ -36,7 +36,7 @@ public final class MysticBarrier extends CardImpl {
new EntersBattlefieldTriggeredAbility(null, false),
new BeginningOfUpkeepTriggeredAbility(null, TargetController.YOU, false)));
- // Each player may attack only the opponent seated nearest him or her in the last chosen direction and planeswalkers controlled by that player.
+ // Each player may attack only the nearest opponent in the last chosen direction and planeswalkers controlled by that player.
this.addAbility(new SimpleStaticAbility(new MysticBarrierReplacementEffect()));
}
diff --git a/Mage.Sets/src/mage/cards/m/MysticSanctuary.java b/Mage.Sets/src/mage/cards/m/MysticSanctuary.java
new file mode 100644
index 00000000000..b01e015bd51
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MysticSanctuary.java
@@ -0,0 +1,75 @@
+package mage.cards.m;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.common.EntersBattlefieldUntappedTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.PutOnLibraryTargetEffect;
+import mage.abilities.effects.common.TapSourceEffect;
+import mage.abilities.mana.BlueManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.filter.FilterCard;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.common.FilterInstantOrSorceryCard;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.target.common.TargetCardInYourGraveyard;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class MysticSanctuary extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterControlledPermanent(SubType.ISLAND);
+ private static final FilterCard filter2
+ = new FilterInstantOrSorceryCard("instant or sorcery card from your graveyard");
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ }
+
+ private static final Condition condition
+ = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.FEWER_THAN, 3);
+
+ public MysticSanctuary(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ this.subtype.add(SubType.ISLAND);
+
+ // ({T}: Add {U}.)
+ this.addAbility(new BlueManaAbility());
+
+ // Mystic Sanctuary enters the battlefield tapped unless you control three or more other Islands.
+ this.addAbility(new EntersBattlefieldAbility(
+ new ConditionalOneShotEffect(new TapSourceEffect(), condition),
+ "tapped unless you control three or more other Islands"
+ ));
+
+ // When Mystic Sanctuary enters the battlefield untapped, you may put target instant or sorcery card from your graveyard on top of your library.
+ Ability ability = new EntersBattlefieldUntappedTriggeredAbility(
+ new PutOnLibraryTargetEffect(true)
+ .setText("put target instant or sorcery card from your graveyard on top of your library"),
+ true
+ );
+ ability.addTarget(new TargetCardInYourGraveyard(filter2));
+ this.addAbility(ability);
+ }
+
+ private MysticSanctuary(final MysticSanctuary card) {
+ super(card);
+ }
+
+ @Override
+ public MysticSanctuary copy() {
+ return new MysticSanctuary(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/m/MysticalDispute.java b/Mage.Sets/src/mage/cards/m/MysticalDispute.java
new file mode 100644
index 00000000000..f2c290d95e0
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/m/MysticalDispute.java
@@ -0,0 +1,73 @@
+package mage.cards.m;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.CounterUnlessPaysEffect;
+import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.stack.StackObject;
+import mage.target.Target;
+import mage.target.TargetSpell;
+
+import java.util.Collection;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class MysticalDispute extends CardImpl {
+
+ public MysticalDispute(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}");
+
+ // This spell costs {2} less to cast if it targets a blue spell.
+ this.addAbility(new SimpleStaticAbility(
+ Zone.STACK, new SpellCostReductionSourceEffect(2, MysticalDisputeCondition.instance)
+ ).setRuleAtTheTop(true));
+
+ // Counter target spell unless its controller pays {3}.
+ this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new GenericManaCost(3)));
+ this.getSpellAbility().addTarget(new TargetSpell());
+ }
+
+ private MysticalDispute(final MysticalDispute card) {
+ super(card);
+ }
+
+ @Override
+ public MysticalDispute copy() {
+ return new MysticalDispute(this);
+ }
+}
+
+enum MysticalDisputeCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ StackObject sourceSpell = game.getStack().getStackObject(source.getSourceId());
+ if (sourceSpell == null) {
+ return false;
+ }
+ return sourceSpell
+ .getStackAbility()
+ .getTargets()
+ .stream()
+ .map(Target::getTargets)
+ .flatMap(Collection::stream)
+ .map(game::getSpell)
+ .anyMatch(spell -> spell != null && spell.getColor(game).isBlue());
+ }
+
+ @Override
+ public String toString() {
+ return "it targets a blue spell";
+ }
+
+}
diff --git a/Mage.Sets/src/mage/cards/n/NafsAsp.java b/Mage.Sets/src/mage/cards/n/NafsAsp.java
index bb0e57b77d5..491122a928d 100644
--- a/Mage.Sets/src/mage/cards/n/NafsAsp.java
+++ b/Mage.Sets/src/mage/cards/n/NafsAsp.java
@@ -25,10 +25,10 @@ public final class NafsAsp extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(1);
- // Whenever Nafs Asp deals damage to a player, that player loses 1 life at the beginning of their next draw step unless he or she pays {1} before that draw step.
+ // Whenever Nafs Asp deals damage to a player, that player loses 1 life at the beginning of their next draw step unless they pay {1} before that draw step.
this.addAbility(new DealsDamageToAPlayerTriggeredAbility(new UnlessPaysDelayedEffect(
new ManaCostsImpl("{1}"), new LoseLifeTargetEffect(1), PhaseStep.DRAW, true,
- "that player loses 1 life at the beginning of their next draw step unless he or she pays {1} before that draw step."),
+ "that player loses 1 life at the beginning of their next draw step unless they pay {1} before that draw step."),
false, true));
}
diff --git a/Mage.Sets/src/mage/cards/n/NaturalBalance.java b/Mage.Sets/src/mage/cards/n/NaturalBalance.java
index ca4658a0531..1dfc2c3bc22 100644
--- a/Mage.Sets/src/mage/cards/n/NaturalBalance.java
+++ b/Mage.Sets/src/mage/cards/n/NaturalBalance.java
@@ -32,7 +32,7 @@ public final class NaturalBalance extends CardImpl {
public NaturalBalance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}{G}");
- // Each player who controls six or more lands chooses five lands he or she controls and sacrifices the rest. Each player who controls four or fewer lands may search their library for up to X basic land cards and put them onto the battlefield, where X is five minus the number of lands he or she controls. Then each player who searched their library this way shuffles it.
+ // Each player who controls six or more lands chooses five lands they control and sacrifices the rest. Each player who controls four or fewer lands may search their library for up to X basic land cards and put them onto the battlefield, where X is five minus the number of lands they control. Then each player who searched their library this way shuffles it.
this.getSpellAbility().addEffect(new NaturalBalanceEffect());
}
@@ -49,7 +49,7 @@ public final class NaturalBalance extends CardImpl {
public NaturalBalanceEffect() {
super(Outcome.PutCardInPlay);
- this.staticText = "Each player who controls six or more lands chooses five lands he or she controls and sacrifices the rest. Each player who controls four or fewer lands may search their library for up to X basic land cards and put them onto the battlefield, where X is five minus the number of lands he or she controls. Then each player who searched their library this way shuffles it.";
+ this.staticText = "Each player who controls six or more lands chooses five lands they control and sacrifices the rest. Each player who controls four or fewer lands may search their library for up to X basic land cards and put them onto the battlefield, where X is five minus the number of lands they control. Then each player who searched their library this way shuffles it.";
}
public NaturalBalanceEffect(final NaturalBalanceEffect effect) {
@@ -71,7 +71,7 @@ public final class NaturalBalance extends CardImpl {
if (player != null) {
int landCount = game.getBattlefield().countAll(new FilterControlledLandPermanent(), player.getId(), game);
if (landCount > 5) {
- // chooses five lands he or she controls and sacrifices the rest
+ // chooses five lands they control and sacrifices the rest
TargetControlledPermanent target = new TargetControlledPermanent(5, 5, new FilterControlledLandPermanent("lands to keep"), true);
if (target.choose(Outcome.Sacrifice, player.getId(), source.getSourceId(), game)) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterLandPermanent(), player.getId(), game)) {
diff --git a/Mage.Sets/src/mage/cards/n/NaturesWrath.java b/Mage.Sets/src/mage/cards/n/NaturesWrath.java
index 8f3e01cf8c7..6c2f7ad6ffe 100644
--- a/Mage.Sets/src/mage/cards/n/NaturesWrath.java
+++ b/Mage.Sets/src/mage/cards/n/NaturesWrath.java
@@ -43,21 +43,21 @@ public final class NaturesWrath extends CardImpl {
// At the beginning of your upkeep, sacrifice Nature's Wrath unless you pay {G}.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl("{G}")), TargetController.YOU, false));
- // Whenever a player puts an Island or blue permanent onto the battlefield, he or she sacrifices an Island or blue permanent.
+ // Whenever a player puts an Island or blue permanent onto the battlefield, they sacrifice an Island or blue permanent.
this.addAbility(new EntersBattlefieldAllTriggeredAbility(
Zone.BATTLEFIELD,
new SacrificeEffect(filterBlue, 1, ""),
filterBlue,
false, SetTargetPointer.PLAYER,
- "Whenever a player puts an Island or blue permanent onto the battlefield, he or she sacrifices an Island or blue permanent."));
+ "Whenever a player puts an Island or blue permanent onto the battlefield, they sacrifice an Island or blue permanent."));
- // Whenever a player puts a Swamp or black permanent onto the battlefield, he or she sacrifices a Swamp or black permanent.
+ // Whenever a player puts a Swamp or black permanent onto the battlefield, they sacrifice a Swamp or black permanent.
this.addAbility(new EntersBattlefieldAllTriggeredAbility(
Zone.BATTLEFIELD,
new SacrificeEffect(filterBlack, 1, ""),
filterBlack,
false, SetTargetPointer.PLAYER,
- "Whenever a player puts a Swamp or black permanent onto the battlefield, he or she sacrifices a Swamp or black permanent."));
+ "Whenever a player puts a Swamp or black permanent onto the battlefield, they sacrifice a Swamp or black permanent."));
}
public NaturesWrath(final NaturesWrath card) {
diff --git a/Mage.Sets/src/mage/cards/n/NecromancersCovenant.java b/Mage.Sets/src/mage/cards/n/NecromancersCovenant.java
index 67b53399082..88ec3503d56 100644
--- a/Mage.Sets/src/mage/cards/n/NecromancersCovenant.java
+++ b/Mage.Sets/src/mage/cards/n/NecromancersCovenant.java
@@ -1,4 +1,3 @@
-
package mage.cards.n;
import java.util.UUID;
@@ -12,8 +11,8 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledCreaturePermanent;
-import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.game.permanent.token.ZombieToken;
@@ -33,7 +32,7 @@ public final class NecromancersCovenant extends CardImpl {
}
public NecromancersCovenant(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}{B}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{B}{B}");
// When Necromancer's Covenant enters the battlefield, exile all creature cards from target player's graveyard, then create a 2/2 black Zombie creature token for each card exiled this way.
Ability ability = new EntersBattlefieldTriggeredAbility(new NecromancersConvenantEffect(), false);
@@ -72,7 +71,7 @@ class NecromancersConvenantEffect extends OneShotEffect {
return false;
}
int count = 0;
- for (Card card : player.getGraveyard().getCards(new FilterCreatureCard(), game)) {
+ for (Card card : player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game)) {
if (card.moveToExile(source.getSourceId(), "Necromancer Covenant", source.getSourceId(), game)) {
count += 1;
}
diff --git a/Mage.Sets/src/mage/cards/n/NecromancersStockpile.java b/Mage.Sets/src/mage/cards/n/NecromancersStockpile.java
index 640496dabca..13f6a4d93af 100644
--- a/Mage.Sets/src/mage/cards/n/NecromancersStockpile.java
+++ b/Mage.Sets/src/mage/cards/n/NecromancersStockpile.java
@@ -1,4 +1,3 @@
-
package mage.cards.n;
import java.util.UUID;
@@ -17,7 +16,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.token.ZombieToken;
import mage.players.Player;
@@ -29,12 +28,12 @@ import mage.target.common.TargetCardInHand;
public final class NecromancersStockpile extends CardImpl {
public NecromancersStockpile(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}");
// {1}{B}, Discard a creature card: Draw a card.
// If the discarded card was a Zombie card, create a tapped 2/2 black Zombie creature token.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{1}{B}"));
- ability.addCost(new NecromancersStockpileDiscardTargetCost(new TargetCardInHand(new FilterCreatureCard())));
+ ability.addCost(new NecromancersStockpileDiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE)));
ability.addEffect(new NecromancersStockpilePutTokenEffect());
this.addAbility(ability);
}
@@ -67,7 +66,7 @@ class NecromancersStockpileDiscardTargetCost extends CostImpl {
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
if (targets.choose(Outcome.Discard, controllerId, sourceId, game)) {
Player player = game.getPlayer(controllerId);
- if(player != null) {
+ if (player != null) {
for (UUID targetId : targets.get(0).getTargets()) {
Card card = player.getHand().get(targetId, game);
if (card == null) {
diff --git a/Mage.Sets/src/mage/cards/n/NekusarTheMindrazer.java b/Mage.Sets/src/mage/cards/n/NekusarTheMindrazer.java
index 6c98f0d6f1e..c6dd30f6117 100644
--- a/Mage.Sets/src/mage/cards/n/NekusarTheMindrazer.java
+++ b/Mage.Sets/src/mage/cards/n/NekusarTheMindrazer.java
@@ -35,7 +35,7 @@ public final class NekusarTheMindrazer extends CardImpl {
effect.setText("that player draws an additional card");
this.addAbility(new BeginningOfDrawTriggeredAbility(effect , TargetController.ANY, false));
// Whenever an opponent draws a card, Nekusar, the Mindrazer deals 1 damage to that player.
- this.addAbility(new DrawCardOpponentTriggeredAbility(new DamageTargetEffect(1, true, "him or her"), false, true));
+ this.addAbility(new DrawCardOpponentTriggeredAbility(new DamageTargetEffect(1, true, "that player"), false, true));
}
public NekusarTheMindrazer(final NekusarTheMindrazer card) {
diff --git a/Mage.Sets/src/mage/cards/n/NemesisOfMortals.java b/Mage.Sets/src/mage/cards/n/NemesisOfMortals.java
index 0cab56e3fe8..45bcc9b02d3 100644
--- a/Mage.Sets/src/mage/cards/n/NemesisOfMortals.java
+++ b/Mage.Sets/src/mage/cards/n/NemesisOfMortals.java
@@ -1,6 +1,6 @@
-
package mage.cards.n;
+import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
@@ -12,13 +12,10 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.players.Player;
import mage.util.CardUtil;
-import java.util.UUID;
-
/**
* @author LevelX2
*/
@@ -32,7 +29,7 @@ public final class NemesisOfMortals extends CardImpl {
this.toughness = new MageInt(5);
// Nemesis of Mortals costs {1} less to cast for each creature card in your graveyard.
- Ability ability = new SimpleStaticAbility(Zone.ALL, new SourceCostReductionForEachCardInGraveyardEffect(new FilterCreatureCard()));
+ Ability ability = new SimpleStaticAbility(Zone.ALL, new SourceCostReductionForEachCardInGraveyardEffect(StaticFilters.FILTER_CARD_CREATURE));
ability.setRuleAtTheTop(true);
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/n/NetherSpirit.java b/Mage.Sets/src/mage/cards/n/NetherSpirit.java
index 392754dc55e..edfe391c9b4 100644
--- a/Mage.Sets/src/mage/cards/n/NetherSpirit.java
+++ b/Mage.Sets/src/mage/cards/n/NetherSpirit.java
@@ -1,4 +1,3 @@
-
package mage.cards.n;
import java.util.UUID;
@@ -16,7 +15,7 @@ import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
@@ -27,7 +26,7 @@ import mage.players.Player;
public final class NetherSpirit extends CardImpl {
public NetherSpirit(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}");
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(2);
@@ -56,7 +55,7 @@ class NetherSpiritCondition implements Condition {
if (player != null) {
Card card = game.getCard(source.getSourceId());
if (card != null) {
- return player.getGraveyard().contains(card.getId()) && player.getGraveyard().count(new FilterCreatureCard(), game) == 1;
+ return player.getGraveyard().contains(card.getId()) && player.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game) == 1;
}
}
return false;
diff --git a/Mage.Sets/src/mage/cards/n/NetherbornPhalanx.java b/Mage.Sets/src/mage/cards/n/NetherbornPhalanx.java
index 3f39e60e74d..91570504ea8 100644
--- a/Mage.Sets/src/mage/cards/n/NetherbornPhalanx.java
+++ b/Mage.Sets/src/mage/cards/n/NetherbornPhalanx.java
@@ -28,7 +28,7 @@ public final class NetherbornPhalanx extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(4);
- // When Netherborn Phalanx enters the battlefield, each opponent loses 1 life for each creature he or she controls.
+ // When Netherborn Phalanx enters the battlefield, each opponent loses 1 life for each creature they control.
Ability ability = new EntersBattlefieldTriggeredAbility(new NetherbornPhalanxEffect());
this.addAbility(ability);
@@ -50,7 +50,7 @@ class NetherbornPhalanxEffect extends OneShotEffect {
NetherbornPhalanxEffect() {
super(Outcome.Sacrifice);
- this.staticText = "each opponent loses 1 life for each creature he or she controls";
+ this.staticText = "each opponent loses 1 life for each creature they control";
}
NetherbornPhalanxEffect(final NetherbornPhalanxEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/n/NewPerspectives.java b/Mage.Sets/src/mage/cards/n/NewPerspectives.java
index 6222f4187a7..91855cc381a 100644
--- a/Mage.Sets/src/mage/cards/n/NewPerspectives.java
+++ b/Mage.Sets/src/mage/cards/n/NewPerspectives.java
@@ -1,9 +1,7 @@
-
package mage.cards.n;
import java.util.UUID;
import mage.abilities.Ability;
-import mage.abilities.ActivatedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.CyclingDiscardCost;
@@ -70,7 +68,8 @@ class NewPerspectivesCostModificationEffect extends CostModificationEffectImpl {
public boolean apply(Game game, Ability source, Ability abilityToModify) {
Player controller = game.getPlayer(abilityToModify.getControllerId());
if (controller != null) {
- if ((abilityToModify instanceof ActivatedAbility && ((ActivatedAbility) abilityToModify).isCheckPlayableMode()) || controller.chooseUse(Outcome.PlayForFree, "Pay {0} to cycle?", source, game)) {
+ if (game.inCheckPlayableState()
+ || controller.chooseUse(Outcome.PlayForFree, "Pay {0} to cycle?", source, game)) {
abilityToModify.getCosts().clear();
abilityToModify.getManaCostsToPay().clear();
abilityToModify.getCosts().add(new CyclingDiscardCost());
diff --git a/Mage.Sets/src/mage/cards/n/NicolBolasGodPharaoh.java b/Mage.Sets/src/mage/cards/n/NicolBolasGodPharaoh.java
index dd4859ee9af..186e337692a 100644
--- a/Mage.Sets/src/mage/cards/n/NicolBolasGodPharaoh.java
+++ b/Mage.Sets/src/mage/cards/n/NicolBolasGodPharaoh.java
@@ -45,7 +45,7 @@ public final class NicolBolasGodPharaoh extends CardImpl {
this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(7));
- // +2: Target opponent exiles cards from the top of their library until he or she exiles a nonland card. Until end of turn, you may cast that card without paying its mana cost.
+ // +2: Target opponent exiles cards from the top of their library until they exile a nonland card. Until end of turn, you may cast that card without paying its mana cost.
LoyaltyAbility ability = new LoyaltyAbility(new NicolBolasGodPharaohPlusTwoEffect(), 2);
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
@@ -98,11 +98,17 @@ class NicolBolasGodPharaohPlusOneEffect extends OneShotEffect {
Player opponent = game.getPlayer(opponentId);
if (opponent != null) {
int numberOfCardsToExile = Math.min(2, opponent.getHand().size());
- Target target = new TargetCardInHand(numberOfCardsToExile, new FilterCard());
- target.setRequired(true);
- if (opponent.chooseTarget(Outcome.Exile, target, source, game)) {
- Cards cards = new CardsImpl(target.getTargets());
- cardsToExile.put(opponentId, cards);
+ if(numberOfCardsToExile > 0) {
+ Target target = new TargetCardInHand(numberOfCardsToExile, new FilterCard());
+ target.setRequired(true);
+ if (opponent.chooseTarget(Outcome.Exile, target, source, game)) {
+ Cards cards = new CardsImpl(target.getTargets());
+ cardsToExile.put(opponentId, cards);
+ }
+ }
+ else
+ {
+ cardsToExile.put(opponentId, new CardsImpl());
}
}
}
@@ -125,7 +131,7 @@ class NicolBolasGodPharaohPlusTwoEffect extends OneShotEffect {
public NicolBolasGodPharaohPlusTwoEffect() {
super(Outcome.Detriment);
this.staticText = "Target opponent exiles cards from the top of their "
- + "library until he or she exiles a nonland card. Until end of turn, "
+ + "library until they exile a nonland card. Until end of turn, "
+ "you may cast that card without paying its mana cost";
}
diff --git a/Mage.Sets/src/mage/cards/n/Nighthowler.java b/Mage.Sets/src/mage/cards/n/Nighthowler.java
index 849ef4a8b6e..1176375c2ad 100644
--- a/Mage.Sets/src/mage/cards/n/Nighthowler.java
+++ b/Mage.Sets/src/mage/cards/n/Nighthowler.java
@@ -1,4 +1,3 @@
-
package mage.cards.n;
import java.util.UUID;
@@ -14,10 +13,10 @@ import mage.abilities.keyword.BestowAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
+import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -26,7 +25,7 @@ import mage.filter.common.FilterCreatureCard;
public final class Nighthowler extends CardImpl {
public Nighthowler(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{1}{B}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{B}{B}");
this.subtype.add(SubType.HORROR);
this.power = new MageInt(0);
@@ -35,7 +34,7 @@ public final class Nighthowler extends CardImpl {
// Bestow {2}{B}{B}
this.addAbility(new BestowAbility(this, "{2}{B}{B}"));
// Nighthowler and enchanted creature each get +X/+X, where X is the number of creature cards in all graveyards.
- DynamicValue graveCreatures = new CardsInAllGraveyardsCount(new FilterCreatureCard());
+ DynamicValue graveCreatures = new CardsInAllGraveyardsCount(StaticFilters.FILTER_CARD_CREATURE);
Effect effect = new BoostSourceEffect(graveCreatures, graveCreatures, Duration.WhileOnBattlefield);
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
effect = new BoostEnchantedEffect(graveCreatures, graveCreatures, Duration.WhileOnBattlefield);
diff --git a/Mage.Sets/src/mage/cards/n/NissaSageAnimist.java b/Mage.Sets/src/mage/cards/n/NissaSageAnimist.java
index 5940a4b0ac9..b64572e12c7 100644
--- a/Mage.Sets/src/mage/cards/n/NissaSageAnimist.java
+++ b/Mage.Sets/src/mage/cards/n/NissaSageAnimist.java
@@ -1,6 +1,6 @@
-
package mage.cards.n;
+import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
@@ -9,6 +9,7 @@ import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.UntapTargetEffect;
+import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -18,10 +19,10 @@ import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.NissaSageAnimistToken;
+import mage.game.permanent.token.custom.CreatureToken;
import mage.players.Player;
import mage.target.common.TargetLandPermanent;
-
-import java.util.UUID;
+import mage.target.targetpointer.FixedTarget;
/**
*
@@ -48,7 +49,7 @@ public final class NissaSageAnimist extends CardImpl {
// -7: Untap up to six target lands. They become 6/6 Elemental creatures. They're still lands.
Ability ability = new LoyaltyAbility(new UntapTargetEffect(), -7);
ability.addTarget(new TargetLandPermanent(0, 6, StaticFilters.FILTER_LANDS, false));
- ability.addEffect(new NissaSageAnimistMinusSevenEffect());
+ ability.addEffect(new NissaSageAnimistMinusAnimateEffect());
this.addAbility(ability);
}
@@ -98,52 +99,82 @@ class NissaSageAnimistPlusOneEffect extends OneShotEffect {
}
}
-class NissaSageAnimistMinusSevenEffect extends ContinuousEffectImpl {
+class NissaSageAnimistMinusAnimateEffect extends OneShotEffect {
- NissaSageAnimistMinusSevenEffect() {
- super(Duration.EndOfGame, Outcome.BecomeCreature);
+ public NissaSageAnimistMinusAnimateEffect() {
+ super(Outcome.BecomeCreature);
this.staticText = "They become 6/6 Elemental creatures. They're still lands";
}
- NissaSageAnimistMinusSevenEffect(final NissaSageAnimistMinusSevenEffect effect) {
+ public NissaSageAnimistMinusAnimateEffect(final NissaSageAnimistMinusAnimateEffect effect) {
super(effect);
}
@Override
- public NissaSageAnimistMinusSevenEffect copy() {
- return new NissaSageAnimistMinusSevenEffect(this);
+ public NissaSageAnimistMinusAnimateEffect copy() {
+ return new NissaSageAnimistMinusAnimateEffect(this);
}
@Override
- public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
+ public boolean apply(Game game, Ability source) {
for (UUID permanentId : this.getTargetPointer().getTargets(game, source)) {
Permanent permanent = game.getPermanent(permanentId);
if (permanent != null) {
- switch (layer) {
- case TypeChangingEffects_4:
- permanent.addCardType(CardType.CREATURE);
- if (!permanent.hasSubtype(SubType.ELEMENTAL, game)) {
- permanent.getSubtype(game).add(SubType.ELEMENTAL);
- }
- break;
- case PTChangingEffects_7:
- if (sublayer == SubLayer.SetPT_7b) {
- permanent.getToughness().setValue(6);
- permanent.getPower().setValue(6);
- }
- }
+ ContinuousEffectImpl effect = new BecomesCreatureTargetEffect(new CreatureToken(6, 6, "", SubType.ELEMENTAL), false, true, Duration.Custom);
+ effect.setTargetPointer(new FixedTarget(permanent, game));
+ game.addEffect(effect, source);
}
}
return true;
}
- @Override
- public boolean apply(Game game, Ability source) {
- return false;
- }
-
- @Override
- public boolean hasLayer(Layer layer) {
- return layer == Layer.TypeChangingEffects_4 || layer == Layer.PTChangingEffects_7;
- }
+// class NissaSageAnimistMinusSevenEffect extends ContinuousEffectImpl {
+//
+// NissaSageAnimistMinusSevenEffect() {
+// super(Duration.EndOfGame, Outcome.BecomeCreature);
+// this.staticText = "They become 6/6 Elemental creatures. They're still lands";
+// }
+//
+// NissaSageAnimistMinusSevenEffect(final NissaSageAnimistMinusSevenEffect effect) {
+// super(effect);
+// }
+//
+// @Override
+// public NissaSageAnimistMinusSevenEffect copy() {
+// return new NissaSageAnimistMinusSevenEffect(this);
+// }
+//
+// @Override
+// public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
+// for (UUID permanentId : this.getTargetPointer().getTargets(game, source)) {
+// Permanent permanent = game.getPermanent(permanentId);
+// if (permanent != null) {
+// switch (layer) {
+// case TypeChangingEffects_4:
+// permanent.addCardType(CardType.CREATURE);
+// if (!permanent.hasSubtype(SubType.ELEMENTAL, game)) {
+// permanent.getSubtype(game).add(SubType.ELEMENTAL);
+// }
+// break;
+// case PTChangingEffects_7:
+// if (sublayer == SubLayer.SetPT_7b) {
+// permanent.getToughness().setValue(6);
+// permanent.getPower().setValue(6);
+// }
+// }
+// }
+// }
+// return true;
+// }
+//
+// @Override
+// public boolean apply(Game game, Ability source) {
+// return false;
+// }
+//
+// @Override
+// public boolean hasLayer(Layer layer) {
+// return layer == Layer.TypeChangingEffects_4 || layer == Layer.PTChangingEffects_7;
+// }
+// }
}
diff --git a/Mage.Sets/src/mage/cards/n/NissasEncouragement.java b/Mage.Sets/src/mage/cards/n/NissasEncouragement.java
index a94f7703856..63466a9dda1 100644
--- a/Mage.Sets/src/mage/cards/n/NissasEncouragement.java
+++ b/Mage.Sets/src/mage/cards/n/NissasEncouragement.java
@@ -1,15 +1,8 @@
-
package mage.cards.n;
-import java.util.HashMap;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
-import mage.cards.Card;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-import mage.cards.Cards;
-import mage.cards.CardsImpl;
+import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
@@ -21,8 +14,10 @@ import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary;
+import java.util.HashMap;
+import java.util.UUID;
+
/**
- *
* @author spjspj
*/
public final class NissasEncouragement extends CardImpl {
@@ -89,8 +84,8 @@ class NissasEncouragementEffect extends OneShotEffect {
foundCards.put("Brambleweft Behemoth", 0);
foundCards.put("Nissa, Genesis Mage", 0);
Cards cards = new CardsImpl();
-
- if (!target.getTargets().isEmpty()) {
+
+ if (!target.getTargets().isEmpty()) {
for (UUID cardId : target.getTargets()) {
Card card = player.getLibrary().remove(cardId, game);
@@ -120,7 +115,7 @@ class NissasEncouragementEffect extends OneShotEffect {
}
}
}
-
+
if (!cards.isEmpty()) {
player.revealCards(sourceCard.getIdName(), cards, game);
player.moveCards(cards, Zone.HAND, source, game);
@@ -149,7 +144,7 @@ class NissasEncouragementTarget extends TargetCardInLibrary {
}
@Override
- public boolean canTarget(UUID id, Cards cards, Game game) {
+ public boolean canTarget(UUID playerId, UUID id, Ability source, Cards cards, Game game) {
Card card = cards.get(id, game);
if (card != null) {
for (UUID targetId : this.getTargets()) {
@@ -158,7 +153,7 @@ class NissasEncouragementTarget extends TargetCardInLibrary {
return false;
}
}
- return filter.match(card, game);
+ return filter.match(card, playerId, game);
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/n/NivMizzetReborn.java b/Mage.Sets/src/mage/cards/n/NivMizzetReborn.java
index fe55aa3aae4..c55256fafcd 100644
--- a/Mage.Sets/src/mage/cards/n/NivMizzetReborn.java
+++ b/Mage.Sets/src/mage/cards/n/NivMizzetReborn.java
@@ -155,7 +155,7 @@ class NivMizzetRebornEffect extends OneShotEffect {
player.putCardsOnBottomOfLibrary(cards, game, source, false);
if (player.moveCards(cards2, Zone.HAND, source, game)) {
for (Card card : cards2.getCards(game)) {
- game.informPlayers(player.getName() + " chose " + card.getName() + " and put it into his or her hand.");
+ game.informPlayers(player.getName() + " chose " + card.getName() + " and put it into their hand.");
}
}
return true;
diff --git a/Mage.Sets/src/mage/cards/n/NotOfThisWorld.java b/Mage.Sets/src/mage/cards/n/NotOfThisWorld.java
index 740bd42953c..b3d50c71da4 100644
--- a/Mage.Sets/src/mage/cards/n/NotOfThisWorld.java
+++ b/Mage.Sets/src/mage/cards/n/NotOfThisWorld.java
@@ -1,33 +1,30 @@
-
package mage.cards.n;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.UUID;
import mage.abilities.Ability;
+import mage.abilities.Mode;
+import mage.abilities.Modes;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.effects.common.CounterTargetEffect;
import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.ComparisonType;
-import mage.constants.TargetController;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.filter.Filter;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.PowerPredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
-import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.game.stack.StackAbility;
import mage.game.stack.StackObject;
import mage.target.Target;
import mage.target.TargetObject;
-import mage.target.Targets;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
/**
* @author Rafbill
@@ -39,14 +36,14 @@ public final class NotOfThisWorld extends CardImpl {
this.subtype.add(SubType.ELDRAZI);
// Counter target spell or ability that targets a permanent you control.
- this.getSpellAbility().addTarget(
- new TargetStackObjectTargetingControlledPermanent());
+ this.getSpellAbility().addTarget(new TargetStackObjectTargetingControlledPermanent());
this.getSpellAbility().addEffect(new CounterTargetEffect());
+
// Not of This World costs {7} less to cast if it targets a spell or ability that targets a creature you control with power 7 or greater.
this.addAbility(new SimpleStaticAbility(Zone.STACK, new SpellCostReductionSourceEffect(7, NotOfThisWorldCondition.instance)));
}
- public NotOfThisWorld(final NotOfThisWorld card) {
+ private NotOfThisWorld(final NotOfThisWorld card) {
super(card);
}
@@ -58,14 +55,14 @@ public final class NotOfThisWorld extends CardImpl {
class TargetStackObjectTargetingControlledPermanent extends TargetObject {
- public TargetStackObjectTargetingControlledPermanent() {
+ TargetStackObjectTargetingControlledPermanent() {
this.minNumberOfTargets = 1;
this.maxNumberOfTargets = 1;
this.zone = Zone.STACK;
this.targetName = "spell or ability that targets a permanent you control";
}
- public TargetStackObjectTargetingControlledPermanent(final TargetStackObjectTargetingControlledPermanent target) {
+ private TargetStackObjectTargetingControlledPermanent(final TargetStackObjectTargetingControlledPermanent target) {
super(target);
}
@@ -87,22 +84,20 @@ class TargetStackObjectTargetingControlledPermanent extends TargetObject {
@Override
public boolean canChoose(UUID sourceControllerId, Game game) {
- for (StackObject stackObject : game.getStack()) {
- if ((stackObject instanceof Spell) || (stackObject instanceof StackAbility)) {
- Targets objectTargets = stackObject.getStackAbility().getTargets();
- if (!objectTargets.isEmpty()) {
- for (Target target : objectTargets) {
- for (UUID targetId : target.getTargets()) {
- Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId);
- if (targetedPermanent != null && targetedPermanent.isControlledBy(sourceControllerId)) {
- return true;
- }
- }
- }
- }
- }
- }
- return false;
+ return game.getStack()
+ .stream()
+ .filter(stackObject -> stackObject instanceof Spell || stackObject instanceof StackAbility)
+ .map(StackObject::getStackAbility)
+ .map(Ability::getModes)
+ .map(Modes::values)
+ .flatMap(Collection::stream)
+ .map(Mode::getTargets)
+ .flatMap(Collection::stream)
+ .filter(target -> !target.isNotTarget())
+ .map(Target::getTargets)
+ .flatMap(Collection::stream)
+ .map(game::getPermanentOrLKIBattlefield)
+ .anyMatch(permanent -> permanent != null && permanent.isControlledBy(sourceControllerId));
}
@Override
@@ -114,21 +109,26 @@ class TargetStackObjectTargetingControlledPermanent extends TargetObject {
@Override
public Set possibleTargets(UUID sourceControllerId, Game game) {
Set possibleTargets = new HashSet<>();
- for (StackObject stackObject : game.getStack()) {
- if ((stackObject instanceof Spell) || (stackObject instanceof StackAbility)) {
- Targets objectTargets = stackObject.getStackAbility().getTargets();
- if (!objectTargets.isEmpty()) {
- for (Target target : objectTargets) {
- for (UUID targetId : target.getTargets()) {
- Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId);
- if (targetedPermanent != null && targetedPermanent.isControlledBy(sourceControllerId)) {
- possibleTargets.add(stackObject.getId());
- }
- }
- }
- }
+ game.getStack().stream().forEach(stackObject -> {
+ if (!(stackObject instanceof Spell || stackObject instanceof StackAbility)) {
+ return;
}
- }
+ boolean flag = stackObject
+ .getStackAbility()
+ .getModes()
+ .values()
+ .stream()
+ .map(Mode::getTargets)
+ .flatMap(Collection::stream)
+ .filter(target -> !target.isNotTarget())
+ .map(Target::getTargets)
+ .flatMap(Collection::stream)
+ .map(game::getPermanentOrLKIBattlefield)
+ .anyMatch(permanent -> permanent != null && permanent.isControlledBy(sourceControllerId));
+ if (flag) {
+ possibleTargets.add(stackObject.getId());
+ }
+ });
return possibleTargets;
}
@@ -140,8 +140,9 @@ class TargetStackObjectTargetingControlledPermanent extends TargetObject {
}
enum NotOfThisWorldCondition implements Condition {
+
instance;
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control with power 7 or greater");
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
static {
filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 6));
@@ -149,24 +150,30 @@ enum NotOfThisWorldCondition implements Condition {
}
-
@Override
public boolean apply(Game game, Ability source) {
StackObject sourceSpell = game.getStack().getStackObject(source.getSourceId());
- if (sourceSpell != null && sourceSpell.getStackAbility().getTargets().isChosen()) {
- StackObject objectToCounter = game.getStack().getStackObject(sourceSpell.getStackAbility().getTargets().getFirstTarget());
- if (objectToCounter != null) {
- for (Target target : objectToCounter.getStackAbility().getTargets()) {
- for (UUID targetId : target.getTargets()) {
- Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId);
- if (targetedPermanent != null && filter.match(targetedPermanent, sourceSpell.getSourceId(), sourceSpell.getControllerId(), game)) {
- return true;
- }
- }
- }
- }
+ if (sourceSpell == null || !sourceSpell.getStackAbility().getTargets().isChosen()) {
+ return false;
}
- return false;
+ StackObject objectToCounter = game.getStack().getStackObject(sourceSpell.getStackAbility().getTargets().getFirstTarget());
+ if (objectToCounter == null) {
+ return false;
+ }
+ return objectToCounter
+ .getStackAbility()
+ .getModes()
+ .values()
+ .stream()
+ .map(Mode::getTargets)
+ .flatMap(Collection::stream)
+ .filter(target -> !target.isNotTarget())
+ .map(Target::getTargets)
+ .flatMap(Collection::stream)
+ .map(game::getPermanentOrLKIBattlefield)
+ .anyMatch(permanent -> permanent != null && filter.match(
+ permanent, sourceSpell.getSourceId(), sourceSpell.getControllerId(), game
+ ));
}
@Override
diff --git a/Mage.Sets/src/mage/cards/n/NotionThief.java b/Mage.Sets/src/mage/cards/n/NotionThief.java
index 75626aeb1ac..79b0045f7fd 100644
--- a/Mage.Sets/src/mage/cards/n/NotionThief.java
+++ b/Mage.Sets/src/mage/cards/n/NotionThief.java
@@ -36,7 +36,7 @@ public final class NotionThief extends CardImpl {
// Flash
this.addAbility(FlashAbility.getInstance());
- // If an opponent would draw a card except the first one he or she draws in each of their draw steps, instead that player skips that draw and you draw a card.
+ // If an opponent would draw a card except the first one they draw in each of their draw steps, instead that player skips that draw and you draw a card.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new NotionThiefReplacementEffect()), new CardsDrawnDuringDrawStepWatcher());
}
@@ -55,7 +55,7 @@ class NotionThiefReplacementEffect extends ReplacementEffectImpl {
public NotionThiefReplacementEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit);
- staticText = "If an opponent would draw a card except the first one he or she draws in each of their draw steps, instead that player skips that draw and you draw a card";
+ staticText = "If an opponent would draw a card except the first one they draw in each of their draw steps, instead that player skips that draw and you draw a card";
}
public NotionThiefReplacementEffect(final NotionThiefReplacementEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/n/NykthosShrineToNyx.java b/Mage.Sets/src/mage/cards/n/NykthosShrineToNyx.java
index b36a2111d7f..3e288bee9c4 100644
--- a/Mage.Sets/src/mage/cards/n/NykthosShrineToNyx.java
+++ b/Mage.Sets/src/mage/cards/n/NykthosShrineToNyx.java
@@ -1,8 +1,5 @@
package mage.cards.n;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.costs.common.TapSourceCost;
@@ -15,14 +12,17 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceColor;
import mage.constants.CardType;
-import mage.constants.ColoredManaSymbol;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
/**
- *
* @author LevelX2
*/
public final class NykthosShrineToNyx extends CardImpl {
@@ -33,12 +33,12 @@ public final class NykthosShrineToNyx extends CardImpl {
// {T}: Add {C}.
this.addAbility(new ColorlessManaAbility());
+
// {2}, {T}: Choose a color. Add an amount of mana of that color equal to your devotion to that color.
- Ability ability = new NykthosShrineToNyxManaAbility();
- this.addAbility(ability);
+ this.addAbility(new NykthosShrineToNyxManaAbility());
}
- public NykthosShrineToNyx(final NykthosShrineToNyx card) {
+ private NykthosShrineToNyx(final NykthosShrineToNyx card) {
super(card);
}
@@ -50,12 +50,17 @@ public final class NykthosShrineToNyx extends CardImpl {
class NykthosShrineToNyxManaAbility extends ActivatedManaAbilityImpl {
- public NykthosShrineToNyxManaAbility() {
+ NykthosShrineToNyxManaAbility() {
super(Zone.BATTLEFIELD, new NykthosDynamicManaEffect(), new GenericManaCost(2));
this.addCost(new TapSourceCost());
+ this.addHint(DevotionCount.W.getHint());
+ this.addHint(DevotionCount.U.getHint());
+ this.addHint(DevotionCount.B.getHint());
+ this.addHint(DevotionCount.R.getHint());
+ this.addHint(DevotionCount.G.getHint());
}
- public NykthosShrineToNyxManaAbility(final NykthosShrineToNyxManaAbility ability) {
+ private NykthosShrineToNyxManaAbility(final NykthosShrineToNyxManaAbility ability) {
super(ability);
}
@@ -67,21 +72,22 @@ class NykthosShrineToNyxManaAbility extends ActivatedManaAbilityImpl {
@Override
public List getNetMana(Game game) {
ArrayList netManaCopy = new ArrayList<>();
- if (game != null) {
- netManaCopy.addAll(((ManaEffect) this.getEffects().get(0)).getNetMana(game, this));
+ if (game == null) {
+ return netManaCopy;
}
+ netManaCopy.addAll(((ManaEffect) this.getEffects().get(0)).getNetMana(game, this));
return netManaCopy;
}
}
class NykthosDynamicManaEffect extends ManaEffect {
- public NykthosDynamicManaEffect() {
+ NykthosDynamicManaEffect() {
super();
this.staticText = "Choose a color. Add an amount of mana of that color equal to your devotion to that color. (Your devotion to a color is the number of mana symbols of that color in the mana costs of permanents you control.)";
}
- public NykthosDynamicManaEffect(final NykthosDynamicManaEffect effect) {
+ private NykthosDynamicManaEffect(final NykthosDynamicManaEffect effect) {
super(effect);
}
@@ -92,49 +98,48 @@ class NykthosDynamicManaEffect extends ManaEffect {
@Override
public List getNetMana(Game game, Ability source) {
- List netMana = new ArrayList<>();
- for (String colorChoice : ChoiceColor.getBaseColors()) {
- Mana mana = computeMana(colorChoice, game, source);
- if (mana.count() > 0) {
- netMana.add(mana);
- }
- }
- return netMana;
+ return ChoiceColor.getBaseColors()
+ .stream()
+ .map(s -> computeMana(s, game, source))
+ .filter(mana -> mana.count() > 0)
+ .collect(Collectors.toList());
}
@Override
public Mana produceMana(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- ChoiceColor choice = new ChoiceColor();
- choice.setMessage("Choose a color for devotion of Nykthos");
- if (controller.choose(outcome, choice, game)) {
- return computeMana(choice.getChoice(), game, source);
- }
+ if (controller == null) {
+ return null;
}
- return null;
+ ChoiceColor choice = new ChoiceColor();
+ choice.setMessage("Choose a color for devotion of Nykthos");
+ if (!controller.choose(outcome, choice, game)) {
+ return null;
+ }
+ return computeMana(choice.getChoice(), game, source);
}
- public Mana computeMana(String color, Game game, Ability source) {
+ private Mana computeMana(String color, Game game, Ability source) {
Mana mana = new Mana();
- if (color != null && !color.isEmpty()) {
- switch (color) {
- case "Red":
- mana.setRed(new DevotionCount(ColoredManaSymbol.R).calculate(game, source, this));
- break;
- case "Blue":
- mana.setBlue(new DevotionCount(ColoredManaSymbol.U).calculate(game, source, this));
- break;
- case "White":
- mana.setWhite(new DevotionCount(ColoredManaSymbol.W).calculate(game, source, this));
- break;
- case "Black":
- mana.setBlack(new DevotionCount(ColoredManaSymbol.B).calculate(game, source, this));
- break;
- case "Green":
- mana.setGreen(new DevotionCount(ColoredManaSymbol.G).calculate(game, source, this));
- break;
- }
+ if (color == null || color.isEmpty()) {
+ return mana;
+ }
+ switch (color) {
+ case "White":
+ mana.setWhite(DevotionCount.W.calculate(game, source, this));
+ break;
+ case "Blue":
+ mana.setBlue(DevotionCount.U.calculate(game, source, this));
+ break;
+ case "Black":
+ mana.setBlack(DevotionCount.B.calculate(game, source, this));
+ break;
+ case "Red":
+ mana.setRed(DevotionCount.R.calculate(game, source, this));
+ break;
+ case "Green":
+ mana.setGreen(DevotionCount.G.calculate(game, source, this));
+ break;
}
return mana;
}
diff --git a/Mage.Sets/src/mage/cards/n/NyleaGodOfTheHunt.java b/Mage.Sets/src/mage/cards/n/NyleaGodOfTheHunt.java
index 5e0a93d2cd3..9b0635f87a5 100644
--- a/Mage.Sets/src/mage/cards/n/NyleaGodOfTheHunt.java
+++ b/Mage.Sets/src/mage/cards/n/NyleaGodOfTheHunt.java
@@ -1,14 +1,11 @@
-
package mage.cards.n;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.DevotionCount;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
@@ -16,12 +13,16 @@ import mage.abilities.keyword.IndestructibleAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class NyleaGodOfTheHunt extends CardImpl {
@@ -36,20 +37,27 @@ public final class NyleaGodOfTheHunt extends CardImpl {
// Indestructible
this.addAbility(IndestructibleAbility.getInstance());
- // As long as your devotion to white is less than five, Nylea isn't a creature.(Each {G} in the mana costs of permanents you control counts towards your devotion to green.)
- Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.G), 5);
- effect.setText("As long as your devotion to green is less than five, Nylea isn't a creature.(Each {G} in the mana costs of permanents you control counts towards your devotion to green.)");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+
+ // As long as your devotion to green is less than five, Nylea isn't a creature.(Each {G} in the mana costs of permanents you control counts towards your devotion to green.)
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.G, 5))
+ .addHint(DevotionCount.G.getHint()));
+
// Other creatures you control have trample.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE, true)));
+ this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
+ TrampleAbility.getInstance(), Duration.WhileOnBattlefield,
+ StaticFilters.FILTER_PERMANENT_CREATURE, true
+ )));
+
// {3}{G}: Target creature gets +2/+2 until end of turn.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(2, 2, Duration.EndOfTurn), new ManaCostsImpl("{3}{G}"));
+ Ability ability = new SimpleActivatedAbility(
+ new BoostTargetEffect(2, 2, Duration.EndOfTurn), new ManaCostsImpl("{3}{G}")
+ );
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
- public NyleaGodOfTheHunt(final NyleaGodOfTheHunt card) {
+ private NyleaGodOfTheHunt(final NyleaGodOfTheHunt card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/n/NyleasDisciple.java b/Mage.Sets/src/mage/cards/n/NyleasDisciple.java
index 755147a3f8a..c83bd62f9e0 100644
--- a/Mage.Sets/src/mage/cards/n/NyleasDisciple.java
+++ b/Mage.Sets/src/mage/cards/n/NyleasDisciple.java
@@ -1,26 +1,23 @@
-
package mage.cards.n;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.common.DevotionCount;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.ColoredManaSymbol;
+
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class NyleasDisciple extends CardImpl {
public NyleasDisciple(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}");
this.subtype.add(SubType.CENTAUR);
this.subtype.add(SubType.ARCHER);
@@ -28,12 +25,12 @@ public final class NyleasDisciple extends CardImpl {
this.toughness = new MageInt(3);
// When Nylea's Disciple enters the battlefield, you gain life equal to your devotion to green.
- Effect effect = new GainLifeEffect(new DevotionCount(ColoredManaSymbol.G));
- effect.setText("you gain life equal to your devotion to green");
- this.addAbility(new EntersBattlefieldTriggeredAbility(effect));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(
+ new GainLifeEffect(DevotionCount.G).setText("you gain life equal to your devotion to green")
+ ).addHint(DevotionCount.G.getHint()));
}
- public NyleasDisciple(final NyleasDisciple card) {
+ private NyleasDisciple(final NyleasDisciple card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/n/NyxLotus.java b/Mage.Sets/src/mage/cards/n/NyxLotus.java
new file mode 100644
index 00000000000..cc89d5c3291
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/n/NyxLotus.java
@@ -0,0 +1,157 @@
+package mage.cards.n;
+
+import mage.Mana;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTappedAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.dynamicvalue.common.DevotionCount;
+import mage.abilities.effects.common.ManaEffect;
+import mage.abilities.mana.ActivatedManaAbilityImpl;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.choices.ChoiceColor;
+import mage.constants.CardType;
+import mage.constants.SuperType;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.players.Player;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * @author TheElk801
+ */
+public final class NyxLotus extends CardImpl {
+
+ public NyxLotus(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+
+ // Nyx Lotus enters the battlefield tapped.
+ this.addAbility(new EntersBattlefieldTappedAbility());
+
+ // {T}: Choose a color. Add an amount of mana of that color equal to your devotion to that color.
+ this.addAbility(new NyxLotusManaAbility());
+ }
+
+ private NyxLotus(final NyxLotus card) {
+ super(card);
+ }
+
+ @Override
+ public NyxLotus copy() {
+ return new NyxLotus(this);
+ }
+}
+
+class NyxLotusManaAbility extends ActivatedManaAbilityImpl {
+
+ NyxLotusManaAbility() {
+ super(Zone.BATTLEFIELD, new NyxLotusDynamicManaEffect(), new TapSourceCost());
+ this.addHint(DevotionCount.W.getHint());
+ this.addHint(DevotionCount.U.getHint());
+ this.addHint(DevotionCount.B.getHint());
+ this.addHint(DevotionCount.R.getHint());
+ this.addHint(DevotionCount.G.getHint());
+ }
+
+ private NyxLotusManaAbility(final NyxLotusManaAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public NyxLotusManaAbility copy() {
+ return new NyxLotusManaAbility(this);
+ }
+
+ @Override
+ public List getNetMana(Game game) {
+ ArrayList netManaCopy = new ArrayList<>();
+ if (game == null) {
+ return netManaCopy;
+ }
+ netManaCopy.addAll(((ManaEffect) this.getEffects().get(0)).getNetMana(game, this));
+ return netManaCopy;
+ }
+}
+
+class NyxLotusDynamicManaEffect extends ManaEffect {
+
+ NyxLotusDynamicManaEffect() {
+ super();
+ this.staticText = "Choose a color. Add an amount of mana of that color equal to your devotion to that color. (Your devotion to a color is the number of mana symbols of that color in the mana costs of permanents you control.)";
+ }
+
+ private NyxLotusDynamicManaEffect(final NyxLotusDynamicManaEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public NyxLotusDynamicManaEffect copy() {
+ return new NyxLotusDynamicManaEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) {
+ return false;
+ }
+ checkToFirePossibleEvents(getMana(game, source), game, source);
+ controller.getManaPool().addMana(getMana(game, source), game, source);
+ return true;
+
+ }
+
+ @Override
+ public List getNetMana(Game game, Ability source) {
+ return ChoiceColor.getBaseColors()
+ .stream()
+ .map(s -> computeMana(s, game, source))
+ .filter(mana -> mana.count() > 0)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public Mana produceMana(boolean netMana, Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) {
+ return null;
+ }
+ ChoiceColor choice = new ChoiceColor();
+ choice.setMessage("Choose a color for devotion of Nyx Lotus");
+ if (!controller.choose(outcome, choice, game)) {
+ return null;
+ }
+ return computeMana(choice.getChoice(), game, source);
+ }
+
+ private Mana computeMana(String color, Game game, Ability source) {
+ Mana mana = new Mana();
+ if (color == null || color.isEmpty()) {
+ return mana;
+ }
+ switch (color) {
+ case "White":
+ mana.setWhite(DevotionCount.W.calculate(game, source, this));
+ break;
+ case "Blue":
+ mana.setBlue(DevotionCount.U.calculate(game, source, this));
+ break;
+ case "Black":
+ mana.setBlack(DevotionCount.B.calculate(game, source, this));
+ break;
+ case "Red":
+ mana.setRed(DevotionCount.R.calculate(game, source, this));
+ break;
+ case "Green":
+ mana.setGreen(DevotionCount.G.calculate(game, source, this));
+ break;
+ }
+ return mana;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/n/NyxbornColossus.java b/Mage.Sets/src/mage/cards/n/NyxbornColossus.java
new file mode 100644
index 00000000000..4005098a1e1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/n/NyxbornColossus.java
@@ -0,0 +1,32 @@
+package mage.cards.n;
+
+import mage.MageInt;
+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 NyxbornColossus extends CardImpl {
+
+ public NyxbornColossus(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{3}{G}{G}{G}");
+
+ this.subtype.add(SubType.GIANT);
+ this.power = new MageInt(6);
+ this.toughness = new MageInt(7);
+ }
+
+ private NyxbornColossus(final NyxbornColossus card) {
+ super(card);
+ }
+
+ @Override
+ public NyxbornColossus copy() {
+ return new NyxbornColossus(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/n/NyxbornCourser.java b/Mage.Sets/src/mage/cards/n/NyxbornCourser.java
new file mode 100644
index 00000000000..3bffca694f8
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/n/NyxbornCourser.java
@@ -0,0 +1,35 @@
+package mage.cards.n;
+
+import mage.MageInt;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author jmharmon
+ */
+
+public final class NyxbornCourser extends CardImpl {
+
+ public NyxbornCourser(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{W}{W}");
+
+ this.subtype.add(SubType.CENTAUR);
+ this.subtype.add(SubType.SCOUT);
+
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(4);
+ }
+
+ public NyxbornCourser(final NyxbornCourser card) {
+ super(card);
+ }
+
+ @Override
+ public NyxbornCourser copy() {
+ return new NyxbornCourser(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/o/OakhameAdversary.java b/Mage.Sets/src/mage/cards/o/OakhameAdversary.java
new file mode 100644
index 00000000000..bfc25c3e5c0
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/o/OakhameAdversary.java
@@ -0,0 +1,66 @@
+package mage.cards.o;
+
+import mage.MageInt;
+import mage.ObjectColor;
+import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
+import mage.abilities.keyword.DeathtouchAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.FilterPermanent;
+import mage.filter.predicate.mageobject.ColorPredicate;
+import java.util.UUID;
+import mage.abilities.condition.common.OpponentControlsPermanentCondition;
+import mage.constants.ComparisonType;
+
+/**
+ * @author TheElk801
+ */
+public final class OakhameAdversary extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterPermanent("your opponent controls a green permanent");
+
+ static {
+ filter.add(new ColorPredicate(ObjectColor.GREEN));
+ }
+
+ private static final Condition condition = new OpponentControlsPermanentCondition(filter, ComparisonType.MORE_THAN, 0);
+
+ public OakhameAdversary(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
+
+ this.subtype.add(SubType.ELF);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // This spell costs {2} less to cast if your opponent controls a green permanent.
+ this.addAbility(new SimpleStaticAbility(
+ Zone.STACK, new SpellCostReductionSourceEffect(2, condition)
+ ).setRuleAtTheTop(true));
+
+ // Deathtouch
+ this.addAbility(DeathtouchAbility.getInstance());
+
+ // Whenever Oakhame Adversary deals combat damage to a player, draw a card.
+ this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(
+ new DrawCardSourceControllerEffect(1), false
+ ));
+ }
+
+ private OakhameAdversary(final OakhameAdversary card) {
+ super(card);
+ }
+
+ @Override
+ public OakhameAdversary copy() {
+ return new OakhameAdversary(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/o/OakhameRanger.java b/Mage.Sets/src/mage/cards/o/OakhameRanger.java
new file mode 100644
index 00000000000..9ebc7bb6597
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/o/OakhameRanger.java
@@ -0,0 +1,48 @@
+package mage.cards.o;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.continuous.BoostControlledEffect;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.game.permanent.token.HumanToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class OakhameRanger extends AdventureCard {
+
+ public OakhameRanger(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{G/W}{G/W}{G/W}{G/W}", "Bring Back", "{G/W}{G/W}{G/W}{G/W}");
+
+ this.subtype.add(SubType.ELF);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // {T}: Creatures you control get +1/+1 until end of turn.
+ this.addAbility(new SimpleActivatedAbility(
+ new BoostControlledEffect(1, 1, Duration.EndOfTurn), new TapSourceCost()
+ ));
+
+ // Bring Back
+ // Create two 1/1 white Human creature tokens.
+ this.getSpellCard().getSpellAbility().addEffect(new CreateTokenEffect(new HumanToken(), 2));
+ }
+
+ private OakhameRanger(final OakhameRanger card) {
+ super(card);
+ }
+
+ @Override
+ public OakhameRanger copy() {
+ return new OakhameRanger(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/o/OathOfDruids.java b/Mage.Sets/src/mage/cards/o/OathOfDruids.java
index 652548ad6f1..56598079aa8 100644
--- a/Mage.Sets/src/mage/cards/o/OathOfDruids.java
+++ b/Mage.Sets/src/mage/cards/o/OathOfDruids.java
@@ -28,9 +28,9 @@ public final class OathOfDruids extends CardImpl {
public OathOfDruids(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
- // At the beginning of each player's upkeep, that player chooses target player who controls more creatures than he or she does and is their opponent.
- // The first player may reveal cards from the top of their library until he or she reveals a creature card.
- // If he or she does, that player puts that card onto the battlefield and all other cards revealed this way into their graveyard.
+ // At the beginning of each player's upkeep, that player chooses target player who controls more creatures than they do and is their opponent.
+ // The first player may reveal cards from the top of their library until they reveal a creature card.
+ // If they do, that player puts that card onto the battlefield and all other cards revealed this way into their graveyard.
Ability ability = new BeginningOfUpkeepTriggeredAbility(new OathOfDruidsEffect(), TargetController.ANY, false);
ability.setTargetAdjuster(OathOfDruidsAdjuster.instance);
this.addAbility(ability);
@@ -89,7 +89,7 @@ class OathOfDruidsPredicate implements ObjectSourcePlayerPredicateAdamant — If at least three green mana was spent to cast this spell, " +
+ "instead return those cards to your hand and exile {this}.";
+ }
+
+ private OnceAndFutureEffect(final OnceAndFutureEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public OnceAndFutureEffect copy() {
+ return new OnceAndFutureEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ Card card1 = game.getCard(source.getFirstTarget());
+ Card card2 = game.getCard(source.getTargets().get(1).getFirstTarget());
+ if (card1 == null) {
+ card1 = card2;
+ card2 = null;
+ }
+ if (card1 == null) {
+ return false;
+ }
+ if (card2 == null) {
+ player.putInHand(card1, game);
+ return ExileSpellEffect.getInstance().apply(game, source);
+ }
+ if (AdamantCondition.GREEN.apply(game, source)) {
+ Cards cards = new CardsImpl();
+ cards.add(card1);
+ cards.add(card2);
+ player.moveCards(cards, Zone.HAND, source, game);
+ return ExileSpellEffect.getInstance().apply(game, source);
+ }
+ player.putInHand(card1, game);
+ player.putCardsOnTopOfLibrary(new CardsImpl(card2), game, source, false);
+ return ExileSpellEffect.getInstance().apply(game, source);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/o/OnceUponATime.java b/Mage.Sets/src/mage/cards/o/OnceUponATime.java
new file mode 100644
index 00000000000..3a3559d9fa9
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/o/OnceUponATime.java
@@ -0,0 +1,106 @@
+package mage.cards.o;
+
+import mage.abilities.Ability;
+import mage.abilities.condition.Condition;
+import mage.abilities.costs.AlternativeCostSourceAbility;
+import mage.abilities.dynamicvalue.common.StaticValue;
+import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.WatcherScope;
+import mage.constants.Zone;
+import mage.filter.FilterCard;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.watchers.Watcher;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class OnceUponATime extends CardImpl {
+
+ private static final FilterCard filter = new FilterCard("a creature or land card");
+
+ static {
+ filter.add(Predicates.or(
+ new CardTypePredicate(CardType.CREATURE),
+ new CardTypePredicate(CardType.LAND)
+ ));
+ }
+
+ public OnceUponATime(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}");
+
+ // If this spell is the first spell you've cast this game, you may cast it without paying its mana cost.
+ this.addAbility(new AlternativeCostSourceAbility(
+ null, OnceUponATimeCondition.instance, "If this spell is the first spell " +
+ "you've cast this game, you may cast it without paying its mana cost."
+ ), new OnceUponATimeWatcher());
+
+ // Look at the top five cards of your library. You may reveal a creature or land card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(
+ new StaticValue(5), false, new StaticValue(1), filter,
+ Zone.LIBRARY, false, true, false, Zone.HAND,
+ true, false, false
+ ).setBackInRandomOrder(true).setText("Look at the top five cards of your library. " +
+ "You may reveal a creature or land card from among them and put it into your hand. " +
+ "Put the rest on the bottom of your library in a random order."
+ ));
+ }
+
+ private OnceUponATime(final OnceUponATime card) {
+ super(card);
+ }
+
+ @Override
+ public OnceUponATime copy() {
+ return new OnceUponATime(this);
+ }
+}
+
+enum OnceUponATimeCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ OnceUponATimeWatcher watcher = game.getState().getWatcher(OnceUponATimeWatcher.class);
+ return watcher != null && watcher.getSpellsCastThisTurn(source.getControllerId());
+ }
+}
+
+class OnceUponATimeWatcher extends Watcher {
+
+ private final Set castSpells = new HashSet();
+
+ OnceUponATimeWatcher() {
+ super(WatcherScope.GAME);
+ }
+
+ private OnceUponATimeWatcher(final OnceUponATimeWatcher watcher) {
+ super(watcher);
+ this.castSpells.addAll(watcher.castSpells);
+ }
+
+ @Override
+ public OnceUponATimeWatcher copy() {
+ return new OnceUponATimeWatcher(this);
+ }
+
+ @Override
+ public void watch(GameEvent event, Game game) {
+ if (GameEvent.EventType.SPELL_CAST == event.getType()) {
+ castSpells.add(event.getPlayerId());
+ }
+ }
+
+ public boolean getSpellsCastThisTurn(UUID playerId) {
+ return !castSpells.contains(playerId);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/o/OpenTheArmory.java b/Mage.Sets/src/mage/cards/o/OpenTheArmory.java
index a0063c18b63..8e04b2959ce 100644
--- a/Mage.Sets/src/mage/cards/o/OpenTheArmory.java
+++ b/Mage.Sets/src/mage/cards/o/OpenTheArmory.java
@@ -1,31 +1,35 @@
-
package mage.cards.o;
-import java.util.UUID;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
-import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.cards.Cards;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SubtypePredicate;
-import mage.game.Game;
import mage.target.common.TargetCardInLibrary;
+import java.util.UUID;
+
/**
- *
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
public final class OpenTheArmory extends CardImpl {
+ private static final FilterCard auraOrEquipmentTarget = new FilterCard("Aura or Equipment card");
+
+ static {
+ auraOrEquipmentTarget.add(Predicates.or(
+ new SubtypePredicate(SubType.EQUIPMENT),
+ new SubtypePredicate(SubType.AURA)));
+ }
+
public OpenTheArmory(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{W}");
// Search your library for an Aura or Equipment card, reveal it, and put it into your hand. Then shuffle your library.
- this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new OpenTheArmoryTarget(), true, true));
+ this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(1, 1, auraOrEquipmentTarget), true, true));
}
public OpenTheArmory(final OpenTheArmory card) {
@@ -36,36 +40,4 @@ public final class OpenTheArmory extends CardImpl {
public OpenTheArmory copy() {
return new OpenTheArmory(this);
}
-}
-
-class OpenTheArmoryTarget extends TargetCardInLibrary {
-
- private static final FilterCard auraOrEquipmentTarget = new FilterCard("Aura or Equipment card");
- static {
- auraOrEquipmentTarget.add(Predicates.or(
- new SubtypePredicate(SubType.EQUIPMENT),
- new SubtypePredicate(SubType.AURA)));
- }
-
- public OpenTheArmoryTarget() {
- super(1, 1, auraOrEquipmentTarget.copy());
- }
-
- public OpenTheArmoryTarget(final OpenTheArmoryTarget target) {
- super(target);
- }
-
- @Override
- public OpenTheArmoryTarget copy() {
- return new OpenTheArmoryTarget(this);
- }
-
- @Override
- public boolean canTarget(UUID id, Cards cards, Game game) {
- Card card = cards.get(id, game);
- if (card != null) {
- return auraOrEquipmentTarget.match(card, game);
- }
- return false;
- }
-}
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/o/OpportunisticDragon.java b/Mage.Sets/src/mage/cards/o/OpportunisticDragon.java
new file mode 100644
index 00000000000..60d557c2625
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/o/OpportunisticDragon.java
@@ -0,0 +1,147 @@
+package mage.cards.o;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.combat.CantAttackBlockTargetEffect;
+import mage.abilities.effects.common.continuous.GainControlTargetEffect;
+import mage.abilities.effects.common.continuous.LoseAllAbilitiesTargetEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+import mage.filter.FilterPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.TargetPermanent;
+
+/**
+ * @author TheElk801
+ */
+public final class OpportunisticDragon extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterPermanent("Human or artifact an opponent controls");
+
+ static {
+ filter.add(Predicates.or(
+ new CardTypePredicate(CardType.ARTIFACT),
+ new SubtypePredicate(SubType.HUMAN)
+ ));
+ filter.add(new ControllerPredicate(TargetController.OPPONENT));
+ }
+
+ public OpportunisticDragon(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
+
+ this.subtype.add(SubType.DRAGON);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(3);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // When Opportunistic Dragon enters the battlefield, choose target Human or artifact an opponent controls.
+ // For as long as Opportunistic Dragon remains on the battlefield, gain control of that permanent, it loses all abilities, and it can't attack or block.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new OpportunisticDragonControlEffect());
+ ability.addEffect(new OpportunisticDragonLoseAbilitiesEffect());
+ ability.addEffect(new OpportunisticDragonAttackBlockEffect());
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(ability);
+ }
+
+ private OpportunisticDragon(final OpportunisticDragon card) {
+ super(card);
+ }
+
+ @Override
+ public OpportunisticDragon copy() {
+ return new OpportunisticDragon(this);
+ }
+}
+
+class OpportunisticDragonControlEffect extends GainControlTargetEffect {
+
+ OpportunisticDragonControlEffect() {
+ super(Duration.Custom);
+ staticText = "choose target Human or artifact an opponent controls. "
+ + "For as long as {this} remains on the battlefield, gain control of that permanent,";
+ }
+
+ private OpportunisticDragonControlEffect(final OpportunisticDragonControlEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public OpportunisticDragonControlEffect copy() {
+ return new OpportunisticDragonControlEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ if (source.getSourcePermanentIfItStillExists(game) == null) {
+ discard();
+ return false;
+ }
+ return super.apply(game, source);
+ }
+}
+
+class OpportunisticDragonLoseAbilitiesEffect extends LoseAllAbilitiesTargetEffect {
+
+ OpportunisticDragonLoseAbilitiesEffect() {
+ super(Duration.Custom);
+ staticText = "it loses all abilities,";
+ }
+
+ private OpportunisticDragonLoseAbilitiesEffect(final OpportunisticDragonLoseAbilitiesEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public OpportunisticDragonLoseAbilitiesEffect copy() {
+ return new OpportunisticDragonLoseAbilitiesEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ if (source.getSourcePermanentIfItStillExists(game) == null) {
+ discard();
+ return false;
+ }
+ return super.apply(game, source);
+ }
+}
+
+class OpportunisticDragonAttackBlockEffect extends CantAttackBlockTargetEffect {
+
+ OpportunisticDragonAttackBlockEffect() {
+ super(Duration.Custom);
+ staticText = "and it can't attack or block";
+ }
+
+ private OpportunisticDragonAttackBlockEffect(final OpportunisticDragonAttackBlockEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public OpportunisticDragonAttackBlockEffect copy() {
+ return new OpportunisticDragonAttackBlockEffect(this);
+ }
+
+ @Override
+ public boolean applies(Permanent permanent, Ability source, Game game) {
+ if (source.getSourcePermanentIfItStillExists(game) == null) {
+ discard();
+ return false;
+ }
+ return super.applies(permanent, source, game); //To change body of generated methods, choose Tools | Templates.
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/o/OracleEnVec.java b/Mage.Sets/src/mage/cards/o/OracleEnVec.java
index 04f6d213700..f79916b7911 100644
--- a/Mage.Sets/src/mage/cards/o/OracleEnVec.java
+++ b/Mage.Sets/src/mage/cards/o/OracleEnVec.java
@@ -64,7 +64,7 @@ class OracleEnVecEffect extends OneShotEffect {
OracleEnVecEffect() {
super(Outcome.Benefit);
- this.staticText = "Target opponent chooses any number of creatures he or she controls. During that player's next turn, " +
+ this.staticText = "Target opponent chooses any number of creatures they control. During that player's next turn, " +
"the chosen creatures attack if able, and other creatures can't attack. At the beginning of that turn's end step, " +
"destroy each of the chosen creatures that didn't attack";
}
diff --git a/Mage.Sets/src/mage/cards/o/OracleOfBones.java b/Mage.Sets/src/mage/cards/o/OracleOfBones.java
index d54fec1de78..7b5e809bed0 100644
--- a/Mage.Sets/src/mage/cards/o/OracleOfBones.java
+++ b/Mage.Sets/src/mage/cards/o/OracleOfBones.java
@@ -1,4 +1,3 @@
-
package mage.cards.o;
import java.util.UUID;
@@ -43,10 +42,12 @@ public final class OracleOfBones extends CardImpl {
this.addAbility(HasteAbility.getInstance());
// Tribute 2
this.addAbility(new TributeAbility(2));
- // When Oracle of Bones enters the battlefield, if tribute wasn't paid, you may cast an instant or sorcery card from your hand without paying its mana cost.
+ // When Oracle of Bones enters the battlefield, if tribute wasn't paid,
+ // you may cast an instant or sorcery card from your hand without paying its mana cost.
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new OracleOfBonesCastEffect(), false);
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, TributeNotPaidCondition.instance,
- "When {this} enters the battlefield, if its tribute wasn't paid, you may cast an instant or sorcery card from your hand without paying its mana cost."));
+ "When {this} enters the battlefield, if its tribute wasn't paid, "
+ + "you may cast an instant or sorcery card from your hand without paying its mana cost."));
}
public OracleOfBones(final OracleOfBones card) {
@@ -61,11 +62,13 @@ public final class OracleOfBones extends CardImpl {
class OracleOfBonesCastEffect extends OneShotEffect {
- private static final FilterCard filter = new FilterInstantOrSorceryCard("instant or sorcery card from your hand");
+ private static final FilterCard filter = new FilterInstantOrSorceryCard(
+ "instant or sorcery card from your hand");
public OracleOfBonesCastEffect() {
super(Outcome.PlayForFree);
- this.staticText = "you may cast an instant or sorcery card from your hand without paying its mana cost";
+ this.staticText = "you may cast an instant or sorcery card "
+ + "from your hand without paying its mana cost";
}
public OracleOfBonesCastEffect(final OracleOfBonesCastEffect effect) {
@@ -83,13 +86,16 @@ class OracleOfBonesCastEffect extends OneShotEffect {
if (controller != null) {
Target target = new TargetCardInHand(filter);
if (target.canChoose(source.getSourceId(), controller.getId(), game)
- && controller.chooseUse(outcome, "Cast an instant or sorcery card from your hand without paying its mana cost?", source, game)) {
+ && controller.chooseUse(outcome, "Cast an instant or sorcery "
+ + "card from your hand without paying its mana cost?", source, game)) {
Card cardToCast = null;
boolean cancel = false;
- while (controller.canRespond() && !cancel) {
+ while (controller.canRespond()
+ && !cancel) {
if (controller.chooseTarget(outcome, target, source, game)) {
cardToCast = game.getCard(target.getFirstTarget());
- if (cardToCast != null && cardToCast.getSpellAbility().canChooseTarget(game)) {
+ if (cardToCast != null
+ && cardToCast.getSpellAbility().canChooseTarget(game)) {
cancel = true;
}
} else {
@@ -97,7 +103,10 @@ class OracleOfBonesCastEffect extends OneShotEffect {
}
}
if (cardToCast != null) {
- controller.cast(cardToCast.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + cardToCast.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(cardToCast, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + cardToCast.getId(), null);
}
}
return true;
diff --git a/Mage.Sets/src/mage/cards/o/OrderOfMidnight.java b/Mage.Sets/src/mage/cards/o/OrderOfMidnight.java
new file mode 100644
index 00000000000..9829efb2a30
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/o/OrderOfMidnight.java
@@ -0,0 +1,49 @@
+package mage.cards.o;
+
+import mage.MageInt;
+import mage.abilities.common.CantBlockAbility;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
+import mage.target.common.TargetCardInYourGraveyard;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class OrderOfMidnight extends AdventureCard {
+
+ public OrderOfMidnight(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{1}{B}","Alter Fate", "{1}{B}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Order of Midnight can't block.
+ this.addAbility(new CantBlockAbility());
+
+ // Alter Fate
+ // Return target creature card from your graveyard to your hand.
+ this.getSpellCard().getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect());
+ this.getSpellCard().getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
+ }
+
+ private OrderOfMidnight(final OrderOfMidnight card) {
+ super(card);
+ }
+
+ @Override
+ public OrderOfMidnight copy() {
+ return new OrderOfMidnight(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/o/OrderOfSuccession.java b/Mage.Sets/src/mage/cards/o/OrderOfSuccession.java
index 9633f56bb84..1bb55e17a21 100644
--- a/Mage.Sets/src/mage/cards/o/OrderOfSuccession.java
+++ b/Mage.Sets/src/mage/cards/o/OrderOfSuccession.java
@@ -34,7 +34,7 @@ public final class OrderOfSuccession extends CardImpl {
public OrderOfSuccession(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}");
- // Choose left or right. Starting with you and proceeding in the chosen direction, each player chooses a creature controlled by the next player in that direction. Each player gains control of the creature he or she chose.
+ // Choose left or right. Starting with you and proceeding in the chosen direction, each player chooses a creature controlled by the next player in that direction. Each player gains control of the creature they chose.
this.getSpellAbility().addEffect(new OrderOfSuccessionEffect());
}
@@ -52,7 +52,7 @@ class OrderOfSuccessionEffect extends OneShotEffect {
public OrderOfSuccessionEffect() {
super(Outcome.Benefit);
- this.staticText = "Starting with you and proceeding in the chosen direction, each player chooses a creature controlled by the next player in that direction. Each player gains control of the creature he or she chose";
+ this.staticText = "Starting with you and proceeding in the chosen direction, each player chooses a creature controlled by the next player in that direction. Each player gains control of the creature they chose";
}
public OrderOfSuccessionEffect(final OrderOfSuccessionEffect effect) {
@@ -95,7 +95,7 @@ class OrderOfSuccessionEffect extends OneShotEffect {
if (!nextPlayer.canRespond()) {
continue;
}
- // if player is in range he chooses a creature to control
+ // if player is in range they choose a creature to control
if (currentPlayer != null && game.getState().getPlayersInRange(controller.getId(), game).contains(currentPlayer.getId())) {
FilterCreaturePermanent filter = new FilterCreaturePermanent("creature controlled by " + nextPlayer.getLogName());
filter.add(new ControllerIdPredicate(nextPlayer.getId()));
diff --git a/Mage.Sets/src/mage/cards/o/OrzhovAdvokist.java b/Mage.Sets/src/mage/cards/o/OrzhovAdvokist.java
index b436b129474..bc4d079cec7 100644
--- a/Mage.Sets/src/mage/cards/o/OrzhovAdvokist.java
+++ b/Mage.Sets/src/mage/cards/o/OrzhovAdvokist.java
@@ -42,7 +42,7 @@ public final class OrzhovAdvokist extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(4);
- // At the beginning of your upkeep, each player may put two +1/+1 counters on a creature he or she controls. If a player does, creatures that player controls can't attack you or a planeswalker you control until your next turn.
+ // At the beginning of your upkeep, each player may put two +1/+1 counters on a creature they control. If a player does, creatures that player controls can't attack you or a planeswalker you control until your next turn.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new OrzhovAdvokistEffect(), TargetController.YOU, false));
}
@@ -60,7 +60,7 @@ class OrzhovAdvokistEffect extends OneShotEffect {
public OrzhovAdvokistEffect() {
super(Outcome.Benefit);
- this.staticText = "each player may put two +1/+1 counters on a creature he or she controls. "
+ this.staticText = "each player may put two +1/+1 counters on a creature they control. "
+ "If a player does, creatures that player controls can't attack you or a planeswalker you control until your next turn";
}
diff --git a/Mage.Sets/src/mage/cards/o/Outflank.java b/Mage.Sets/src/mage/cards/o/Outflank.java
new file mode 100644
index 00000000000..38180738195
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/o/Outflank.java
@@ -0,0 +1,40 @@
+package mage.cards.o;
+
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.StaticFilters;
+import mage.target.common.TargetAttackingOrBlockingCreature;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class Outflank extends CardImpl {
+
+ private static final DynamicValue xValue
+ = new PermanentsOnBattlefieldCount(StaticFilters.FILTER_CONTROLLED_CREATURE);
+
+ public Outflank(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}");
+
+ // Outflank deals damage to target attacking or blocking creature equal to the number of creatures you control.
+ this.getSpellAbility().addEffect(new DamageTargetEffect(xValue)
+ .setText("{this} deals damage to target attacking or blocking creature " +
+ "equal to the number of creatures you control"));
+ this.getSpellAbility().addTarget(new TargetAttackingOrBlockingCreature());
+ }
+
+ private Outflank(final Outflank card) {
+ super(card);
+ }
+
+ @Override
+ public Outflank copy() {
+ return new Outflank(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/o/OutlawsMerriment.java b/Mage.Sets/src/mage/cards/o/OutlawsMerriment.java
new file mode 100644
index 00000000000..653fa86cf9b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/o/OutlawsMerriment.java
@@ -0,0 +1,55 @@
+package mage.cards.o;
+
+import mage.abilities.Ability;
+import mage.abilities.Mode;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.TargetController;
+import mage.game.permanent.token.OutlawsMerrimentClericToken;
+import mage.game.permanent.token.OutlawsMerrimentRogueToken;
+import mage.game.permanent.token.OutlawsMerrimentWarriorToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class OutlawsMerriment extends CardImpl {
+
+ public OutlawsMerriment(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}{W}{W}");
+
+ // At the beginning of your upkeep, choose one at random. Create a red and white creature token with those characteristics.
+ // • 3/1 Human Warrior with trample and haste.
+ Ability ability = new BeginningOfUpkeepTriggeredAbility(
+ new CreateTokenEffect(new OutlawsMerrimentWarriorToken())
+ .setText("3/1 Human Warrior with trample and haste"),
+ TargetController.YOU, false
+ );
+
+ // • 2/1 Human Cleric with lifelink and haste.
+ ability.addMode(new Mode(new CreateTokenEffect(new OutlawsMerrimentClericToken())
+ .setText("2/1 Human Cleric with lifelink and haste")));
+
+ // • 1/2 Human Rogue with haste and "When this creature enters the battlefield, it deals 1 damage to any target."
+ ability.addMode(new Mode(new CreateTokenEffect(new OutlawsMerrimentRogueToken())
+ .setText("1/2 Human Rogue with haste and \"When this creature enters the battlefield, it deals 1 damage to any target.\"")));
+
+ ability.getModes().setChooseText("choose one at random. Create a red and white creature token with those characteristics.");
+ ability.getModes().setRandom(true);
+
+ this.addAbility(ability);
+ }
+
+ private OutlawsMerriment(final OutlawsMerriment card) {
+ super(card);
+ }
+
+ @Override
+ public OutlawsMerriment copy() {
+ return new OutlawsMerriment(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/o/Outmuscle.java b/Mage.Sets/src/mage/cards/o/Outmuscle.java
new file mode 100644
index 00000000000..02fc9bbbbfa
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/o/Outmuscle.java
@@ -0,0 +1,98 @@
+package mage.cards.o;
+
+import mage.abilities.Ability;
+import mage.abilities.condition.common.AdamantCondition;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.keyword.IndestructibleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.TargetController;
+import mage.counters.CounterType;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetControlledCreaturePermanent;
+import mage.target.targetpointer.FixedTarget;
+import mage.watchers.common.ManaSpentToCastWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class Outmuscle extends CardImpl {
+
+ private static final FilterCreaturePermanent filter
+ = new FilterCreaturePermanent("creature you don't control");
+
+ static {
+ filter.add(new ControllerPredicate(TargetController.NOT_YOU));
+ }
+
+ public Outmuscle(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}");
+
+ // Put a +1/+1 counter on target creature you control, then it fights target creature you don't control.
+ // Adamant — If at least three green mana was spent to cast this spell, the creature you control gains indestructible until end of turn.
+ this.getSpellAbility().addEffect(new OutmuscleEffect());
+ this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
+ this.getSpellAbility().addTarget(new TargetPermanent(filter));
+ this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher());
+ }
+
+ private Outmuscle(final Outmuscle card) {
+ super(card);
+ }
+
+ @Override
+ public Outmuscle copy() {
+ return new Outmuscle(this);
+ }
+}
+
+class OutmuscleEffect extends OneShotEffect {
+
+ OutmuscleEffect() {
+ super(Outcome.Benefit);
+ staticText = "Put a +1/+1 counter on target creature you control, " +
+ "then it fights target creature you don't control." +
+ "
Adamant — If at least three green mana was spent to cast this spell, " +
+ "the creature you control gains indestructible until end of turn.";
+ }
+
+ private OutmuscleEffect(final OutmuscleEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public OutmuscleEffect copy() {
+ return new OutmuscleEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = game.getPermanent(source.getFirstTarget());
+ if (permanent == null) {
+ return false;
+ }
+ if (AdamantCondition.GREEN.apply(game, source)) {
+ ContinuousEffect effect = new GainAbilityTargetEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn);
+ effect.setTargetPointer(new FixedTarget(permanent, game));
+ game.addEffect(effect, source);
+ }
+ permanent.addCounters(CounterType.P1P1.createInstance(), source, game);
+ Permanent creature = game.getPermanent(source.getTargets().get(1).getFirstTarget());
+ if (creature == null) {
+ return true;
+ }
+ game.applyEffects();
+ return creature.fight(permanent, source, game);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/o/Overabundance.java b/Mage.Sets/src/mage/cards/o/Overabundance.java
index 929d3d43847..63a040fe133 100644
--- a/Mage.Sets/src/mage/cards/o/Overabundance.java
+++ b/Mage.Sets/src/mage/cards/o/Overabundance.java
@@ -22,7 +22,7 @@ public final class Overabundance extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}{G}");
- // Whenever a player taps a land for mana, that player adds one mana of any type that land produced, and Overabundance deals 1 damage to him or her.
+ // Whenever a player taps a land for mana, that player adds one mana of any type that land produced, and Overabundance deals 1 damage to that player.
this.addAbility(new TapForManaAllTriggeredManaAbility(
new AddManaOfAnyTypeProducedEffect(),
new FilterLandPermanent( "a player taps a land"),
diff --git a/Mage.Sets/src/mage/cards/o/Overburden.java b/Mage.Sets/src/mage/cards/o/Overburden.java
index fb145c23318..7f0a878dd83 100644
--- a/Mage.Sets/src/mage/cards/o/Overburden.java
+++ b/Mage.Sets/src/mage/cards/o/Overburden.java
@@ -31,7 +31,7 @@ public final class Overburden extends CardImpl {
public Overburden(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}");
- // Whenever a player puts a nontoken creature onto the battlefield, that player returns a land he or she controls to its owner's hand.
+ // Whenever a player puts a nontoken creature onto the battlefield, that player returns a land they control to its owner's hand.
this.addAbility(new EntersBattlefieldAllTriggeredAbility(
Zone.BATTLEFIELD,
new ReturnToHandChosenPermanentEffect(RETURN_FILTER),
@@ -39,7 +39,7 @@ public final class Overburden extends CardImpl {
false,
SetTargetPointer.PLAYER,
"Whenever a player puts a nontoken creature onto the battlefield,"
- + " that player returns a land he or she controls to its owner's hand."));
+ + " that player returns a land they control to its owner's hand."));
}
public Overburden(final Overburden card) {
diff --git a/Mage.Sets/src/mage/cards/o/OversoldCemetery.java b/Mage.Sets/src/mage/cards/o/OversoldCemetery.java
index 5c4825f137a..d855975ac53 100644
--- a/Mage.Sets/src/mage/cards/o/OversoldCemetery.java
+++ b/Mage.Sets/src/mage/cards/o/OversoldCemetery.java
@@ -1,4 +1,3 @@
-
package mage.cards.o;
import java.util.UUID;
@@ -13,7 +12,6 @@ import mage.constants.CardType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterCreatureCard;
import mage.target.common.TargetCardInGraveyard;
/**
@@ -27,7 +25,7 @@ public final class OversoldCemetery extends CardImpl {
// At the beginning of your upkeep, if you have four or more creature cards in your graveyard, you may return target creature card from your graveyard to your hand.
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new ReturnFromGraveyardToHandTargetEffect(), TargetController.YOU, true);
- ability.addTarget(new TargetCardInGraveyard(new FilterCreatureCard()));
+ ability.addTarget(new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE));
CardsInControllerGraveCondition condition = new CardsInControllerGraveCondition(4, StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD);
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, condition, "At the beginning of your upkeep, if you have four or more creature cards in your graveyard, you may return target creature card from your graveyard to your hand."));
}
diff --git a/Mage.Sets/src/mage/cards/o/OverwhelmedApprentice.java b/Mage.Sets/src/mage/cards/o/OverwhelmedApprentice.java
new file mode 100644
index 00000000000..c62134e5663
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/o/OverwhelmedApprentice.java
@@ -0,0 +1,45 @@
+package mage.cards.o;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveEachPlayerEffect;
+import mage.abilities.effects.keyword.ScryEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class OverwhelmedApprentice extends CardImpl {
+
+ public OverwhelmedApprentice(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.WIZARD);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(2);
+
+ // When Overwhelmed Apprentice enters the battlefield, each opponent puts the top two cards of their library into their graveyard. Then you scry 2.
+ Ability ability = new EntersBattlefieldTriggeredAbility(
+ new PutTopCardOfLibraryIntoGraveEachPlayerEffect(2, TargetController.OPPONENT)
+ );
+ ability.addEffect(new ScryEffect(2).setText("Then you scry 2."));
+ this.addAbility(ability);
+ }
+
+ private OverwhelmedApprentice(final OverwhelmedApprentice card) {
+ super(card);
+ }
+
+ @Override
+ public OverwhelmedApprentice copy() {
+ return new OverwhelmedApprentice(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/o/OxOfAgonas.java b/Mage.Sets/src/mage/cards/o/OxOfAgonas.java
new file mode 100644
index 00000000000..93a92d0b763
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/o/OxOfAgonas.java
@@ -0,0 +1,51 @@
+package mage.cards.o;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.EscapesWithAbility;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.discard.DiscardHandControllerEffect;
+import mage.abilities.keyword.EscapeAbility;
+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 OxOfAgonas extends CardImpl {
+
+ public OxOfAgonas(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}");
+
+ this.subtype.add(SubType.OX);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(2);
+
+ // When Ox of Agonas enters the battlefield, discard your hand, then draw three cards.
+ Ability ability = new EntersBattlefieldTriggeredAbility(
+ new DiscardHandControllerEffect().setText("discard your hand,")
+ );
+ ability.addEffect(new DrawCardSourceControllerEffect(3).setText("then draw three cards"));
+ this.addAbility(ability);
+
+ // Escape—{R}{R}, Exile eight other cards from your graveyard.
+ this.addAbility(new EscapeAbility(this, "{R}{R}", 8));
+
+ // Ox of Agonas escapes with a +1/+1 counter on it.
+ this.addAbility(new EscapesWithAbility(1));
+ }
+
+ private OxOfAgonas(final OxOfAgonas card) {
+ super(card);
+ }
+
+ @Override
+ public OxOfAgonas copy() {
+ return new OxOfAgonas(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/p/PainfulQuandary.java b/Mage.Sets/src/mage/cards/p/PainfulQuandary.java
index c5f17b4e6cb..18b94eb6b86 100644
--- a/Mage.Sets/src/mage/cards/p/PainfulQuandary.java
+++ b/Mage.Sets/src/mage/cards/p/PainfulQuandary.java
@@ -27,7 +27,7 @@ public final class PainfulQuandary extends CardImpl {
public PainfulQuandary(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{B}{B}");
- // Whenever an opponent casts a spell, that player loses 5 life unless he or she discards a card.
+ // Whenever an opponent casts a spell, that player loses 5 life unless they discard a card.
this.addAbility(new SpellCastOpponentTriggeredAbility(Zone.BATTLEFIELD, new PainfulQuandryEffect(), StaticFilters.FILTER_SPELL, false, SetTargetPointer.PLAYER));
}
@@ -46,7 +46,7 @@ class PainfulQuandryEffect extends OneShotEffect {
public PainfulQuandryEffect() {
super(Outcome.LoseLife);
- staticText = "that player loses 5 life unless he or she discards a card";
+ staticText = "that player loses 5 life unless they discard a card";
}
public PainfulQuandryEffect(final PainfulQuandryEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/p/PalaceSiege.java b/Mage.Sets/src/mage/cards/p/PalaceSiege.java
index e73cefcb5e7..a6a6b381102 100644
--- a/Mage.Sets/src/mage/cards/p/PalaceSiege.java
+++ b/Mage.Sets/src/mage/cards/p/PalaceSiege.java
@@ -1,6 +1,6 @@
-
package mage.cards.p;
+import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.EntersBattlefieldAbility;
@@ -15,11 +15,9 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCardInYourGraveyard;
-import java.util.UUID;
-
/**
*
* @author LevelX2
@@ -28,22 +26,22 @@ public final class PalaceSiege extends CardImpl {
private static final String ruleTrigger1 = "&bull Khans — At the beginning of your upkeep, return target creature card from your graveyard to your hand.";
private static final String ruleTrigger2 = "&bull Dragons — At the beginning of your upkeep, each opponent loses 2 life and you gain 2 life.";
-
+
public PalaceSiege(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{B}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}");
// As Palace Siege enters the battlefield, choose Khans or Dragons.
- this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?","Khans", "Dragons"),null,
- "As {this} enters the battlefield, choose Khans or Dragons.",""));
-
+ this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null,
+ "As {this} enters the battlefield, choose Khans or Dragons.", ""));
+
// * Khans - At the beginning of your upkeep, return target creature card from your graveyard to your hand.
Ability ability1 = new ConditionalTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect(), TargetController.YOU, false),
new ModeChoiceSourceCondition("Khans"),
ruleTrigger1);
- ability1.addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard()));
+ ability1.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE));
this.addAbility(ability1);
-
+
// * Dragons - At the beginning of your upkeep, each opponent loses 2 life and you gain 2 life.
Ability ability2 = new ConditionalTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility(new LoseLifeOpponentsEffect(2), TargetController.YOU, false),
@@ -53,7 +51,7 @@ public final class PalaceSiege extends CardImpl {
effect.setText("and you gain 2 life");
ability2.addEffect(effect);
this.addAbility(ability2);
-
+
}
public PalaceSiege(final PalaceSiege card) {
diff --git a/Mage.Sets/src/mage/cards/p/Paleoloth.java b/Mage.Sets/src/mage/cards/p/Paleoloth.java
index a7650a5bbeb..4c137c936fa 100644
--- a/Mage.Sets/src/mage/cards/p/Paleoloth.java
+++ b/Mage.Sets/src/mage/cards/p/Paleoloth.java
@@ -1,4 +1,3 @@
-
package mage.cards.p;
import java.util.UUID;
@@ -9,10 +8,10 @@ import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.ComparisonType;
+import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.PowerPredicate;
import mage.filter.predicate.permanent.AnotherPredicate;
@@ -23,18 +22,18 @@ import mage.target.common.TargetCardInYourGraveyard;
* @author jeffwadsworth
*/
public final class Paleoloth extends CardImpl {
-
+
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature with power 5 or greater");
-
+
static {
filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 4));
filter.add(AnotherPredicate.instance);
}
-
+
private static final String rule = "Whenever another creature with power 5 or greater enters the battlefield under your control, you may return target creature card from your graveyard to your hand.";
public Paleoloth(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(5);
@@ -42,9 +41,9 @@ public final class Paleoloth extends CardImpl {
// Whenever another creature with power 5 or greater enters the battlefield under your control, you may return target creature card from your graveyard to your hand.
Ability ability = new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, new ReturnFromGraveyardToHandTargetEffect(), filter, true, rule);
- ability.addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard()));
+ ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE));
this.addAbility(ability);
-
+
}
public Paleoloth(final Paleoloth card) {
diff --git a/Mage.Sets/src/mage/cards/p/PanopticMirror.java b/Mage.Sets/src/mage/cards/p/PanopticMirror.java
index d724c32dabc..f911ddb64fe 100644
--- a/Mage.Sets/src/mage/cards/p/PanopticMirror.java
+++ b/Mage.Sets/src/mage/cards/p/PanopticMirror.java
@@ -1,4 +1,3 @@
-
package mage.cards.p;
import java.util.UUID;
@@ -84,7 +83,7 @@ class PanopticMirrorExileEffect extends OneShotEffect {
}
TargetCardInHand target = new TargetCardInHand(filter);
- if (player.choose(this.outcome, target, source.getSourceId(), game)) {
+ if (player.choose(outcome.PlayForFree, target, source.getSourceId(), game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
card.moveToExile(CardUtil.getCardExileZoneId(game, source), "Panoptic Mirror", source.getSourceId(), game);
@@ -103,7 +102,7 @@ class PanopticMirrorCastEffect extends OneShotEffect {
public PanopticMirrorCastEffect() {
super(Outcome.ReturnToHand);
- this.staticText = "you may copy a card exiled with Panoptic Mirror. If you do, you may cast the copy without paying its mana cost";
+ this.staticText = "you may copy a card exiled with {this}. If you do, you may cast the copy without paying its mana cost";
}
public PanopticMirrorCastEffect(final PanopticMirrorCastEffect effect) {
@@ -122,7 +121,10 @@ class PanopticMirrorCastEffect extends OneShotEffect {
if (PanopticMirror == null) {
PanopticMirror = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
}
- if (PanopticMirror != null && PanopticMirror.getImprinted() != null && !PanopticMirror.getImprinted().isEmpty() && controller != null) {
+ if (PanopticMirror != null
+ && PanopticMirror.getImprinted() != null
+ && !PanopticMirror.getImprinted().isEmpty()
+ && controller != null) {
CardsImpl cards = new CardsImpl();
for (UUID uuid : PanopticMirror.getImprinted()) {
Card card = game.getCard(uuid);
@@ -145,8 +147,11 @@ class PanopticMirrorCastEffect extends OneShotEffect {
}
if (cardToCopy != null) {
Card copy = game.copyCard(cardToCopy, source, source.getControllerId());
- if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
- return controller.cast(copy.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ if (controller.chooseUse(outcome.PlayForFree, "Cast the copied card without paying mana cost?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + copy.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(copy, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + copy.getId(), null);
}
}
return true;
diff --git a/Mage.Sets/src/mage/cards/p/ParallaxNexus.java b/Mage.Sets/src/mage/cards/p/ParallaxNexus.java
index 62f03c93f75..7b48c258bf6 100644
--- a/Mage.Sets/src/mage/cards/p/ParallaxNexus.java
+++ b/Mage.Sets/src/mage/cards/p/ParallaxNexus.java
@@ -39,7 +39,7 @@ public final class ParallaxNexus extends CardImpl {
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
- // When Parallax Nexus leaves the battlefield, each player returns to their hand all cards he or she owns exiled with Parallax Nexus.
+ // When Parallax Nexus leaves the battlefield, each player returns to their hand all cards they own exiled with Parallax Nexus.
this.addAbility(new LeavesBattlefieldTriggeredAbility(new ReturnFromExileEffect(exileId, Zone.HAND), false));
}
diff --git a/Mage.Sets/src/mage/cards/p/ParallaxTide.java b/Mage.Sets/src/mage/cards/p/ParallaxTide.java
index 3ea4283ef16..3798ec60ab3 100644
--- a/Mage.Sets/src/mage/cards/p/ParallaxTide.java
+++ b/Mage.Sets/src/mage/cards/p/ParallaxTide.java
@@ -32,7 +32,7 @@ public final class ParallaxTide extends CardImpl {
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetForSourceEffect(), new RemoveCountersSourceCost(CounterType.FADE.createInstance()));
ability.addTarget(new TargetLandPermanent());
this.addAbility(ability);
- // When Parallax Tide leaves the battlefield, each player returns to the battlefield all cards he or she owns exiled with Parallax Tide.
+ // When Parallax Tide leaves the battlefield, each player returns to the battlefield all cards they own exiled with Parallax Tide.
this.addAbility(new LeavesBattlefieldTriggeredAbility(new ReturnFromExileForSourceEffect(Zone.BATTLEFIELD), splitCard));
}
diff --git a/Mage.Sets/src/mage/cards/p/ParallaxWave.java b/Mage.Sets/src/mage/cards/p/ParallaxWave.java
index 2a388c151fb..abb14781395 100644
--- a/Mage.Sets/src/mage/cards/p/ParallaxWave.java
+++ b/Mage.Sets/src/mage/cards/p/ParallaxWave.java
@@ -40,7 +40,7 @@ public final class ParallaxWave extends CardImpl {
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
- // When Parallax Wave leaves the battlefield, each player returns to the battlefield all cards he or she owns exiled with Parallax Wave.
+ // When Parallax Wave leaves the battlefield, each player returns to the battlefield all cards they own exiled with Parallax Wave.
this.addAbility(new LeavesBattlefieldTriggeredAbility(new ParallaxWaveEffect(), false));
}
@@ -59,7 +59,7 @@ class ParallaxWaveEffect extends OneShotEffect {
public ParallaxWaveEffect() {
super(Outcome.Benefit);
- this.staticText = "each player returns to the battlefield all cards he or she owns exiled with {this}";
+ this.staticText = "each player returns to the battlefield all cards they own exiled with {this}";
}
public ParallaxWaveEffect(final ParallaxWaveEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/p/Paralyze.java b/Mage.Sets/src/mage/cards/p/Paralyze.java
index f8b233e31df..659e2091dcd 100644
--- a/Mage.Sets/src/mage/cards/p/Paralyze.java
+++ b/Mage.Sets/src/mage/cards/p/Paralyze.java
@@ -38,7 +38,7 @@ public final class Paralyze extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new TapEnchantedEffect()));
// Enchanted creature doesn't untap during its controller's untap step.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepEnchantedEffect()));
- // At the beginning of the upkeep of enchanted creature's controller, that player may pay {4}. If he or she does, untap the creature.
+ // At the beginning of the upkeep of enchanted creature's controller, that player may pay {4}. If they do, untap the creature.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new ParalyzeEffect(), TargetController.CONTROLLER_ATTACHED_TO, false));
}
@@ -81,6 +81,6 @@ class ParalyzeEffect extends DoIfCostPaid {
@Override
public String getText(Mode mode) {
- return "that player may " + getCostText() + ". If he or she does, " + executingEffects.getText(mode);
+ return "that player may " + getCostText() + ". If they do, " + executingEffects.getText(mode);
}
}
diff --git a/Mage.Sets/src/mage/cards/p/PatternMatcher.java b/Mage.Sets/src/mage/cards/p/PatternMatcher.java
index 61844ffa6d1..c53382c25e6 100644
--- a/Mage.Sets/src/mage/cards/p/PatternMatcher.java
+++ b/Mage.Sets/src/mage/cards/p/PatternMatcher.java
@@ -19,9 +19,9 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
-import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
+import java.util.stream.Collectors;
/**
* @author TheElk801
@@ -72,14 +72,16 @@ class RegularExpression extends OneShotEffect {
if (player == null) {
return false;
}
- List predicates = new ArrayList();
- game.getBattlefield()
- .getAllActivePermanents(
- StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, source.getControllerId(), game
+ List predicates = game
+ .getBattlefield()
+ .getActivePermanents(
+ StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE,
+ source.getControllerId(), source.getSourceId(), game
).stream()
.map(Permanent::getName)
.filter(s -> !"".equals(s))
- .forEach(s -> predicates.add(new NamePredicate(s)));
+ .map(NamePredicate::new)
+ .collect(Collectors.toList());
FilterCard filter
= new FilterCard("a creature card with the same name as another creature you control");
filter.add(Predicates.or(predicates));
diff --git a/Mage.Sets/src/mage/cards/p/PatternOfRebirth.java b/Mage.Sets/src/mage/cards/p/PatternOfRebirth.java
index 8184f1d0602..24344395630 100644
--- a/Mage.Sets/src/mage/cards/p/PatternOfRebirth.java
+++ b/Mage.Sets/src/mage/cards/p/PatternOfRebirth.java
@@ -1,5 +1,6 @@
package mage.cards.p;
+import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.DiesAttachedTriggeredAbility;
import mage.abilities.effects.Effect;
@@ -12,13 +13,11 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SetTargetPointer;
import mage.constants.SubType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.target.TargetPermanent;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetCreaturePermanent;
-import java.util.UUID;
-
/**
* @author LevelX2
*/
@@ -35,9 +34,9 @@ public final class PatternOfRebirth extends CardImpl {
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
- // When enchanted creature dies, that creature's controller may search their library for a creature card and put that card onto the battlefield. If that player does, he or she shuffles their library.
- Effect effect = new SearchLibraryPutInPlayTargetPlayerEffect(new TargetCardInLibrary(new FilterCreatureCard()), false, false, Outcome.PutCreatureInPlay);
- effect.setText("that creature's controller may search their library for a creature card and put that card onto the battlefield. If that player does, he or she shuffles their library");
+ // When enchanted creature dies, that creature's controller may search their library for a creature card and put that card onto the battlefield. If that player does, they shuffle their library.
+ Effect effect = new SearchLibraryPutInPlayTargetPlayerEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_CREATURE), false, false, Outcome.PutCreatureInPlay);
+ effect.setText("that creature's controller may search their library for a creature card and put that card onto the battlefield. If that player does, they shuffle their library");
this.addAbility(new DiesAttachedTriggeredAbility(effect, "enchanted creature", true, true, SetTargetPointer.ATTACHED_TO_CONTROLLER));
}
diff --git a/Mage.Sets/src/mage/cards/p/PaupersCage.java b/Mage.Sets/src/mage/cards/p/PaupersCage.java
index fcfad9135d9..f267989e36c 100644
--- a/Mage.Sets/src/mage/cards/p/PaupersCage.java
+++ b/Mage.Sets/src/mage/cards/p/PaupersCage.java
@@ -23,12 +23,12 @@ public final class PaupersCage extends CardImpl {
public PaupersCage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
- // At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, Paupers' Cage deals 2 damage to him or her.
+ // At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, Paupers' Cage deals 2 damage to that player.
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
new DamageTargetEffect(2), TargetController.OPPONENT, false, true);
CardsInHandCondition condition = new CardsInHandCondition(ComparisonType.FEWER_THAN, 3, null, TargetController.ACTIVE);
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, condition,
- "At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, {this} deals 2 damage to him or her."));
+ "At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, {this} deals 2 damage to that player."));
}
public PaupersCage(final PaupersCage card) {
diff --git a/Mage.Sets/src/mage/cards/p/PeaceTalks.java b/Mage.Sets/src/mage/cards/p/PeaceTalks.java
index e50bbf11e3a..bff35048f32 100644
--- a/Mage.Sets/src/mage/cards/p/PeaceTalks.java
+++ b/Mage.Sets/src/mage/cards/p/PeaceTalks.java
@@ -142,7 +142,7 @@ class PeaceTalksPlayersAndPermanentsCantBeTargetsOfSpellsOrActivatedAbilities ex
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
- for (UUID playerId : game.getPlayer(source.getControllerId()).getInRange()) {
+ for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
if (event.getTargetId().equals(playerId)) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/p/PerniciousDeed.java b/Mage.Sets/src/mage/cards/p/PerniciousDeed.java
index c539cfb2e55..0654ce7a44f 100644
--- a/Mage.Sets/src/mage/cards/p/PerniciousDeed.java
+++ b/Mage.Sets/src/mage/cards/p/PerniciousDeed.java
@@ -1,4 +1,3 @@
-
package mage.cards.p;
import java.util.UUID;
@@ -7,6 +6,7 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DestroyAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -18,18 +18,15 @@ import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
-import mage.game.permanent.Permanent;
/**
* @author Plopman
*/
public final class PerniciousDeed extends CardImpl {
-
public PerniciousDeed(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{G}");
-
// {X}, Sacrifice Pernicious Deed: Destroy each artifact, creature, and enchantment with converted mana cost X or less.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PerniciousDeedEffect(), new VariableManaCost());
ability.addCost(new SacrificeSourceCost());
@@ -46,16 +43,13 @@ public final class PerniciousDeed extends CardImpl {
}
}
-
class PerniciousDeedEffect extends OneShotEffect {
-
public PerniciousDeedEffect() {
super(Outcome.DestroyPermanent);
staticText = "Destroy each artifact, creature, and enchantment with converted mana cost X or less";
}
-
public PerniciousDeedEffect(final PerniciousDeedEffect effect) {
super(effect);
}
@@ -68,21 +62,15 @@ class PerniciousDeedEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
-
FilterPermanent filter = new FilterPermanent("artifacts, creatures, and enchantments");
-
filter.add(Predicates.or(
new CardTypePredicate(CardType.ARTIFACT),
new CardTypePredicate(CardType.CREATURE),
new CardTypePredicate(CardType.ENCHANTMENT)));
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, source.getManaCostsToPay().getX() + 1));
-
- for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
- permanent.destroy(source.getSourceId(), game, false);
- }
- return true;
+ return new DestroyAllEffect(filter).apply(game, source);
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/p/PersonalSanctuary.java b/Mage.Sets/src/mage/cards/p/PersonalSanctuary.java
index 2a0cdb373b8..56a263d736d 100644
--- a/Mage.Sets/src/mage/cards/p/PersonalSanctuary.java
+++ b/Mage.Sets/src/mage/cards/p/PersonalSanctuary.java
@@ -1,7 +1,5 @@
-
package mage.cards.p;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.PreventionEffectImpl;
@@ -11,16 +9,19 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
+
+import java.util.UUID;
/**
- *
* @author nantuko
*/
public final class PersonalSanctuary extends CardImpl {
public PersonalSanctuary(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
// During your turn, prevent all damage that would be dealt to you.
@@ -50,7 +51,7 @@ class PersonalSanctuaryEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
event.setAmount(0);
diff --git a/Mage.Sets/src/mage/cards/p/PharikaGodOfAffliction.java b/Mage.Sets/src/mage/cards/p/PharikaGodOfAffliction.java
index cc4d1a0697e..eb33899f32b 100644
--- a/Mage.Sets/src/mage/cards/p/PharikaGodOfAffliction.java
+++ b/Mage.Sets/src/mage/cards/p/PharikaGodOfAffliction.java
@@ -1,14 +1,11 @@
-
package mage.cards.p;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.DevotionCount;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
import mage.abilities.keyword.IndestructibleAbility;
@@ -20,15 +17,17 @@ import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.game.permanent.token.PharikaSnakeToken;
import mage.players.Player;
-import mage.target.Target;
import mage.target.common.TargetCardInGraveyard;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class PharikaGodOfAffliction extends CardImpl {
+ private static final FilterCreatureCard filter = new FilterCreatureCard("a creature card from a graveyard");
+
public PharikaGodOfAffliction(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{B}{G}");
addSuperType(SuperType.LEGENDARY);
@@ -39,14 +38,14 @@ public final class PharikaGodOfAffliction extends CardImpl {
// Indestructible
this.addAbility(IndestructibleAbility.getInstance());
+
// As long as your devotion to black and green is less than seven, Pharika isn't a creature.
- Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.B, ColoredManaSymbol.G), 7);
- effect.setText("As long as your devotion to black and green is less than seven, Pharika isn't a creature");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.BG, 7))
+ .addHint(DevotionCount.BG.getHint()));
+
// {B}{G}: Exile target creature card from a graveyard. It's owner creates a 1/1 black and green Snake enchantment creature token with deathtouch.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PharikaExileEffect(), new ManaCostsImpl("{B}{G}"));
- Target target = new TargetCardInGraveyard(new FilterCreatureCard("a creature card from a graveyard"));
- ability.addTarget(target);
+ Ability ability = new SimpleActivatedAbility(new PharikaExileEffect(), new ManaCostsImpl("{B}{G}"));
+ ability.addTarget(new TargetCardInGraveyard(filter));
this.addAbility(ability);
}
@@ -63,31 +62,33 @@ public final class PharikaGodOfAffliction extends CardImpl {
class PharikaExileEffect extends OneShotEffect {
- public PharikaExileEffect() {
+ PharikaExileEffect() {
super(Outcome.PutCreatureInPlay);
staticText = "Exile target creature card from a graveyard. Its owner creates a 1/1 black and green Snake enchantment creature token with deathtouch";
}
- public PharikaExileEffect(final PharikaExileEffect effect) {
+ private PharikaExileEffect(final PharikaExileEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- Card targetCard = game.getCard(source.getFirstTarget());
- if (targetCard != null) {
- if (game.getState().getZone(source.getFirstTarget()) == Zone.GRAVEYARD) {
- controller.moveCardToExileWithInfo(targetCard, null, "", source.getSourceId(), game, Zone.GRAVEYARD, true);
- }
- Player tokenController = game.getPlayer(targetCard.getOwnerId());
- if (tokenController != null) {
- return new PharikaSnakeToken().putOntoBattlefield(1, game, source.getSourceId(), tokenController.getId());
- }
- }
+ if (controller == null) {
+ return false;
}
- return false;
+ Card targetCard = game.getCard(source.getFirstTarget());
+ if (targetCard == null) {
+ return false;
+ }
+ if (game.getState().getZone(source.getFirstTarget()) == Zone.GRAVEYARD) {
+ controller.moveCards(targetCard, Zone.EXILED, source, game);
+ }
+ Player tokenController = game.getPlayer(targetCard.getOwnerId());
+ if (tokenController == null) {
+ return false;
+ }
+ return new PharikaSnakeToken().putOntoBattlefield(1, game, source.getSourceId(), tokenController.getId());
}
@Override
diff --git a/Mage.Sets/src/mage/cards/p/PhenaxGodOfDeception.java b/Mage.Sets/src/mage/cards/p/PhenaxGodOfDeception.java
index 56a5663f6fd..ec36c25ab34 100644
--- a/Mage.Sets/src/mage/cards/p/PhenaxGodOfDeception.java
+++ b/Mage.Sets/src/mage/cards/p/PhenaxGodOfDeception.java
@@ -1,7 +1,5 @@
-
package mage.cards.p;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -9,25 +7,28 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.dynamicvalue.common.DevotionCount;
import mage.abilities.dynamicvalue.common.SourcePermanentToughnessValue;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.target.TargetPlayer;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class PhenaxGodOfDeception extends CardImpl {
public PhenaxGodOfDeception(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{3}{U}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{3}{U}{B}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.GOD);
@@ -36,21 +37,26 @@ public final class PhenaxGodOfDeception extends CardImpl {
// Indestructible
this.addAbility(IndestructibleAbility.getInstance());
+
// As long as your devotion to blue and black is less than seven, Phenax isn't a creature.
- Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.U, ColoredManaSymbol.B), 7);
- effect.setText("As long as your devotion to blue and black is less than seven, Phenax isn't a creature");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.UB, 7))
+ .addHint(DevotionCount.UB.getHint()));
+
// Creatures you control have "{T}: Target player puts the top X cards of their library into their graveyard, where X is this creature's toughness."
- effect = new PutTopCardOfLibraryIntoGraveTargetEffect(SourcePermanentToughnessValue.getInstance());
- effect.setText("Target player puts the top X cards of their library into their graveyard, where X is this creature's toughness");
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost());
+ Ability ability = new SimpleActivatedAbility(
+ new PutTopCardOfLibraryIntoGraveTargetEffect(SourcePermanentToughnessValue.getInstance())
+ .setText("Target player puts the top X cards of their library into their graveyard, " +
+ "where X is this creature's toughness"), new TapSourceCost());
ability.addTarget(new TargetPlayer());
- effect = new GainAbilityControlledEffect(ability, Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES,false);
- effect.setText("Creatures you control have \"{T}: Target player puts the top X cards of their library into their graveyard, where X is this creature's toughness.\"");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ this.addAbility(new SimpleStaticAbility(
+ new GainAbilityControlledEffect(
+ ability, Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES, false
+ ).setText("Creatures you control have \"{T}: Target player puts the top X cards of their library " +
+ "into their graveyard, where X is this creature's toughness.\"")
+ ));
}
- public PhenaxGodOfDeception(final PhenaxGodOfDeception card) {
+ private PhenaxGodOfDeception(final PhenaxGodOfDeception card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianHydra.java b/Mage.Sets/src/mage/cards/p/PhyrexianHydra.java
index a1ca5c20d1e..390f8a5ca61 100644
--- a/Mage.Sets/src/mage/cards/p/PhyrexianHydra.java
+++ b/Mage.Sets/src/mage/cards/p/PhyrexianHydra.java
@@ -1,8 +1,5 @@
-
-
package mage.cards.p;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
@@ -11,22 +8,25 @@ import mage.abilities.keyword.InfectAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
+import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.game.permanent.Permanent;
+import java.util.UUID;
+
/**
- *
* @author BetaSteward_at_googlemail.com
*/
public final class PhyrexianHydra extends CardImpl {
public PhyrexianHydra(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}");
this.subtype.add(SubType.HYDRA);
this.power = new MageInt(7);
@@ -71,7 +71,7 @@ class PhyrexianHydraEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
boolean retValue = false;
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
int damage = event.getAmount();
if (!game.replaceEvent(preventEvent)) {
event.setAmount(0);
@@ -88,9 +88,7 @@ class PhyrexianHydraEffect extends PreventionEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
- if (event.getTargetId().equals(source.getSourceId())) {
- return true;
- }
+ return event.getTargetId().equals(source.getSourceId());
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java b/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java
index 7657b358f1a..819aa094f1d 100644
--- a/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java
+++ b/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java
@@ -27,7 +27,7 @@ public final class PhyrexianTyranny extends CardImpl {
public PhyrexianTyranny(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{B}{R}");
- // Whenever a player draws a card, that player loses 2 life unless he or she pays {2}.
+ // Whenever a player draws a card, that player loses 2 life unless they pay {2}.
this.addAbility(new PhyrexianTyrannyTriggeredAbility());
}
@@ -73,7 +73,7 @@ class PhyrexianTyrannyTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
- return "Whenever a player draws a card, that player loses 2 life unless he or she pays {2}.";
+ return "Whenever a player draws a card, that player loses 2 life unless they pay {2}.";
}
}
@@ -81,7 +81,7 @@ class PhyrexianTyrannyEffect extends OneShotEffect {
PhyrexianTyrannyEffect() {
super(Outcome.Neutral);
- this.staticText = "that player loses 2 life unless he or she pays {2}";
+ this.staticText = "that player loses 2 life unless they pay {2}";
}
PhyrexianTyrannyEffect(final PhyrexianTyrannyEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/p/PiasRevolution.java b/Mage.Sets/src/mage/cards/p/PiasRevolution.java
index 8580678631c..b665e8a9225 100644
--- a/Mage.Sets/src/mage/cards/p/PiasRevolution.java
+++ b/Mage.Sets/src/mage/cards/p/PiasRevolution.java
@@ -32,7 +32,7 @@ public final class PiasRevolution extends CardImpl {
public PiasRevolution(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
- // Whenever a nontoken artifact is put into your graveyard from the battlefield, return that card to your hand unless target opponent has Pia's Revolution deal 3 damage to him or her.
+ // Whenever a nontoken artifact is put into your graveyard from the battlefield, return that card to your hand unless target opponent has Pia's Revolution deal 3 damage to them.
Ability ability = new PiasRevolutionTriggeredAbility();
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
@@ -52,7 +52,7 @@ class PiasRevolutionReturnEffect extends OneShotEffect {
public PiasRevolutionReturnEffect() {
super(Outcome.Benefit);
- this.staticText = "return that card to your hand unless target opponent has {this} deal 3 damage to him or her";
+ this.staticText = "return that card to your hand unless target opponent has {this} deal 3 damage to them";
}
public PiasRevolutionReturnEffect(final PiasRevolutionReturnEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/p/PilgrimOfJustice.java b/Mage.Sets/src/mage/cards/p/PilgrimOfJustice.java
index 3f2887bf106..728b63f2262 100644
--- a/Mage.Sets/src/mage/cards/p/PilgrimOfJustice.java
+++ b/Mage.Sets/src/mage/cards/p/PilgrimOfJustice.java
@@ -1,7 +1,5 @@
-
package mage.cards.p;
-import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
@@ -12,25 +10,24 @@ import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.filter.FilterObject;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.target.TargetSource;
+import java.util.UUID;
+
/**
- *
* @author cbt33, Plopman (Circle of Protection: Red)
*/
public final class PilgrimOfJustice extends CardImpl {
-
+
public PilgrimOfJustice(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.CLERIC);
@@ -58,15 +55,17 @@ public final class PilgrimOfJustice extends CardImpl {
class PilgrimOfJusticeEffect extends PreventionEffectImpl {
private static final FilterObject filter = new FilterObject("red source");
- static{
+
+ static {
filter.add(new ColorPredicate(ObjectColor.RED));
}
+
private TargetSource target;
public PilgrimOfJusticeEffect() {
super(Duration.EndOfTurn);
target = new TargetSource(filter);
-
+
staticText = "The next time a red source of your choice would deal damage to you this turn, prevent that damage";
}
@@ -100,7 +99,7 @@ class PilgrimOfJusticeEffect extends PreventionEffectImpl {
}
private void preventDamage(GameEvent event, Ability source, UUID target, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, target, source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(target, source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
event.setAmount(0);
@@ -112,9 +111,7 @@ class PilgrimOfJusticeEffect extends PreventionEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!this.used && super.applies(event, source, game)) {
- if (event.getTargetId().equals(source.getControllerId()) && event.getSourceId().equals(target.getFirstTarget())) {
- return true;
- }
+ return event.getTargetId().equals(source.getControllerId()) && event.getSourceId().equals(target.getFirstTarget());
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/p/PilgrimOfVirtue.java b/Mage.Sets/src/mage/cards/p/PilgrimOfVirtue.java
index 7e989ecbc1f..6dc3426496c 100644
--- a/Mage.Sets/src/mage/cards/p/PilgrimOfVirtue.java
+++ b/Mage.Sets/src/mage/cards/p/PilgrimOfVirtue.java
@@ -1,7 +1,5 @@
-
package mage.cards.p;
-import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
@@ -12,25 +10,24 @@ import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.filter.FilterObject;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.target.TargetSource;
+import java.util.UUID;
+
/**
- *
* @author cbt33, Plopman (Circle of Protection: Red)
*/
public final class PilgrimOfVirtue extends CardImpl {
public PilgrimOfVirtue(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.CLERIC);
@@ -62,6 +59,7 @@ class PilgrimOfVirtueEffect extends PreventionEffectImpl {
static {
filter.add(new ColorPredicate(ObjectColor.BLACK));
}
+
private final TargetSource target;
public PilgrimOfVirtueEffect() {
@@ -101,7 +99,7 @@ class PilgrimOfVirtueEffect extends PreventionEffectImpl {
}
private void preventDamage(GameEvent event, Ability source, UUID target, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, target, source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(target, source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
event.setAmount(0);
@@ -113,9 +111,7 @@ class PilgrimOfVirtueEffect extends PreventionEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!this.used && super.applies(event, source, game)) {
- if (event.getTargetId().equals(source.getControllerId()) && event.getSourceId().equals(target.getFirstTarget())) {
- return true;
- }
+ return event.getTargetId().equals(source.getControllerId()) && event.getSourceId().equals(target.getFirstTarget());
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/p/PillarTombsOfAku.java b/Mage.Sets/src/mage/cards/p/PillarTombsOfAku.java
index acaef90f970..34da48fed86 100644
--- a/Mage.Sets/src/mage/cards/p/PillarTombsOfAku.java
+++ b/Mage.Sets/src/mage/cards/p/PillarTombsOfAku.java
@@ -28,7 +28,7 @@ public final class PillarTombsOfAku extends CardImpl {
this.addSuperType(SuperType.WORLD);
- // At the beginning of each player's upkeep, that player may sacrifice a creature. If that player doesn't, he or she loses 5 life and you sacrifice Pillar Tombs of Aku.
+ // At the beginning of each player's upkeep, that player may sacrifice a creature. If that player doesn't, they lose 5 life and you sacrifice Pillar Tombs of Aku.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
new PillarTombsOfAkuEffect(),
TargetController.ANY,
diff --git a/Mage.Sets/src/mage/cards/p/PiperOfTheSwarm.java b/Mage.Sets/src/mage/cards/p/PiperOfTheSwarm.java
new file mode 100644
index 00000000000..028bd0c5c15
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/p/PiperOfTheSwarm.java
@@ -0,0 +1,74 @@
+package mage.cards.p;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
+import mage.abilities.effects.common.continuous.GainControlTargetEffect;
+import mage.abilities.keyword.MenaceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.game.permanent.token.RatToken;
+import mage.target.common.TargetControlledPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class PiperOfTheSwarm extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterCreaturePermanent(SubType.RAT, "Rats");
+ private static final FilterControlledPermanent filter2 = new FilterControlledPermanent(SubType.RAT, "Rats");
+
+ public PiperOfTheSwarm(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.WARLOCK);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(3);
+
+ // Rats you control have menace.
+ this.addAbility(new SimpleStaticAbility(
+ new GainAbilityControlledEffect(new MenaceAbility(), Duration.WhileOnBattlefield, filter)
+ ));
+
+ // {1}{B}, {T}: Create a 1/1 black Rat creature token.
+ Ability ability = new SimpleActivatedAbility(
+ new CreateTokenEffect(new RatToken()), new ManaCostsImpl("{1}{B}")
+ );
+ ability.addCost(new TapSourceCost());
+ this.addAbility(ability);
+
+ // {2}{B}{B}, {T}, Sacrifice three Rats: Gain control of target creature.
+ ability = new SimpleActivatedAbility(
+ new GainControlTargetEffect(Duration.Custom), new ManaCostsImpl("{2}{B}{B}")
+ );
+ ability.addCost(new TapSourceCost());
+ ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(3, filter2)));
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+ }
+
+ private PiperOfTheSwarm(final PiperOfTheSwarm card) {
+ super(card);
+ }
+
+ @Override
+ public PiperOfTheSwarm copy() {
+ return new PiperOfTheSwarm(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/p/PitKeeper.java b/Mage.Sets/src/mage/cards/p/PitKeeper.java
index ce51141cf77..00834f6622a 100644
--- a/Mage.Sets/src/mage/cards/p/PitKeeper.java
+++ b/Mage.Sets/src/mage/cards/p/PitKeeper.java
@@ -1,4 +1,3 @@
-
package mage.cards.p;
import java.util.UUID;
@@ -14,7 +13,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
@@ -62,7 +60,7 @@ class CreatureCardsInControllerGraveCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
Player p = game.getPlayer(source.getControllerId());
- if (p != null && p.getGraveyard().count(new FilterCreatureCard(), game) >= value) {
+ if (p != null && p.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game) >= value) {
return true;
}
return false;
diff --git a/Mage.Sets/src/mage/cards/p/PlagueOfVermin.java b/Mage.Sets/src/mage/cards/p/PlagueOfVermin.java
index 0a5dd16f1ee..59a53a9367d 100644
--- a/Mage.Sets/src/mage/cards/p/PlagueOfVermin.java
+++ b/Mage.Sets/src/mage/cards/p/PlagueOfVermin.java
@@ -25,7 +25,7 @@ public final class PlagueOfVermin extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{6}{B}");
- // Starting with you, each player may pay any amount of life. Repeat this process until no one pays life. Each player creates a 1/1 black Rat creature token for each 1 life he or she paid this way.
+ // Starting with you, each player may pay any amount of life. Repeat this process until no one pays life. Each player creates a 1/1 black Rat creature token for each 1 life they paid this way.
this.getSpellAbility().addEffect(new PlagueOfVerminEffect());
}
@@ -44,7 +44,7 @@ class PlagueOfVerminEffect extends OneShotEffect {
public PlagueOfVerminEffect() {
super(Outcome.PutCardInPlay);
- this.staticText = "Starting with you, each player may pay any amount of life. Repeat this process until no one pays life. Each player creates a 1/1 black Rat creature token for each 1 life he or she paid this way.";
+ this.staticText = "Starting with you, each player may pay any amount of life. Repeat this process until no one pays life. Each player creates a 1/1 black Rat creature token for each 1 life they paid this way.";
}
public PlagueOfVerminEffect(final PlagueOfVerminEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/p/PlanarChaos.java b/Mage.Sets/src/mage/cards/p/PlanarChaos.java
index 863a0d0d4a0..988ca68454e 100644
--- a/Mage.Sets/src/mage/cards/p/PlanarChaos.java
+++ b/Mage.Sets/src/mage/cards/p/PlanarChaos.java
@@ -32,7 +32,7 @@ public final class PlanarChaos extends CardImpl {
// At the beginning of your upkeep, flip a coin. If you lose the flip, sacrifice Planar Chaos.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new PlanarChaosUpkeepEffect(), TargetController.YOU, false));
- // Whenever a player casts a spell, that player flips a coin. If he or she loses the flip, counter that spell.
+ // Whenever a player casts a spell, that player flips a coin. If they lose the flip, counter that spell.
this.addAbility(new SpellCastAllTriggeredAbility(new PlanarChaosCastAllEffect(), new FilterSpell("a spell"), false, SetTargetPointer.SPELL));
}
@@ -82,7 +82,7 @@ class PlanarChaosCastAllEffect extends OneShotEffect {
public PlanarChaosCastAllEffect() {
super(Outcome.Benefit);
- this.staticText = "that player flips a coin. If he or she loses the flip, counter that spell";
+ this.staticText = "that player flips a coin. If they lose the flip, counter that spell";
}
public PlanarChaosCastAllEffect(final PlanarChaosCastAllEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/p/PlanarOverlay.java b/Mage.Sets/src/mage/cards/p/PlanarOverlay.java
index d7d8681eec7..ced5f87121f 100644
--- a/Mage.Sets/src/mage/cards/p/PlanarOverlay.java
+++ b/Mage.Sets/src/mage/cards/p/PlanarOverlay.java
@@ -26,7 +26,7 @@ public final class PlanarOverlay extends CardImpl {
public PlanarOverlay(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}");
- // Each player chooses a land he or she controls of each basic land type. Return those lands to their owners' hands.
+ // Each player chooses a land they control of each basic land type. Return those lands to their owners' hands.
this.getSpellAbility().addEffect(new PlanarOverlayEffect());
}
@@ -44,7 +44,7 @@ class PlanarOverlayEffect extends OneShotEffect {
public PlanarOverlayEffect() {
super(Outcome.ReturnToHand);
- this.staticText = "Each player chooses a land he or she controls of each basic land type. Return those lands to their owners' hands";
+ this.staticText = "Each player chooses a land they control of each basic land type. Return those lands to their owners' hands";
}
public PlanarOverlayEffect(final PlanarOverlayEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/p/PlasmCapture.java b/Mage.Sets/src/mage/cards/p/PlasmCapture.java
index bde6f8c3c5a..3a1c278e761 100644
--- a/Mage.Sets/src/mage/cards/p/PlasmCapture.java
+++ b/Mage.Sets/src/mage/cards/p/PlasmCapture.java
@@ -4,12 +4,11 @@ package mage.cards.p;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
-import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.delayed.AtTheBeginOfMainPhaseDelayedTriggeredAbility;
import mage.abilities.common.delayed.AtTheBeginOfMainPhaseDelayedTriggeredAbility.PhaseSelection;
+import mage.abilities.effects.mana.AddManaInAnyCombinationEffect;
import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.ManaEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceColor;
@@ -19,7 +18,6 @@ import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.game.Game;
import mage.game.stack.Spell;
-import mage.players.Player;
import mage.target.TargetSpell;
/**
@@ -70,44 +68,10 @@ class PlasmCaptureCounterEffect extends OneShotEffect {
// mana gets added also if counter is not successful
int mana = spell.getConvertedManaCost();
AtTheBeginOfMainPhaseDelayedTriggeredAbility delayedAbility
- = new AtTheBeginOfMainPhaseDelayedTriggeredAbility(new PlasmCaptureManaEffect(mana), false, TargetController.YOU, PhaseSelection.NEXT_PRECOMBAT_MAIN);
+ = new AtTheBeginOfMainPhaseDelayedTriggeredAbility(new AddManaInAnyCombinationEffect(mana), false, TargetController.YOU, PhaseSelection.NEXT_PRECOMBAT_MAIN);
game.addDelayedTriggeredAbility(delayedAbility, source);
return true;
}
return false;
}
-}
-
-class PlasmCaptureManaEffect extends ManaEffect {
-
- int amountOfMana;
-
- public PlasmCaptureManaEffect(int amountOfMana) {
- super();
- this.amountOfMana = amountOfMana;
- this.staticText = "add X mana in any combination of colors, where X is that spell's converted mana cost";
- }
-
- public PlasmCaptureManaEffect(final PlasmCaptureManaEffect effect) {
- super(effect);
- this.amountOfMana = effect.amountOfMana;
- }
-
- @Override
- public PlasmCaptureManaEffect copy() {
- return new PlasmCaptureManaEffect(this);
- }
-
- @Override
- public Mana produceMana(Game game, Ability source) {
- Player player = getPlayer(game, source);
- return ManaChoice.chooseAnyColor(player, game, amountOfMana);
- }
-
- @Override
- public List getNetMana(Game game, Ability source) {
- List netMana = new ArrayList<>();
- netMana.add(new Mana(0, 0, 0, 0, 0, 0, amountOfMana, 0));
- return netMana;
- }
-}
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/p/PollenbrightWings.java b/Mage.Sets/src/mage/cards/p/PollenbrightWings.java
index 921f6a4a2b2..ce7ab74f198 100644
--- a/Mage.Sets/src/mage/cards/p/PollenbrightWings.java
+++ b/Mage.Sets/src/mage/cards/p/PollenbrightWings.java
@@ -66,7 +66,6 @@ class PollenbrightWingsAbility extends TriggeredAbilityImpl {
public PollenbrightWingsAbility() {
super(Zone.BATTLEFIELD, new PollenbrightWingsEffect());
- this.addEffect(new UntapAllLandsControllerEffect());
}
public PollenbrightWingsAbility(final PollenbrightWingsAbility ability) {
diff --git a/Mage.Sets/src/mage/cards/p/Polymorph.java b/Mage.Sets/src/mage/cards/p/Polymorph.java
index bebaafa8946..9e3a7446cfb 100644
--- a/Mage.Sets/src/mage/cards/p/Polymorph.java
+++ b/Mage.Sets/src/mage/cards/p/Polymorph.java
@@ -31,7 +31,7 @@ public final class Polymorph extends CardImpl {
// Destroy target creature. It can't be regenerated.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new DestroyTargetEffect(true));
- // Its controller reveals cards from the top of their library until he or she reveals a creature card.
+ // Its controller reveals cards from the top of their library until they reveal a creature card.
// The player puts that card onto the battlefield, then shuffles all other cards revealed this way into their library.
this.getSpellAbility().addEffect(new PolymorphEffect());
}
@@ -50,7 +50,7 @@ class PolymorphEffect extends OneShotEffect {
public PolymorphEffect() {
super(Outcome.PutCreatureInPlay);
- this.staticText = "Its controller reveals cards from the top of their library until he or she reveals a creature card. The player puts that card onto the battlefield, then shuffles all other cards revealed this way into their library";
+ this.staticText = "Its controller reveals cards from the top of their library until they reveal a creature card. The player puts that card onto the battlefield, then shuffles all other cards revealed this way into their library";
}
public PolymorphEffect(final PolymorphEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/p/PossessedPortal.java b/Mage.Sets/src/mage/cards/p/PossessedPortal.java
index c970a34258d..87347da971d 100644
--- a/Mage.Sets/src/mage/cards/p/PossessedPortal.java
+++ b/Mage.Sets/src/mage/cards/p/PossessedPortal.java
@@ -34,7 +34,7 @@ public final class PossessedPortal extends CardImpl {
// If a player would draw a card, that player skips that draw instead.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PossessedPortalReplacementEffect()));
- // At the beginning of each end step, each player sacrifices a permanent unless he or she discards a card.
+ // At the beginning of each end step, each player sacrifices a permanent unless they discard a card.
this.addAbility(new BeginningOfEndStepTriggeredAbility(new PossessedPortalEffect(), TargetController.ANY, false));
}
@@ -84,7 +84,7 @@ class PossessedPortalEffect extends OneShotEffect {
PossessedPortalEffect() {
super(Outcome.Benefit);
- this.staticText = "each player sacrifices a permanent unless he or she discards a card";
+ this.staticText = "each player sacrifices a permanent unless they discard a card";
}
PossessedPortalEffect(final PossessedPortalEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/p/PossibilityStorm.java b/Mage.Sets/src/mage/cards/p/PossibilityStorm.java
index fd2f71b651e..998707e955d 100644
--- a/Mage.Sets/src/mage/cards/p/PossibilityStorm.java
+++ b/Mage.Sets/src/mage/cards/p/PossibilityStorm.java
@@ -35,8 +35,8 @@ public final class PossibilityStorm extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}{R}");
// Whenever a player casts a spell from their hand, that player exiles it, then exiles cards from
- // the top of their library until he or she exiles a card that shares a card type with it. That
- // player may cast that card without paying its mana cost. Then he or she puts all cards exiled with
+ // the top of their library until they exile a card that shares a card type with it. That
+ // player may cast that card without paying its mana cost. Then they put all cards exiled with
// Possibility Storm on the bottom of their library in a random order.
this.addAbility(new PossibilityStormTriggeredAbility());
}
@@ -95,7 +95,7 @@ class PossibilityStormEffect extends OneShotEffect {
public PossibilityStormEffect() {
super(Outcome.Neutral);
- staticText = "that player exiles it, then exiles cards from the top of their library until he or she exiles a card that shares a card type with it. That player may cast that card without paying its mana cost. Then he or she puts all cards exiled with {this} on the bottom of their library in a random order";
+ staticText = "that player exiles it, then exiles cards from the top of their library until they exile a card that shares a card type with it. That player may cast that card without paying its mana cost. Then they put all cards exiled with {this} on the bottom of their library in a random order";
}
public PossibilityStormEffect(final PossibilityStormEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/p/PowerSink.java b/Mage.Sets/src/mage/cards/p/PowerSink.java
index d34172db061..08e7e1b5c0a 100644
--- a/Mage.Sets/src/mage/cards/p/PowerSink.java
+++ b/Mage.Sets/src/mage/cards/p/PowerSink.java
@@ -82,7 +82,7 @@ class PowerSinkCounterUnlessPaysEffect extends OneShotEffect {
// Counter target spell unless its controller pays {X}
game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game);
- // that player taps all lands with mana abilities he or she controls...
+ // that player taps all lands with mana abilities they control...
List lands = game.getBattlefield().getAllActivePermanents(new FilterLandPermanent(), player.getId(), game);
for (Permanent land : lands) {
Abilities landAbilities = land.getAbilities();
diff --git a/Mage.Sets/src/mage/cards/p/PowerSurge.java b/Mage.Sets/src/mage/cards/p/PowerSurge.java
index dd2ee01afdd..2d3396ce2f9 100644
--- a/Mage.Sets/src/mage/cards/p/PowerSurge.java
+++ b/Mage.Sets/src/mage/cards/p/PowerSurge.java
@@ -31,7 +31,7 @@ public final class PowerSurge extends CardImpl {
public PowerSurge(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}{R}");
- // At the beginning of each player's upkeep, Power Surge deals X damage to that player, where X is the number of untapped lands he or she controlled at the beginning of this turn.
+ // At the beginning of each player's upkeep, Power Surge deals X damage to that player, where X is the number of untapped lands they controlled at the beginning of this turn.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new PowerSurgeDamageEffect(), TargetController.ANY, false, true), new PowerSurgeWatcher());
}
@@ -57,7 +57,7 @@ class PowerSurgeDamageEffect extends OneShotEffect {
@Override
public String getText(Mode mode) {
- return "{this} deals X damage to that player where X is the number of untapped lands he or she controlled at the beginning of this turn";
+ return "{this} deals X damage to that player where X is the number of untapped lands they controlled at the beginning of this turn";
}
@Override
diff --git a/Mage.Sets/src/mage/cards/p/PowerTaint.java b/Mage.Sets/src/mage/cards/p/PowerTaint.java
index c985eabd112..29eed920977 100644
--- a/Mage.Sets/src/mage/cards/p/PowerTaint.java
+++ b/Mage.Sets/src/mage/cards/p/PowerTaint.java
@@ -38,9 +38,9 @@ public final class PowerTaint extends CardImpl {
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
- // At the beginning of the upkeep of enchanted enchantment's controller, that player loses 2 life unless he or she pays {2}.
+ // At the beginning of the upkeep of enchanted enchantment's controller, that player loses 2 life unless they pay {2}.
Effect effect = new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new LoseLifeTargetEffect(2),
- new ManaCostsImpl("{2}"), "that player loses 2 life unless he or she pays {2}");
+ new ManaCostsImpl("{2}"), "that player loses 2 life unless they pay {2}");
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, effect,
TargetController.CONTROLLER_ATTACHED_TO, false, true,
"At the beginning of the upkeep of enchanted enchantment's controller, "));
diff --git a/Mage.Sets/src/mage/cards/p/Pox.java b/Mage.Sets/src/mage/cards/p/Pox.java
index f1c96ba39f2..8bec2346935 100644
--- a/Mage.Sets/src/mage/cards/p/Pox.java
+++ b/Mage.Sets/src/mage/cards/p/Pox.java
@@ -25,7 +25,7 @@ public final class Pox extends CardImpl {
public Pox(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}{B}{B}");
- // Each player loses a third of their life, then discards a third of the cards in their hand, then sacrifices a third of the creatures he or she controls, then sacrifices a third of the lands he or she controls. Round up each time.
+ // Each player loses a third of their life, then discards a third of the cards in their hand, then sacrifices a third of the creatures they control, then sacrifices a third of the lands they control. Round up each time.
this.getSpellAbility().addEffect(new PoxEffect());
}
@@ -81,7 +81,7 @@ class PoxEffect extends OneShotEffect {
}
}
}
- // then sacrifices a third of the creatures he or she controls,
+ // then sacrifices a third of the creatures they control,
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
@@ -99,7 +99,7 @@ class PoxEffect extends OneShotEffect {
}
}
}
- // then sacrifices a third of the lands he or she controls.
+ // then sacrifices a third of the lands they control.
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
diff --git a/Mage.Sets/src/mage/cards/p/Preacher.java b/Mage.Sets/src/mage/cards/p/Preacher.java
index c492c3bae28..02bb23ec7dc 100644
--- a/Mage.Sets/src/mage/cards/p/Preacher.java
+++ b/Mage.Sets/src/mage/cards/p/Preacher.java
@@ -42,7 +42,7 @@ public final class Preacher extends CardImpl {
// You may choose not to untap Preacher during your untap step.
this.addAbility(new SkipUntapOptionalAbility());
- // {tap}: Gain control of target creature of an opponent's choice that he or she controls for as long as Preacher remains tapped.
+ // {tap}: Gain control of target creature of an opponent's choice that they control for as long as Preacher remains tapped.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreacherEffect(), new TapSourceCost());
ability.addTarget(new TargetOpponentsChoicePermanent(1, 1, new FilterControlledCreaturePermanent(), false, true));
this.addAbility(ability);
@@ -63,7 +63,7 @@ class PreacherEffect extends OneShotEffect {
public PreacherEffect() {
super(Outcome.GainControl);
- this.staticText = "Gain control of target creature of an opponent's choice that he or she controls for as long as {this} remains tapped";
+ this.staticText = "Gain control of target creature of an opponent's choice that they control for as long as {this} remains tapped";
}
public PreacherEffect(final PreacherEffect effect) {
@@ -89,7 +89,7 @@ class PreacherEffect extends OneShotEffect {
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(
new GainControlTargetEffect(Duration.Custom),
new CompoundCondition(sourceTappedCondition, new CompoundCondition(conditionSourceSameZone, conditionTargetSameZone)),
- "Gain control of target creature of an opponent's choice that he or she controls for as long as {this} remains tapped");
+ "Gain control of target creature of an opponent's choice that they control for as long as {this} remains tapped");
effect.setTargetPointer(new FixedTarget(targetPermanent.getId()));
game.addEffect(effect, source);
return true;
diff --git a/Mage.Sets/src/mage/cards/p/PrematureBurial.java b/Mage.Sets/src/mage/cards/p/PrematureBurial.java
index a4542bed63f..46d0f886d77 100644
--- a/Mage.Sets/src/mage/cards/p/PrematureBurial.java
+++ b/Mage.Sets/src/mage/cards/p/PrematureBurial.java
@@ -21,7 +21,6 @@ import mage.watchers.Watcher;
import java.util.*;
/**
- *
* @author noahg
*/
public final class PrematureBurial extends CardImpl {
@@ -34,7 +33,6 @@ public final class PrematureBurial extends CardImpl {
public PrematureBurial(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}");
-
// Destroy target nonblack creature that entered the battlefield since your last turn ended.
this.getSpellAbility().addEffect(new DestroyTargetEffect().setText("Destroy target nonblack creature that entered the battlefield since your last turn ended."));
@@ -59,17 +57,15 @@ class ETBSinceYourLastTurnTarget extends TargetCreaturePermanent {
this.targetName = "nonblack creature that entered the battlefield since your last turn ended";
}
- public ETBSinceYourLastTurnTarget(ETBSinceYourLastTurnTarget target){
+ public ETBSinceYourLastTurnTarget(ETBSinceYourLastTurnTarget target) {
super(target);
}
@Override
public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) {
- System.out.println("canTarget called");
ETBSinceYourLastTurnWatcher watcher = game.getState().getWatcher(ETBSinceYourLastTurnWatcher.class);
- if (watcher != null){
- if (watcher.enteredSinceLastTurn(controllerId, new MageObjectReference(id, game))){
- System.out.println(game.getPermanent(id).getIdName()+" entered since the last turn.");
+ if (watcher != null) {
+ if (watcher.enteredSinceLastTurn(controllerId, new MageObjectReference(id, game))) {
return super.canTarget(controllerId, id, source, game);
}
}
@@ -80,7 +76,7 @@ class ETBSinceYourLastTurnTarget extends TargetCreaturePermanent {
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
MageObject targetSource = game.getObject(sourceId);
ETBSinceYourLastTurnWatcher watcher = game.getState().getWatcher(ETBSinceYourLastTurnWatcher.class);
- if(targetSource != null) {
+ if (targetSource != null) {
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game)) {
if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) {
if (watcher != null && watcher.enteredSinceLastTurn(sourceControllerId, new MageObjectReference(permanent.getId(), game))) {
@@ -110,22 +106,20 @@ class ETBSinceYourLastTurnWatcher extends Watcher {
public ETBSinceYourLastTurnWatcher(ETBSinceYourLastTurnWatcher watcher) {
super(watcher);
this.playerToETBMap = new HashMap<>();
- for (UUID player : watcher.playerToETBMap.keySet()){
+ for (UUID player : watcher.playerToETBMap.keySet()) {
this.playerToETBMap.put(player, new HashSet<>(watcher.playerToETBMap.get(player)));
}
}
@Override
public void watch(GameEvent event, Game game) {
- if (event.getType() == GameEvent.EventType.END_TURN_STEP_POST){
- System.out.println("End of turn for "+game.getPlayer(event.getPlayerId()).getName());
+ if (event.getType() == GameEvent.EventType.END_TURN_STEP_POST) {
playerToETBMap.put(event.getPlayerId(), new HashSet<>());
- } else if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD){
+ } else if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) {
Permanent etbPermanent = game.getPermanent(event.getTargetId());
- if (etbPermanent != null){
- System.out.println("nonnull permanent entered: "+etbPermanent.getIdName());
- for (UUID player : game.getPlayerList()){
- if (!playerToETBMap.containsKey(player)){
+ if (etbPermanent != null) {
+ for (UUID player : game.getPlayerList()) {
+ if (!playerToETBMap.containsKey(player)) {
playerToETBMap.put(player, new HashSet<>());
}
playerToETBMap.get(player).add(new MageObjectReference(etbPermanent.getBasicMageObject(game), game));
@@ -134,12 +128,7 @@ class ETBSinceYourLastTurnWatcher extends Watcher {
}
}
- public boolean enteredSinceLastTurn(UUID player, MageObjectReference mor){
+ public boolean enteredSinceLastTurn(UUID player, MageObjectReference mor) {
return playerToETBMap.get(player).contains(mor);
}
-
- @Override
- public ETBSinceYourLastTurnWatcher copy() {
- return new ETBSinceYourLastTurnWatcher(this);
- }
}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/p/PriceOfGlory.java b/Mage.Sets/src/mage/cards/p/PriceOfGlory.java
index c34c287cd4f..1fbc55a591a 100644
--- a/Mage.Sets/src/mage/cards/p/PriceOfGlory.java
+++ b/Mage.Sets/src/mage/cards/p/PriceOfGlory.java
@@ -1,7 +1,5 @@
-
package mage.cards.p;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
@@ -17,8 +15,9 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
+import java.util.UUID;
+
/**
- *
* @author cbt33, Loki (Heartbeat of Spring)
*/
public final class PriceOfGlory extends CardImpl {
@@ -63,12 +62,8 @@ class PriceOfGloryAbility extends TriggeredAbilityImpl {
if (permanent == null) {
return false;
}
- Player player = game.getPlayer(controllerId);
- if (player == null) {
- return false;
- }
if (permanent.isLand()
- && player.getInRange().contains(permanent.getControllerId())
+ && game.getState().getPlayersInRange(controllerId, game).contains(permanent.getControllerId())
&& !permanent.isControlledBy(game.getActivePlayerId())) { // intervening if clause
getEffects().get(0).setTargetPointer(new FixedTarget(permanent.getId()));
return true;
diff --git a/Mage.Sets/src/mage/cards/p/PrimalCommand.java b/Mage.Sets/src/mage/cards/p/PrimalCommand.java
index d20b5bf91cb..93ddcec52b5 100644
--- a/Mage.Sets/src/mage/cards/p/PrimalCommand.java
+++ b/Mage.Sets/src/mage/cards/p/PrimalCommand.java
@@ -1,4 +1,3 @@
-
package mage.cards.p;
import java.util.UUID;
@@ -15,7 +14,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
@@ -32,15 +31,15 @@ import mage.target.common.TargetCardInLibrary;
public final class PrimalCommand extends CardImpl {
private static final FilterPermanent filterNonCreature = new FilterPermanent("noncreature permanent");
+
static {
filterNonCreature.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
}
public PrimalCommand(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{G}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}{G}");
-
- // Choose two -
+ // Choose two -
this.getSpellAbility().getModes().setMinModes(2);
this.getSpellAbility().getModes().setMaxModes(2);
// Target player gains 7 life;
@@ -56,12 +55,12 @@ public final class PrimalCommand extends CardImpl {
mode = new Mode();
mode.addEffect(new PrimalCommandShuffleGraveyardEffect());
mode.addTarget(new TargetPlayer());
- this.getSpellAbility().getModes().addMode(mode);
+ this.getSpellAbility().getModes().addMode(mode);
// or search your library for a creature card, reveal it, put it into your hand, then shuffle your library.
mode = new Mode();
- mode.addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(new FilterCreatureCard()), true, true));
+ mode.addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_CREATURE), true, true));
this.getSpellAbility().getModes().addMode(mode);
-
+
}
public PrimalCommand(final PrimalCommand card) {
@@ -94,9 +93,9 @@ class PrimalCommandShuffleGraveyardEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getFirstTarget());
if (player != null) {
- for (Card card: player.getGraveyard().getCards(game)) {
+ for (Card card : player.getGraveyard().getCards(game)) {
player.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD, true, true);
- }
+ }
player.shuffleLibrary(source, game);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/p/PrimalOrder.java b/Mage.Sets/src/mage/cards/p/PrimalOrder.java
index 94ca999698a..b3fe518483d 100644
--- a/Mage.Sets/src/mage/cards/p/PrimalOrder.java
+++ b/Mage.Sets/src/mage/cards/p/PrimalOrder.java
@@ -25,7 +25,7 @@ public final class PrimalOrder extends CardImpl {
public PrimalOrder(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{G}{G}");
- // At the beginning of each player's upkeep, Primal Order deals damage to that player equal to the number of nonbasic lands he or she controls.
+ // At the beginning of each player's upkeep, Primal Order deals damage to that player equal to the number of nonbasic lands they control.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new PrimalOrderDamageTargetEffect(), TargetController.ANY, false, true));
}
@@ -55,7 +55,7 @@ class PrimalOrderDamageTargetEffect extends OneShotEffect{
@Override
public String getText(Mode mode) {
- return "{this} deals damage to that player equal to the number of nonbasic lands he or she controls";
+ return "{this} deals damage to that player equal to the number of nonbasic lands they control";
}
@Override
diff --git a/Mage.Sets/src/mage/cards/p/PrizedGriffin.java b/Mage.Sets/src/mage/cards/p/PrizedGriffin.java
new file mode 100644
index 00000000000..5487a3b7325
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/p/PrizedGriffin.java
@@ -0,0 +1,36 @@
+package mage.cards.p;
+
+import mage.MageInt;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class PrizedGriffin extends CardImpl {
+
+ public PrizedGriffin(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}");
+
+ this.subtype.add(SubType.GRIFFIN);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(4);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+ }
+
+ private PrizedGriffin(final PrizedGriffin card) {
+ super(card);
+ }
+
+ @Override
+ public PrizedGriffin copy() {
+ return new PrizedGriffin(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/p/Propaganda.java b/Mage.Sets/src/mage/cards/p/Propaganda.java
index 4767e39978d..49e5a11f381 100644
--- a/Mage.Sets/src/mage/cards/p/Propaganda.java
+++ b/Mage.Sets/src/mage/cards/p/Propaganda.java
@@ -19,7 +19,7 @@ public final class Propaganda extends CardImpl {
public Propaganda(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}");
- // Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you.
+ // Creatures can't attack you unless their controller pays {2} for each creature they control that's attacking you.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackYouUnlessPayManaAllEffect(new ManaCostsImpl("{2}"))));
}
diff --git a/Mage.Sets/src/mage/cards/p/ProphetOfThePeak.java b/Mage.Sets/src/mage/cards/p/ProphetOfThePeak.java
new file mode 100644
index 00000000000..3f55e1e3f28
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/p/ProphetOfThePeak.java
@@ -0,0 +1,37 @@
+package mage.cards.p;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.keyword.ScryEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ProphetOfThePeak extends CardImpl {
+
+ public ProphetOfThePeak(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}");
+
+ this.subtype.add(SubType.CAT);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(5);
+
+ // When Prophet of the Peak enters the battlefield, scry 2.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new ScryEffect(2)));
+ }
+
+ private ProphetOfThePeak(final ProphetOfThePeak card) {
+ super(card);
+ }
+
+ @Override
+ public ProphetOfThePeak copy() {
+ return new ProphetOfThePeak(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/p/ProteanHydra.java b/Mage.Sets/src/mage/cards/p/ProteanHydra.java
index ca3820ba66e..ad50c030011 100644
--- a/Mage.Sets/src/mage/cards/p/ProteanHydra.java
+++ b/Mage.Sets/src/mage/cards/p/ProteanHydra.java
@@ -38,7 +38,7 @@ public final class ProteanHydra extends CardImpl {
this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldWithXCountersEffect(CounterType.P1P1.createInstance())));
// If damage would be dealt to Protean Hydra, prevent that damage and remove that many +1/+1 counters from it.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventDamageAndRemoveCountersEffect()));
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventDamageAndRemoveCountersEffect(true)));
// Whenever a +1/+1 counter is removed from Protean Hydra, put two +1/+1 counters on it at the beginning of the next end step.
this.addAbility(new ProteanHydraAbility());
diff --git a/Mage.Sets/src/mage/cards/p/ProteusStaff.java b/Mage.Sets/src/mage/cards/p/ProteusStaff.java
index 65669ef485d..431d83f7502 100644
--- a/Mage.Sets/src/mage/cards/p/ProteusStaff.java
+++ b/Mage.Sets/src/mage/cards/p/ProteusStaff.java
@@ -31,7 +31,7 @@ public final class ProteusStaff extends CardImpl {
public ProteusStaff(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
- // {2}{U}, {T}: Put target creature on the bottom of its owner's library. That creature's controller reveals cards from the top of their library until he or she reveals a creature card. The player puts that card onto the battlefield and the rest on the bottom of their library in any order. Activate this ability only any time you could cast a sorcery.
+ // {2}{U}, {T}: Put target creature on the bottom of its owner's library. That creature's controller reveals cards from the top of their library until they reveal a creature card. The player puts that card onto the battlefield and the rest on the bottom of their library in any order. Activate this ability only any time you could cast a sorcery.
Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new ProteusStaffEffect(), new ManaCostsImpl<>("{2}{U}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
@@ -52,7 +52,7 @@ class ProteusStaffEffect extends OneShotEffect {
ProteusStaffEffect() {
super(Outcome.PutCreatureInPlay);
- this.staticText = "Put target creature on the bottom of its owner's library. That creature's controller reveals cards from the top of their library until he or she reveals a creature card. The player puts that card onto the battlefield and the rest on the bottom of their library in any order.";
+ this.staticText = "Put target creature on the bottom of its owner's library. That creature's controller reveals cards from the top of their library until they reveal a creature card. The player puts that card onto the battlefield and the rest on the bottom of their library in any order.";
}
ProteusStaffEffect(final ProteusStaffEffect effect) {
@@ -74,7 +74,7 @@ class ProteusStaffEffect extends OneShotEffect {
// Put target creature on the bottom of its owner's library.
owner.moveCardToLibraryWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD, false, true);
- // That creature's controller reveals cards from the top of their library until he or she reveals a creature card.
+ // That creature's controller reveals cards from the top of their library until they reveal a creature card.
Cards cards = new CardsImpl();
for (Card card : controller.getLibrary().getCards(game)) {
if (card != null) {
diff --git a/Mage.Sets/src/mage/cards/p/PsychicAllergy.java b/Mage.Sets/src/mage/cards/p/PsychicAllergy.java
index 17af2bbb36b..77c2c621609 100644
--- a/Mage.Sets/src/mage/cards/p/PsychicAllergy.java
+++ b/Mage.Sets/src/mage/cards/p/PsychicAllergy.java
@@ -46,7 +46,7 @@ public final class PsychicAllergy extends CardImpl {
// As Psychic Allergy enters the battlefield, choose a color.
this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Damage)));
- // At the beginning of each opponent's upkeep, Psychic Allergy deals X damage to that player, where X is the number of nontoken permanents of the chosen color he or she controls.
+ // At the beginning of each opponent's upkeep, Psychic Allergy deals X damage to that player, where X is the number of nontoken permanents of the chosen color they control.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new PsychicAllergyEffect(), TargetController.OPPONENT, false));
// At the beginning of your upkeep, destroy Psychic Allergy unless you sacrifice two Islands.
@@ -71,7 +71,7 @@ class PsychicAllergyEffect extends OneShotEffect {
public PsychicAllergyEffect() {
super(Outcome.Damage);
- this.staticText = "{this} deals X damage to that player, where X is the number of nontoken permanents of the chosen color he or she controls";
+ this.staticText = "{this} deals X damage to that player, where X is the number of nontoken permanents of the chosen color they control";
}
public PsychicAllergyEffect(PsychicAllergyEffect copy) {
diff --git a/Mage.Sets/src/mage/cards/p/PsychicIntrusion.java b/Mage.Sets/src/mage/cards/p/PsychicIntrusion.java
index 9cc6cc4f33f..40c1684df6e 100644
--- a/Mage.Sets/src/mage/cards/p/PsychicIntrusion.java
+++ b/Mage.Sets/src/mage/cards/p/PsychicIntrusion.java
@@ -1,6 +1,5 @@
package mage.cards.p;
-import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.AsThoughEffectImpl;
@@ -10,12 +9,7 @@ import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.AsThoughEffectType;
-import mage.constants.CardType;
-import mage.constants.Duration;
-import mage.constants.ManaType;
-import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.filter.common.FilterNonlandCard;
import mage.game.Game;
import mage.players.ManaPoolItem;
@@ -25,8 +19,9 @@ import mage.target.common.TargetOpponent;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class PsychicIntrusion extends CardImpl {
@@ -149,10 +144,9 @@ class PsychicIntrusionCastFromExileEffect extends AsThoughEffectImpl {
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
if (objectId.equals(getTargetPointer().getFirst(game, source))) {
- if (affectedControllerId.equals(source.getControllerId())) {
- return true;
- }
+ return affectedControllerId.equals(source.getControllerId());
} else {
if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
// object has moved zone so effect can be discarted
@@ -186,15 +180,11 @@ class PsychicIntrusionSpendAnyManaEffect extends AsThoughEffectImpl implements A
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
- objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget())
&& game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
- if (affectedControllerId.equals(source.getControllerId())) {
- // if the card moved from exile to spell the zone change counter is increased by 1
- if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
- return true;
- }
- }
+ // if the card moved from exile to spell the zone change counter is increased by 1 (effect must applies before and on stack, use isCheckPlayableMode?)
+ return affectedControllerId.equals(source.getControllerId());
} else {
if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
// object has moved zone so effect can be discarted
diff --git a/Mage.Sets/src/mage/cards/p/PsychogenicProbe.java b/Mage.Sets/src/mage/cards/p/PsychogenicProbe.java
index 7181688185c..1a267e81fe6 100644
--- a/Mage.Sets/src/mage/cards/p/PsychogenicProbe.java
+++ b/Mage.Sets/src/mage/cards/p/PsychogenicProbe.java
@@ -23,7 +23,7 @@ public final class PsychogenicProbe extends CardImpl {
public PsychogenicProbe(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
- // Whenever a spell or ability causes a player to shuffle their library, Psychogenic Probe deals 2 damage to him or her.
+ // Whenever a spell or ability causes a player to shuffle their library, Psychogenic Probe deals 2 damage to that player.
this.addAbility(new PsychogenicProbeTriggeredAbility());
}
@@ -67,6 +67,6 @@ class PsychogenicProbeTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
- return "Whenever a spell or ability causes a player to shuffle their library, {this} deals 2 damage to him or her.";
+ return "Whenever a spell or ability causes a player to shuffle their library, {this} deals 2 damage to that player.";
}
}
diff --git a/Mage.Sets/src/mage/cards/p/PublicExecution.java b/Mage.Sets/src/mage/cards/p/PublicExecution.java
index bd08413a7d8..c5f8e25780c 100644
--- a/Mage.Sets/src/mage/cards/p/PublicExecution.java
+++ b/Mage.Sets/src/mage/cards/p/PublicExecution.java
@@ -1,7 +1,5 @@
-
package mage.cards.p;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
@@ -19,20 +17,21 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author jeffwadsworth
*/
public final class PublicExecution extends CardImpl {
-
+
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls");
-
+
static {
- filter.add(new ControllerPredicate(TargetController.NOT_YOU));
+ filter.add(new ControllerPredicate(TargetController.OPPONENT));
}
public PublicExecution(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{5}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{5}{B}");
// Destroy target creature an opponent controls. Each other creature that player controls gets -2/-0 until end of turn.
this.getSpellAbility().addEffect(new DestroyTargetEffect());
@@ -51,7 +50,7 @@ public final class PublicExecution extends CardImpl {
}
class PublicExecutionEffect extends OneShotEffect {
-
+
public PublicExecutionEffect() {
super(Outcome.Benefit);
staticText = "Each other creature that player controls gets -2/-0 until end of turn";
@@ -70,7 +69,7 @@ class PublicExecutionEffect extends OneShotEffect {
FilterCreaturePermanent filter = new FilterCreaturePermanent("each other creature that player controls");
filter.add(new ControllerIdPredicate(opponent));
filter.add(Predicates.not(new PermanentIdPredicate(target.getId())));
- ContinuousEffect effect = new BoostAllEffect(-2,0, Duration.EndOfTurn, filter, false);
+ ContinuousEffect effect = new BoostAllEffect(-2, 0, Duration.EndOfTurn, filter, false);
game.addEffect(effect, source);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/p/PufferExtract.java b/Mage.Sets/src/mage/cards/p/PufferExtract.java
new file mode 100644
index 00000000000..8005874a67b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/p/PufferExtract.java
@@ -0,0 +1,73 @@
+package mage.cards.p;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DestroyTargetEffect;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.game.Game;
+import mage.target.common.TargetControlledCreaturePermanent;
+import mage.target.targetpointer.FixedTarget;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class PufferExtract extends CardImpl {
+
+ public PufferExtract(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
+
+ // {X}, {T}: Target creature you control gets +X/+X until end of turn. Destroy it at the beginning of the next end step.
+ Ability ability = new SimpleActivatedAbility(new PufferExtractEffect(), new ManaCostsImpl("{X}"));
+ ability.addCost(new TapSourceCost());
+ ability.addTarget(new TargetControlledCreaturePermanent());
+ this.addAbility(ability);
+ }
+
+ private PufferExtract(final PufferExtract card) {
+ super(card);
+ }
+
+ @Override
+ public PufferExtract copy() {
+ return new PufferExtract(this);
+ }
+}
+
+class PufferExtractEffect extends OneShotEffect {
+
+ PufferExtractEffect() {
+ super(Outcome.Benefit);
+ staticText = "Target creature you control gets +X/+X until end of turn. " +
+ "Destroy it at the beginning of the next end step.";
+ }
+
+ private PufferExtractEffect(final PufferExtractEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public PufferExtractEffect copy() {
+ return new PufferExtractEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ int xValue = source.getManaCostsToPay().getX();
+ game.addEffect(new BoostTargetEffect(xValue, xValue, Duration.EndOfTurn), source);
+ game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
+ new DestroyTargetEffect().setTargetPointer(new FixedTarget(source.getFirstTarget(), game))
+ ), source);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/p/PurphorosGodOfTheForge.java b/Mage.Sets/src/mage/cards/p/PurphorosGodOfTheForge.java
index 31c7ecc8676..db290596d0e 100644
--- a/Mage.Sets/src/mage/cards/p/PurphorosGodOfTheForge.java
+++ b/Mage.Sets/src/mage/cards/p/PurphorosGodOfTheForge.java
@@ -1,14 +1,11 @@
-
package mage.cards.p;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.DevotionCount;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamagePlayersEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
@@ -16,22 +13,25 @@ import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
+import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.AnotherPredicate;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class PurphorosGodOfTheForge extends CardImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature");
+ private static final FilterPermanent filter = new FilterCreaturePermanent("another creature");
+
static {
filter.add(AnotherPredicate.instance);
}
public PurphorosGodOfTheForge(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{3}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{3}{R}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.GOD);
@@ -41,18 +41,23 @@ public final class PurphorosGodOfTheForge extends CardImpl {
// Indestructible
this.addAbility(IndestructibleAbility.getInstance());
+
// As long as your devotion to red is less than five, Purphoros isn't a creature.
- Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.R), 5);
- effect.setText("As long as your devotion to red is less than five, Purphoros isn't a creature.(Each {R} in the mana costs of permanents you control counts towards your devotion to red.)");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.R, 5))
+ .addHint(DevotionCount.R.getHint()));
// Whenever another creature enters the battlefield under your control, Purphoros deals 2 damage to each opponent.
- this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new DamagePlayersEffect(2, TargetController.OPPONENT), filter));
+ this.addAbility(new EntersBattlefieldControlledTriggeredAbility(
+ new DamagePlayersEffect(2, TargetController.OPPONENT), filter
+ ));
+
// {2}{R}: Creatures you control get +1/+0 until end of turn.
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1,0, Duration.EndOfTurn), new ManaCostsImpl("{2}{R}")));
+ this.addAbility(new SimpleActivatedAbility(
+ new BoostControlledEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl("{2}{R}")
+ ));
}
- public PurphorosGodOfTheForge(final PurphorosGodOfTheForge card) {
+ private PurphorosGodOfTheForge(final PurphorosGodOfTheForge card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/p/PurphurosBronzeBlooded.java b/Mage.Sets/src/mage/cards/p/PurphurosBronzeBlooded.java
new file mode 100644
index 00000000000..5fde5487d7c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/p/PurphurosBronzeBlooded.java
@@ -0,0 +1,131 @@
+package mage.cards.p;
+
+import mage.MageInt;
+import mage.ObjectColor;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.dynamicvalue.common.DevotionCount;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.SacrificeTargetEffect;
+import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
+import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
+import mage.abilities.keyword.HasteAbility;
+import mage.abilities.keyword.IndestructibleAbility;
+import mage.cards.Card;
+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.Predicates;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.filter.predicate.mageobject.ColorPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.common.TargetCardInHand;
+import mage.target.targetpointer.FixedTarget;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class PurphurosBronzeBlooded extends CardImpl {
+
+ public PurphurosBronzeBlooded(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{4}{R}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.GOD);
+ this.power = new MageInt(7);
+ this.toughness = new MageInt(6);
+
+ // Indestructible
+ this.addAbility(IndestructibleAbility.getInstance());
+
+ // As long as your devotion to red is less than five, Purphuros isn't a creature.
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.R, 5))
+ .addHint(DevotionCount.R.getHint()));
+
+ // Other creatures you control have haste.
+ this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
+ HasteAbility.getInstance(), Duration.WhileOnBattlefield,
+ StaticFilters.FILTER_PERMANENT_CREATURES, true
+ )));
+
+ // {2}{R}: You may put a red creature card or an artifact creature card from your hand onto the battlefield. Sacrifice it at the beginning of the next end step.
+ this.addAbility(new SimpleActivatedAbility(new PurphurosBronzeBloodedEffect(), new ManaCostsImpl("{2}{R}")));
+ }
+
+ private PurphurosBronzeBlooded(final PurphurosBronzeBlooded card) {
+ super(card);
+ }
+
+ @Override
+ public PurphurosBronzeBlooded copy() {
+ return new PurphurosBronzeBlooded(this);
+ }
+}
+
+class PurphurosBronzeBloodedEffect extends OneShotEffect {
+
+ private static final String choiceText
+ = "Put a red creature card or an artifact creature card from your hand onto the battlefield?";
+ private static final FilterCard filter
+ = new FilterCreatureCard("a red creature card or an artifact creature card");
+
+ static {
+ filter.add(Predicates.or(
+ new CardTypePredicate(CardType.ARTIFACT),
+ new ColorPredicate(ObjectColor.RED)
+ ));
+ }
+
+ PurphurosBronzeBloodedEffect() {
+ super(Outcome.Benefit);
+ this.staticText = "You may put a red creature card or an artifact creature card " +
+ "from your hand onto the battlefield. Sacrifice it at the beginning of the next end step";
+ }
+
+ private PurphurosBronzeBloodedEffect(final PurphurosBronzeBloodedEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public PurphurosBronzeBloodedEffect copy() {
+ return new PurphurosBronzeBloodedEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null || !controller.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) {
+ return true;
+ }
+ TargetCardInHand target = new TargetCardInHand(filter);
+ if (!controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) {
+ return true;
+ }
+ Card card = game.getCard(target.getFirstTarget());
+ if (card == null || !controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
+ return false;
+ }
+ Permanent permanent = game.getPermanent(card.getId());
+ if (permanent == null) {
+ return true;
+ }
+
+ game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
+ new SacrificeTargetEffect(
+ "sacrifice " + card.getName(),
+ source.getControllerId()
+ ).setTargetPointer(new FixedTarget(permanent, game))
+ ), source);
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/p/PyxisOfPandemonium.java b/Mage.Sets/src/mage/cards/p/PyxisOfPandemonium.java
index cb8f478b370..0b7be6f4099 100644
--- a/Mage.Sets/src/mage/cards/p/PyxisOfPandemonium.java
+++ b/Mage.Sets/src/mage/cards/p/PyxisOfPandemonium.java
@@ -34,7 +34,7 @@ public final class PyxisOfPandemonium extends CardImpl {
new PyxisOfPandemoniumExileEffect(),
new TapSourceCost()));
- // {7}, {T}, Sacrifice Pyxis of Pandemonium: Each player turns face up all cards he or she owns exiled with Pyxis of Pandemonium, then puts all permanent cards among them onto the battlefield.
+ // {7}, {T}, Sacrifice Pyxis of Pandemonium: Each player turns face up all cards they own exiled with Pyxis of Pandemonium, then puts all permanent cards among them onto the battlefield.
Ability ability = new SimpleActivatedAbility(
Zone.BATTLEFIELD,
new PyxisOfPandemoniumPutOntoBattlefieldEffect(),
@@ -112,7 +112,7 @@ class PyxisOfPandemoniumPutOntoBattlefieldEffect extends OneShotEffect {
public PyxisOfPandemoniumPutOntoBattlefieldEffect() {
super(Outcome.PutCardInPlay);
- this.staticText = "Each player turns face up all cards he or she owns exiled with {this}, "
+ this.staticText = "Each player turns face up all cards they own exiled with {this}, "
+ "then puts all permanent cards among them onto the battlefield";
}
diff --git a/Mage.Sets/src/mage/cards/q/QasaliAmbusher.java b/Mage.Sets/src/mage/cards/q/QasaliAmbusher.java
index 134df294229..28cf858f5d4 100644
--- a/Mage.Sets/src/mage/cards/q/QasaliAmbusher.java
+++ b/Mage.Sets/src/mage/cards/q/QasaliAmbusher.java
@@ -1,16 +1,11 @@
-
package mage.cards.q;
import java.util.UUID;
import mage.MageInt;
-import mage.MageObjectReference;
-import mage.abilities.Ability;
import mage.abilities.ActivatedAbilityImpl;
-import mage.abilities.SpellAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashSourceEffect;
import mage.abilities.keyword.ReachAbility;
-import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
@@ -18,7 +13,6 @@ import mage.filter.common.FilterControlledLandPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.game.combat.CombatGroup;
-import mage.players.Player;
/**
*
@@ -36,7 +30,9 @@ public final class QasaliAmbusher extends CardImpl {
// Reach
this.addAbility(ReachAbility.getInstance());
- // If a creature is attacking you and you control a Forest and a Plains, you may casbt Qasali Ambusher without paying its mana cost and as though it had flash.
+
+ // If a creature is attacking you and you control a Forest and a Plains,
+ // you may cast Qasali Ambusher without paying its mana cost and as though it had flash.
this.addAbility(new QasaliAmbusherAbility());
}
@@ -62,7 +58,7 @@ class QasaliAmbusherAbility extends ActivatedAbilityImpl {
}
public QasaliAmbusherAbility() {
- super(Zone.HAND, new QasaliAmbusherEffect(), new ManaCostsImpl());
+ super(Zone.HAND, new CastAsThoughItHadFlashSourceEffect(Duration.EndOfGame), new ManaCostsImpl());
this.timing = TimingRule.INSTANT;
this.usesStack = false;
}
@@ -78,8 +74,10 @@ class QasaliAmbusherAbility extends ActivatedAbilityImpl {
@Override
public ActivationStatus canActivate(UUID playerId, Game game) {
- if (!game.getBattlefield().getActivePermanents(filterPlains, this.getControllerId(), this.getSourceId(), game).isEmpty()
- && !game.getBattlefield().getActivePermanents(filterForest, this.getControllerId(), this.getSourceId(), game).isEmpty()) {
+ if (!game.getBattlefield().getActivePermanents(filterPlains,
+ this.getControllerId(), this.getSourceId(), game).isEmpty()
+ && !game.getBattlefield().getActivePermanents(filterForest,
+ this.getControllerId(), this.getSourceId(), game).isEmpty()) {
for (CombatGroup group : game.getCombat().getGroups()) {
if (isControlledBy(group.getDefenderId())) {
return super.canActivate(playerId, game);
@@ -96,37 +94,8 @@ class QasaliAmbusherAbility extends ActivatedAbilityImpl {
@Override
public String getRule() {
- return "If a creature is attacking you and you control a Forest and a Plains, you may cast {this} without paying its mana cost and as though it had flash.";
- }
-}
-
-class QasaliAmbusherEffect extends OneShotEffect {
-
- public QasaliAmbusherEffect() {
- super(Outcome.Benefit);
- staticText = "";
- }
-
- public QasaliAmbusherEffect(final QasaliAmbusherEffect effect) {
- super(effect);
- }
-
- @Override
- public QasaliAmbusherEffect copy() {
- return new QasaliAmbusherEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Card card = (Card) game.getObject(source.getSourceId());
- if (card != null) {
- Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- SpellAbility spellAbility = card.getSpellAbility();
- spellAbility.clear();
- return controller.cast(spellAbility, game, true, new MageObjectReference(source.getSourceObject(game), game));
- }
- }
- return false;
+ return "If a creature is attacking you and you control a Forest and "
+ + "a Plains, you may cast {this} without paying its mana "
+ + "cost and as though it had flash.";
}
}
diff --git a/Mage.Sets/src/mage/cards/q/QueenOfIce.java b/Mage.Sets/src/mage/cards/q/QueenOfIce.java
new file mode 100644
index 00000000000..d1fe38e761c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/q/QueenOfIce.java
@@ -0,0 +1,57 @@
+package mage.cards.q;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.DealsDamageToACreatureTriggeredAbility;
+import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
+import mage.abilities.effects.common.TapTargetEffect;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class QueenOfIce extends AdventureCard {
+
+ public QueenOfIce(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{2}{U}", "Rage of Winter", "{1}{U}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.NOBLE);
+ this.subtype.add(SubType.WIZARD);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // Whenever Queen of Ice deals combat damage to a creature, tap that creature. It doesn't untap during its controller's next untap step.
+ Ability ability = new DealsDamageToACreatureTriggeredAbility(
+ new TapTargetEffect().setText("tap that creature."),
+ true, false, true
+ );
+ ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect()
+ .setText("It doesn't untap during its controller's next untap step")
+ );
+ this.addAbility(ability);
+
+ // Rage of Winter
+ // Tap target creature. It doesn’t untap during its controller’s next untap step.
+ this.getSpellCard().getSpellAbility().addEffect(new TapTargetEffect());
+ this.getSpellCard().getSpellAbility().addEffect(new DontUntapInControllersNextUntapStepTargetEffect()
+ .setText("It doesn't untap during its controller's next untap step"));
+ this.getSpellCard().getSpellAbility().addTarget(new TargetCreaturePermanent());
+ }
+
+ private QueenOfIce(final QueenOfIce card) {
+ super(card);
+ }
+
+ @Override
+ public QueenOfIce copy() {
+ return new QueenOfIce(this);
+ }
+}
+// let it go
diff --git a/Mage.Sets/src/mage/cards/q/QuestingBeast.java b/Mage.Sets/src/mage/cards/q/QuestingBeast.java
new file mode 100644
index 00000000000..5ff8e7b1205
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/q/QuestingBeast.java
@@ -0,0 +1,157 @@
+package mage.cards.q;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.SimpleEvasionAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
+import mage.abilities.keyword.DeathtouchAbility;
+import mage.abilities.keyword.HasteAbility;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.common.FilterPlaneswalkerPermanent;
+import mage.filter.predicate.mageobject.PowerPredicate;
+import mage.filter.predicate.permanent.ControllerIdPredicate;
+import mage.game.Game;
+import mage.game.events.DamagedEvent;
+import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class QuestingBeast extends CardImpl {
+
+ private static final FilterCreaturePermanent filter
+ = new FilterCreaturePermanent("creatures with power 2 or less");
+
+ static {
+ filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 3));
+ }
+
+ public QuestingBeast(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.BEAST);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(4);
+
+ // Vigilance
+ this.addAbility(VigilanceAbility.getInstance());
+
+ // Deathtouch
+ this.addAbility(DeathtouchAbility.getInstance());
+
+ // Haste
+ this.addAbility(HasteAbility.getInstance());
+
+ // Questing Beast can't be blocked by creatures with power 2 or less.
+ this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield)));
+
+ // Combat damage that would be dealt by creatures you control can't be prevented.
+ this.addAbility(new SimpleStaticAbility(new QuestingBeastPreventionEffect()));
+
+ // Whenever Questing Beast deals combat damage to an opponent, it deals that much damage to target planeswalker that player controls.
+ this.addAbility(new QuestingBeastTriggeredAbility());
+ }
+
+ private QuestingBeast(final QuestingBeast card) {
+ super(card);
+ }
+
+ @Override
+ public QuestingBeast copy() {
+ return new QuestingBeast(this);
+ }
+}
+
+class QuestingBeastPreventionEffect extends ContinuousRuleModifyingEffectImpl {
+
+ QuestingBeastPreventionEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.Benefit);
+ staticText = "Combat damage that would be dealt by creatures you control can't be prevented.";
+ }
+
+ private QuestingBeastPreventionEffect(final QuestingBeastPreventionEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public QuestingBeastPreventionEffect copy() {
+ return new QuestingBeastPreventionEffect(this);
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.PREVENT_DAMAGE;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ if (!((PreventDamageEvent) event).isCombatDamage()) {
+ return false;
+ }
+ Permanent permanent = game.getPermanent(event.getSourceId());
+ return permanent != null
+ && permanent.isCreature()
+ && permanent.isControlledBy(source.getControllerId());
+ }
+}
+
+class QuestingBeastTriggeredAbility extends TriggeredAbilityImpl {
+
+ QuestingBeastTriggeredAbility() {
+ super(Zone.BATTLEFIELD, null, true);
+ }
+
+ private QuestingBeastTriggeredAbility(final QuestingBeastTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public QuestingBeastTriggeredAbility copy() {
+ return new QuestingBeastTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.DAMAGED_PLAYER;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ Player opponent = game.getPlayer(event.getPlayerId());
+ if (opponent == null
+ || !event.getSourceId().equals(this.getSourceId())
+ || !opponent.hasOpponent(this.getControllerId(), game)
+ || !((DamagedEvent) event).isCombatDamage()) {
+ return false;
+ }
+ this.getEffects().clear();
+ this.addEffect(new DamageTargetEffect(event.getAmount()));
+ FilterPermanent filter = new FilterPlaneswalkerPermanent("planeswalker " + opponent.getLogName() + " controls");
+ filter.add(new ControllerIdPredicate(opponent.getId()));
+ this.getTargets().clear();
+ this.addTarget(new TargetPermanent(filter));
+ return true;
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever {this} deals combat damage to an opponent, " +
+ "it deals that much damage to target planeswalker that player controls";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java b/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java
index 994db84272e..2a68085555b 100644
--- a/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java
+++ b/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java
@@ -1,7 +1,5 @@
-
package mage.cards.q;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
@@ -10,28 +8,21 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.AsThoughManaEffect;
-import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.AsThoughEffectType;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Duration;
-import mage.constants.Layer;
-import mage.constants.ManaType;
-import mage.constants.Outcome;
-import mage.constants.SubLayer;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.ManaPoolItem;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
+import mage.util.CardUtil;
+
+import java.util.UUID;
/**
- *
* @author spjspj
*/
public final class QuicksilverElemental extends CardImpl {
@@ -151,10 +142,9 @@ class QuickSilverElementalBlueManaEffect extends AsThoughEffectImpl implements A
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
if (objectId.equals(getTargetPointer().getFirst(game, source))) {
- if (affectedControllerId.equals(source.getControllerId())) {
- return true;
- }
+ return affectedControllerId.equals(source.getControllerId());
}
return false;
diff --git a/Mage.Sets/src/mage/cards/q/QuicksilverFountain.java b/Mage.Sets/src/mage/cards/q/QuicksilverFountain.java
index 5782524f16e..13acce44351 100644
--- a/Mage.Sets/src/mage/cards/q/QuicksilverFountain.java
+++ b/Mage.Sets/src/mage/cards/q/QuicksilverFountain.java
@@ -40,7 +40,7 @@ public final class QuicksilverFountain extends CardImpl {
public QuicksilverFountain(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
- // At the beginning of each player's upkeep, that player puts a flood counter on target non-Island land he or she controls of their choice. That land is an Island for as long as it has a flood counter on it.
+ // At the beginning of each player's upkeep, that player puts a flood counter on target non-Island land they control of their choice. That land is an Island for as long as it has a flood counter on it.
Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new QuicksilverFountainEffect(), TargetController.ANY, false, true);
ability.addTarget(new TargetLandPermanent());
ability.setTargetAdjuster(QuicksilverFountainAdjuster.instance);
diff --git a/Mage.Sets/src/mage/cards/r/RagMan.java b/Mage.Sets/src/mage/cards/r/RagMan.java
index 2910d356b59..32d11b92a78 100644
--- a/Mage.Sets/src/mage/cards/r/RagMan.java
+++ b/Mage.Sets/src/mage/cards/r/RagMan.java
@@ -1,6 +1,6 @@
-
package mage.cards.r;
+import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
@@ -14,13 +14,11 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetOpponent;
-import java.util.UUID;
-
/**
* @author Quercitron
*/
@@ -54,8 +52,6 @@ public final class RagMan extends CardImpl {
class RagManDiscardEffect extends OneShotEffect {
- private static final FilterCreatureCard filter = new FilterCreatureCard();
-
public RagManDiscardEffect() {
super(Outcome.Discard);
this.staticText = "and discards a creature card at random";
@@ -77,7 +73,7 @@ class RagManDiscardEffect extends OneShotEffect {
Cards creatureCardsInHand = new CardsImpl();
for (UUID cardId : player.getHand()) {
Card card = player.getHand().get(cardId, game);
- if (filter.match(card, game)) {
+ if (StaticFilters.FILTER_CARD_CREATURE.match(card, game)) {
creatureCardsInHand.add(card);
}
}
diff --git a/Mage.Sets/src/mage/cards/r/RagingRedcap.java b/Mage.Sets/src/mage/cards/r/RagingRedcap.java
new file mode 100644
index 00000000000..4681a9673a1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RagingRedcap.java
@@ -0,0 +1,37 @@
+package mage.cards.r;
+
+import mage.MageInt;
+import mage.abilities.keyword.DoubleStrikeAbility;
+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 RagingRedcap extends CardImpl {
+
+ public RagingRedcap(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
+
+ this.subtype.add(SubType.GOBLIN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(2);
+
+ // Double strike
+ this.addAbility(DoubleStrikeAbility.getInstance());
+ }
+
+ private RagingRedcap(final RagingRedcap card) {
+ super(card);
+ }
+
+ @Override
+ public RagingRedcap copy() {
+ return new RagingRedcap(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RagingRiver.java b/Mage.Sets/src/mage/cards/r/RagingRiver.java
index 1d5eba39f43..6af818b1391 100644
--- a/Mage.Sets/src/mage/cards/r/RagingRiver.java
+++ b/Mage.Sets/src/mage/cards/r/RagingRiver.java
@@ -41,7 +41,7 @@ public final class RagingRiver extends CardImpl {
public RagingRiver(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}{R}");
- // Whenever one or more creatures you control attack, each defending player divides all creatures without flying he or she controls into a "left" pile and a "right" pile. Then, for each attacking creature you control, choose "left" or "right." That creature can't be blocked this combat except by creatures with flying and creatures in a pile with the chosen label.
+ // Whenever one or more creatures you control attack, each defending player divides all creatures without flying they control into a "left" pile and a "right" pile. Then, for each attacking creature you control, choose "left" or "right." That creature can't be blocked this combat except by creatures with flying and creatures in a pile with the chosen label.
this.addAbility(new AttacksWithCreaturesTriggeredAbility(new RagingRiverEffect(), 1));
}
@@ -59,7 +59,7 @@ class RagingRiverEffect extends OneShotEffect {
public RagingRiverEffect() {
super(Outcome.Detriment);
- staticText = "each defending player divides all creatures without flying he or she controls into a \"left\" pile and a \"right\" pile. Then, for each attacking creature you control, choose \"left\" or \"right.\" That creature can't be blocked this combat except by creatures with flying and creatures in a pile with the chosen label";
+ staticText = "each defending player divides all creatures without flying they control into a \"left\" pile and a \"right\" pile. Then, for each attacking creature you control, choose \"left\" or \"right.\" That creature can't be blocked this combat except by creatures with flying and creatures in a pile with the chosen label";
}
public RagingRiverEffect(final RagingRiverEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/r/RagsRiches.java b/Mage.Sets/src/mage/cards/r/RagsRiches.java
index d8004b70a7c..39c744f4965 100644
--- a/Mage.Sets/src/mage/cards/r/RagsRiches.java
+++ b/Mage.Sets/src/mage/cards/r/RagsRiches.java
@@ -31,7 +31,7 @@ public final class RagsRiches extends SplitCard {
// to
// Riches
- // Each opponent chooses a creature he or she controls. You gain control of each of those creatures.
+ // Each opponent chooses a creature they control. You gain control of each of those creatures.
getRightHalfCard().addAbility(new AftermathAbility().setRuleAtTheTop(true));
getRightHalfCard().getSpellAbility().addEffect(new RichesEffect());
}
@@ -50,7 +50,7 @@ class RichesEffect extends OneShotEffect {
public RichesEffect() {
super(Outcome.Benefit);
- this.staticText = "Each opponent chooses a creature he or she controls. You gain control of each of those creatures.";
+ this.staticText = "Each opponent chooses a creature they control. You gain control of each of those creatures.";
}
public RichesEffect(final RichesEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/r/RaidingParty.java b/Mage.Sets/src/mage/cards/r/RaidingParty.java
index 9449c53670c..7e93728e68e 100644
--- a/Mage.Sets/src/mage/cards/r/RaidingParty.java
+++ b/Mage.Sets/src/mage/cards/r/RaidingParty.java
@@ -53,7 +53,7 @@ public final class RaidingParty extends CardImpl {
// Raiding Party can't be the target of white spells or abilities from white sources.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeTargetedSourceEffect(filterWhite, Duration.WhileOnBattlefield)));
- // Sacrifice an Orc: Each player may tap any number of untapped white creatures he or she controls. For each creature tapped this way, that player chooses up to two Plains. Then destroy all Plains that weren't chosen this way by any player.
+ // Sacrifice an Orc: Each player may tap any number of untapped white creatures they control. For each creature tapped this way, that player chooses up to two Plains. Then destroy all Plains that weren't chosen this way by any player.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RaidingPartyEffect(), new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, filterOrc, true))));
}
@@ -80,7 +80,7 @@ class RaidingPartyEffect extends OneShotEffect {
RaidingPartyEffect() {
super(Outcome.Detriment);
- staticText = "Each player may tap any number of untapped white creatures he or she controls. For each creature tapped this way, that player chooses up to two Plains. Then destroy all Plains that weren't chosen this way by any player";
+ staticText = "Each player may tap any number of untapped white creatures they control. For each creature tapped this way, that player chooses up to two Plains. Then destroy all Plains that weren't chosen this way by any player";
}
RaidingPartyEffect(RaidingPartyEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/r/RakdosTheDefiler.java b/Mage.Sets/src/mage/cards/r/RakdosTheDefiler.java
index eec277ccb07..c974dfc5ead 100644
--- a/Mage.Sets/src/mage/cards/r/RakdosTheDefiler.java
+++ b/Mage.Sets/src/mage/cards/r/RakdosTheDefiler.java
@@ -56,9 +56,9 @@ public final class RakdosTheDefiler extends CardImpl {
Ability ability = new AttacksTriggeredAbility(effect, false);
this.addAbility(ability);
- // Whenever Rakdos deals combat damage to a player, that player sacrifices half the non-Demon permanents he or she controls, rounded up.
+ // Whenever Rakdos deals combat damage to a player, that player sacrifices half the non-Demon permanents they control, rounded up.
effect = new SacrificeEffect(damageToPlayerTriggerFilter, new HalfValue(new PermanentsTargetOpponentControlsCount(damageToPlayerTriggerFilter), true), "");
- effect.setText("that player sacrifices half the non-Demon permanents he or she controls, rounded up");
+ effect.setText("that player sacrifices half the non-Demon permanents they control, rounded up");
ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect, false, true);
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/r/RallyForTheThrone.java b/Mage.Sets/src/mage/cards/r/RallyForTheThrone.java
new file mode 100644
index 00000000000..86e39e86e97
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RallyForTheThrone.java
@@ -0,0 +1,49 @@
+package mage.cards.r;
+
+import mage.abilities.condition.common.AdamantCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.StaticFilters;
+import mage.game.permanent.token.HumanToken;
+import mage.watchers.common.ManaSpentToCastWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RallyForTheThrone extends CardImpl {
+
+ private static final DynamicValue xValue
+ = new PermanentsOnBattlefieldCount(StaticFilters.FILTER_CONTROLLED_CREATURE);
+
+ public RallyForTheThrone(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}");
+
+ // Create two 1/1 white Human creature tokens.
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new HumanToken(), 2));
+
+ // Adamant — If at least three white mana was spent to cast this spell, you gain 1 life for each creature you control.
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new GainLifeEffect(xValue), AdamantCondition.WHITE, "
Adamant — " +
+ "If at least three white mana was spent to cast this spell, " +
+ "you gain 1 life for each creature you control."
+ ));
+ this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher());
+ }
+
+ private RallyForTheThrone(final RallyForTheThrone card) {
+ super(card);
+ }
+
+ @Override
+ public RallyForTheThrone copy() {
+ return new RallyForTheThrone(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RampartSmasher.java b/Mage.Sets/src/mage/cards/r/RampartSmasher.java
new file mode 100644
index 00000000000..381abf43da9
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RampartSmasher.java
@@ -0,0 +1,52 @@
+package mage.cards.r;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RampartSmasher extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Knights or Walls");
+
+ static {
+ filter.add(Predicates.or(
+ new SubtypePredicate(SubType.KNIGHT),
+ new SubtypePredicate(SubType.WALL)
+ ));
+ }
+
+ public RampartSmasher(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R/G}{R/G}{R/G}{R/G}");
+
+ this.subtype.add(SubType.GIANT);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(5);
+
+ // Rampart Smasher can't be blocked by Knights or Walls.
+ this.addAbility(new SimpleStaticAbility(
+ new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield)
+ ));
+ }
+
+ private RampartSmasher(final RampartSmasher card) {
+ super(card);
+ }
+
+ @Override
+ public RampartSmasher copy() {
+ return new RampartSmasher(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RangerCaptainOfEos.java b/Mage.Sets/src/mage/cards/r/RangerCaptainOfEos.java
index 0edaaf54442..a124319640d 100644
--- a/Mage.Sets/src/mage/cards/r/RangerCaptainOfEos.java
+++ b/Mage.Sets/src/mage/cards/r/RangerCaptainOfEos.java
@@ -65,7 +65,7 @@ class RangerCaptainOfEosEffect extends ContinuousRuleModifyingEffectImpl {
RangerCaptainOfEosEffect() {
super(Duration.EndOfTurn, Outcome.Benefit);
- staticText = "Your opponents can't noncreature cast spells this turn.";
+ staticText = "Your opponents can't cast noncreature spells this turn.";
}
private RangerCaptainOfEosEffect(final RangerCaptainOfEosEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/r/RankleMasterOfPranks.java b/Mage.Sets/src/mage/cards/r/RankleMasterOfPranks.java
new file mode 100644
index 00000000000..a823b84f7c7
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RankleMasterOfPranks.java
@@ -0,0 +1,68 @@
+package mage.cards.r;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.Mode;
+import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
+import mage.abilities.effects.common.DrawCardAllEffect;
+import mage.abilities.effects.common.LoseLifeAllPlayersEffect;
+import mage.abilities.effects.common.SacrificeAllEffect;
+import mage.abilities.effects.common.discard.DiscardEachPlayerEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.abilities.keyword.HasteAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.filter.StaticFilters;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RankleMasterOfPranks extends CardImpl {
+
+ public RankleMasterOfPranks(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.FAERIE);
+ this.subtype.add(SubType.ROGUE);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Haste
+ this.addAbility(HasteAbility.getInstance());
+
+ // Whenever Rankle, Master of Pranks deals combat damage to a player, choose any number —
+ // • Each player discards a card.
+ Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DiscardEachPlayerEffect(), false);
+
+ // • Each player loses 1 life and draws a card.
+ Mode mode = new Mode(new LoseLifeAllPlayersEffect(1));
+ mode.addEffect(new DrawCardAllEffect(1).setText("and draws a card"));
+ ability.addMode(mode);
+
+ // • Each player sacrifices a creature.
+ ability.addMode(new Mode(new SacrificeAllEffect(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
+
+ ability.getModes().setMinModes(0);
+ ability.getModes().setMaxModes(3);
+ ability.getModes().setChooseText("choose any number —");
+ this.addAbility(ability);
+ }
+
+ private RankleMasterOfPranks(final RankleMasterOfPranks card) {
+ super(card);
+ }
+
+ @Override
+ public RankleMasterOfPranks copy() {
+ return new RankleMasterOfPranks(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RashmiEternitiesCrafter.java b/Mage.Sets/src/mage/cards/r/RashmiEternitiesCrafter.java
index 6a09ed49408..56777047f50 100644
--- a/Mage.Sets/src/mage/cards/r/RashmiEternitiesCrafter.java
+++ b/Mage.Sets/src/mage/cards/r/RashmiEternitiesCrafter.java
@@ -1,4 +1,3 @@
-
package mage.cards.r;
import java.util.List;
@@ -38,7 +37,9 @@ public final class RashmiEternitiesCrafter extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(3);
- // Whenever you cast your first spell each turn, reveal the top card of your library. If it's a nonland card with converted mana cost less than that spell's, you may cast it without paying its mana cost. If you don't cast the revealed card, put it into your hand.
+ // Whenever you cast your first spell each turn, reveal the top card of your library.
+ // If it's a nonland card with converted mana cost less than that spell's, you may cast it
+ // without paying its mana cost. If you don't cast the revealed card, put it into your hand.
this.addAbility(new RashmiEternitiesCrafterTriggeredAbility(), new SpellsCastWatcher());
}
@@ -120,9 +121,14 @@ class RashmiEternitiesCrafterEffect extends OneShotEffect {
if (cmcObject == null
|| card.isLand()
|| card.getConvertedManaCost() >= (int) cmcObject
- || !controller.chooseUse(Outcome.PlayForFree, "Cast " + card.getName() + " without paying its mana cost?", source, game)
- || !controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
- controller.moveCards(card, Zone.HAND, source, game);
+ || !controller.chooseUse(Outcome.PlayForFree, "Cast " + card.getName() + " without paying its mana cost?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (!cardWasCast) {
+ controller.moveCards(card, Zone.HAND, source, game);
+ }
}
}
return true;
diff --git a/Mage.Sets/src/mage/cards/r/RayamiFirstOfTheFallen.java b/Mage.Sets/src/mage/cards/r/RayamiFirstOfTheFallen.java
index 7358f57d73a..dcdac69a328 100644
--- a/Mage.Sets/src/mage/cards/r/RayamiFirstOfTheFallen.java
+++ b/Mage.Sets/src/mage/cards/r/RayamiFirstOfTheFallen.java
@@ -18,6 +18,7 @@ import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentToken;
import mage.players.Player;
+import java.util.Collection;
import java.util.UUID;
/**
@@ -76,25 +77,24 @@ class RayamiFirstOfTheFallenEffect extends ContinuousEffectImpl {
.stream()
.filter(Card::isCreature)
.filter(card -> card.getCounters(game).getCount(CounterType.BLOOD) > 0)
- .forEach(card -> {
- card.getAbilities(game).stream().forEach(ability -> {
- if (ability instanceof FlyingAbility
- || ability instanceof FirstStrikeAbility
- || ability instanceof DoubleStrikeAbility
- || ability instanceof DeathtouchAbility
- || ability instanceof HasteAbility
- || ability instanceof HexproofAbility
- || ability instanceof IndestructibleAbility
- || ability instanceof LifelinkAbility
- || ability instanceof MenaceAbility
- || ability instanceof ReachAbility
- || ability instanceof TrampleAbility
- || ability instanceof VigilanceAbility) {
- sourcePermanent.addAbility(ability, source.getSourceId(), game);
- } else if (ability instanceof ProtectionAbility) {
- sourcePermanent.addAbility(ability, source.getSourceId(), game);
- }
- });
+ .map(card -> card.getAbilities(game))
+ .flatMap(Collection::stream)
+ .forEach(ability -> {
+ if (ability instanceof FlyingAbility
+ || ability instanceof FirstStrikeAbility
+ || ability instanceof DoubleStrikeAbility
+ || ability instanceof DeathtouchAbility
+ || ability instanceof HasteAbility
+ || ability instanceof HexproofAbility
+ || ability instanceof IndestructibleAbility
+ || ability instanceof LifelinkAbility
+ || ability instanceof MenaceAbility
+ || ability instanceof ReachAbility
+ || ability instanceof TrampleAbility
+ || ability instanceof VigilanceAbility
+ || ability instanceof ProtectionAbility) {
+ sourcePermanent.addAbility(ability, source.getSourceId(), game);
+ }
});
return true;
}
@@ -108,7 +108,7 @@ class RayamiFirstOfTheFallenEffect extends ContinuousEffectImpl {
class RayamiFirstOfTheFallenReplacementEffect extends ReplacementEffectImpl {
RayamiFirstOfTheFallenReplacementEffect() {
- super(Duration.EndOfTurn, Outcome.Exile);
+ super(Duration.WhileOnBattlefield, Outcome.Exile);
staticText = "If a nontoken creature would die, exile that card with a blood counter on it instead";
}
@@ -144,6 +144,6 @@ class RayamiFirstOfTheFallenReplacementEffect extends ReplacementEffectImpl {
ZoneChangeEvent zce = (ZoneChangeEvent) event;
return zce.isDiesEvent()
&& zce.getTarget().isCreature()
- && zce.getTarget() instanceof PermanentToken;
+ && !(zce.getTarget() instanceof PermanentToken);
}
}
diff --git a/Mage.Sets/src/mage/cards/r/RaziasPurification.java b/Mage.Sets/src/mage/cards/r/RaziasPurification.java
index dc9c802b808..8cce688db40 100644
--- a/Mage.Sets/src/mage/cards/r/RaziasPurification.java
+++ b/Mage.Sets/src/mage/cards/r/RaziasPurification.java
@@ -27,7 +27,7 @@ public final class RaziasPurification extends CardImpl {
public RaziasPurification(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}{W}");
- // Each player chooses three permanents he or she controls, then sacrifices the rest.
+ // Each player chooses three permanents they control, then sacrifices the rest.
this.getSpellAbility().addEffect(new RaziasPurificationEffect());
}
@@ -45,7 +45,7 @@ class RaziasPurificationEffect extends OneShotEffect {
public RaziasPurificationEffect() {
super(Outcome.DestroyPermanent);
- staticText = "Each player chooses three permanents he or she controls, then sacrifices the rest";
+ staticText = "Each player chooses three permanents they control, then sacrifices the rest";
}
public RaziasPurificationEffect(RaziasPurificationEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/r/RealmCloakedGiant.java b/Mage.Sets/src/mage/cards/r/RealmCloakedGiant.java
new file mode 100644
index 00000000000..091d45b1d83
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RealmCloakedGiant.java
@@ -0,0 +1,52 @@
+package mage.cards.r;
+
+import mage.MageInt;
+import mage.abilities.effects.common.DestroyAllEffect;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RealmCloakedGiant extends AdventureCard {
+
+ private static final FilterCreaturePermanent filter
+ = new FilterCreaturePermanent("non-Giant creatures");
+
+ static {
+ filter.add(Predicates.not(new SubtypePredicate(SubType.GIANT)));
+ }
+
+ public RealmCloakedGiant(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{5}{W}{W}", "Cast Off", "{3}{W}{W}");
+
+ this.subtype.add(SubType.GIANT);
+ this.power = new MageInt(7);
+ this.toughness = new MageInt(7);
+
+ // Vigilance
+ this.addAbility(VigilanceAbility.getInstance());
+
+ // Cast Off
+ // Destroy all non-Giant creatures.
+ this.getSpellCard().getSpellAbility().addEffect(new DestroyAllEffect(filter));
+ }
+
+ private RealmCloakedGiant(final RealmCloakedGiant card) {
+ super(card);
+ }
+
+ @Override
+ public RealmCloakedGiant copy() {
+ return new RealmCloakedGiant(this);
+ }
+}
+// clock up
diff --git a/Mage.Sets/src/mage/cards/r/RealmsUncharted.java b/Mage.Sets/src/mage/cards/r/RealmsUncharted.java
index 399fb4494fd..09752eba1a6 100644
--- a/Mage.Sets/src/mage/cards/r/RealmsUncharted.java
+++ b/Mage.Sets/src/mage/cards/r/RealmsUncharted.java
@@ -1,16 +1,9 @@
-
package mage.cards.r;
-import java.util.Set;
-import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
-import mage.cards.Card;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-import mage.cards.Cards;
-import mage.cards.CardsImpl;
+import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
@@ -23,14 +16,16 @@ import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetOpponent;
+import java.util.Set;
+import java.util.UUID;
+
/**
- *
* @author North
*/
public final class RealmsUncharted extends CardImpl {
public RealmsUncharted(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}");
// Search your library for four land cards with different names and reveal them. An opponent chooses two of those cards. Put the chosen cards into your graveyard and the rest into your hand. Then shuffle your library.
this.getSpellAbility().addEffect(new RealmsUnchartedEffect());
@@ -128,7 +123,7 @@ class RealmsUnchartedTarget extends TargetCardInLibrary {
}
@Override
- public boolean canTarget(UUID id, Cards cards, Game game) {
+ public boolean canTarget(UUID playerId, UUID id, Ability source, Cards cards, Game game) {
Card card = cards.get(id, game);
if (card != null) {
for (UUID targetId : this.getTargets()) {
@@ -137,7 +132,7 @@ class RealmsUnchartedTarget extends TargetCardInLibrary {
return false;
}
}
- return filter.match(card, game);
+ return filter.match(card, playerId, game);
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/r/ReaperOfNight.java b/Mage.Sets/src/mage/cards/r/ReaperOfNight.java
new file mode 100644
index 00000000000..580020f7741
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/ReaperOfNight.java
@@ -0,0 +1,66 @@
+package mage.cards.r;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.effects.common.discard.DiscardTargetEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.common.TargetOpponent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ReaperOfNight extends AdventureCard {
+
+ public ReaperOfNight(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{5}{B}{B}", "Harvest Fear", "{3}{B}");
+
+ this.subtype.add(SubType.SPECTER);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(5);
+
+ // Whenever Reaper of Night attacks, if defending player has two or fewer cards in hand, it gains flying until end of turn.
+ this.addAbility(new ConditionalInterveningIfTriggeredAbility(
+ new AttacksTriggeredAbility(new GainAbilitySourceEffect(
+ FlyingAbility.getInstance(), Duration.EndOfTurn
+ ), false), ReaperOfNightCondition.instance, "Whenever {this} attacks, " +
+ "if defending player has two or fewer cards in hand, it gains flying until end of turn."
+ ));
+
+ // Harvest Fear
+ // Target opponent discards two cards.
+ this.getSpellCard().getSpellAbility().addEffect(new DiscardTargetEffect(2));
+ this.getSpellCard().getSpellAbility().addTarget(new TargetOpponent());
+ }
+
+ private ReaperOfNight(final ReaperOfNight card) {
+ super(card);
+ }
+
+ @Override
+ public ReaperOfNight copy() {
+ return new ReaperOfNight(this);
+ }
+}
+
+enum ReaperOfNightCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(game.getCombat().getDefendingPlayerId(source.getSourceId(), game));
+ return player != null && player.getHand().size() <= 2;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/r/Reclamation.java b/Mage.Sets/src/mage/cards/r/Reclamation.java
index 04471bf9f7d..850a27a5f4f 100644
--- a/Mage.Sets/src/mage/cards/r/Reclamation.java
+++ b/Mage.Sets/src/mage/cards/r/Reclamation.java
@@ -29,7 +29,7 @@ public final class Reclamation extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}{W}");
- // Black creatures can't attack unless their controller sacrifices a land for each black creature he or she controls that's attacking.
+ // Black creatures can't attack unless their controller sacrifices a land for each black creature they control that's attacking.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ReclamationCostToAttackBlockEffect()));
}
diff --git a/Mage.Sets/src/mage/cards/r/RedcapMelee.java b/Mage.Sets/src/mage/cards/r/RedcapMelee.java
new file mode 100644
index 00000000000..bad15206c2a
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RedcapMelee.java
@@ -0,0 +1,72 @@
+package mage.cards.r;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.SacrificeControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetCreatureOrPlaneswalker;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RedcapMelee extends CardImpl {
+
+ public RedcapMelee(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}");
+
+ // Redcap Melee deals 4 damage to target creature or planeswalker. If a nonred permanent is dealt damage this way, you sacrifice a land.
+ this.getSpellAbility().addEffect(new RedcapMeleeEffect());
+ this.getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker());
+ }
+
+ private RedcapMelee(final RedcapMelee card) {
+ super(card);
+ }
+
+ @Override
+ public RedcapMelee copy() {
+ return new RedcapMelee(this);
+ }
+}
+
+class RedcapMeleeEffect extends OneShotEffect {
+
+ private static final Effect effect = new SacrificeControllerEffect(StaticFilters.FILTER_LAND, 1, "");
+
+ RedcapMeleeEffect() {
+ super(Outcome.Damage);
+ staticText = "{this} deals 4 damage to target creature or planeswalker. " +
+ "If a nonred permanent is dealt damage this way, you sacrifice a land.";
+ }
+
+ private RedcapMeleeEffect(final RedcapMeleeEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public RedcapMeleeEffect copy() {
+ return new RedcapMeleeEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = game.getPermanent(source.getFirstTarget());
+ if (permanent == null) {
+ return false;
+ }
+ boolean isRed = permanent.getColor(game).isRed();
+ if (permanent.damage(4, source.getSourceId(), game) > 0 && !isRed) {
+ return effect.apply(game, source);
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/r/RedcapRaiders.java b/Mage.Sets/src/mage/cards/r/RedcapRaiders.java
new file mode 100644
index 00000000000..876af131591
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RedcapRaiders.java
@@ -0,0 +1,62 @@
+package mage.cards.r;
+
+import mage.MageInt;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.costs.common.TapTargetCost;
+import mage.abilities.effects.common.DoIfCostPaid;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.filter.predicate.permanent.TappedPredicate;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RedcapRaiders extends CardImpl {
+
+ private static final FilterControlledPermanent filter
+ = new FilterControlledCreaturePermanent("an untapped non-Human creature you control");
+
+ static {
+ filter.add(Predicates.not(TappedPredicate.instance));
+ filter.add(Predicates.not(new SubtypePredicate(SubType.HUMAN)));
+ }
+
+ public RedcapRaiders(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
+
+ this.subtype.add(SubType.GOBLIN);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(2);
+
+ // Whenever Redcap Raiders attacks, you may tap an untapped non-Human creature you control. If you do, Redcap Raiders gets +1/+1 and gains trample until end of turn.
+ this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(
+ new BoostSourceEffect(1, 1, Duration.EndOfTurn).setText("{this} gets +1/+1"),
+ new TapTargetCost(new TargetControlledPermanent(filter))
+ ).addEffect(new GainAbilitySourceEffect(
+ TrampleAbility.getInstance(), Duration.EndOfTurn
+ ).setText("and gains trample until end of turn")), false));
+ }
+
+ private RedcapRaiders(final RedcapRaiders card) {
+ super(card);
+ }
+
+ @Override
+ public RedcapRaiders copy() {
+ return new RedcapRaiders(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/ReignOfTerror.java b/Mage.Sets/src/mage/cards/r/ReignOfTerror.java
new file mode 100644
index 00000000000..c19cb0cd468
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/ReignOfTerror.java
@@ -0,0 +1,82 @@
+package mage.cards.r;
+
+import mage.ObjectColor;
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.ColorPredicate;
+import mage.game.Game;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ReignOfTerror extends CardImpl {
+
+ public ReignOfTerror(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}{B}");
+
+ // Destroy all green creatures or all white creatures. They can't be regenerated. You lose 2 life for each creature that died this way.
+ this.getSpellAbility().addEffect(new ReignOfTerrorEffect());
+ }
+
+ private ReignOfTerror(final ReignOfTerror card) {
+ super(card);
+ }
+
+ @Override
+ public ReignOfTerror copy() {
+ return new ReignOfTerror(this);
+ }
+}
+
+class ReignOfTerrorEffect extends OneShotEffect {
+
+ private static final FilterPermanent greenFilter = new FilterCreaturePermanent();
+ private static final FilterPermanent whiteFilter = new FilterCreaturePermanent();
+
+ static {
+ greenFilter.add(new ColorPredicate(ObjectColor.GREEN));
+ whiteFilter.add(new ColorPredicate(ObjectColor.WHITE));
+ }
+
+ ReignOfTerrorEffect() {
+ super(Outcome.Benefit);
+ staticText = "Destroy all green creatures or all white creatures. They can't be regenerated. " +
+ "You lose 2 life for each creature that died this way.";
+ }
+
+ private ReignOfTerrorEffect(final ReignOfTerrorEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ReignOfTerrorEffect copy() {
+ return new ReignOfTerrorEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ FilterPermanent filter = player.chooseUse(
+ outcome, "Destroy all green creatures or all white creatures?",
+ "", "Green", "White", source, game
+ ) ? greenFilter : whiteFilter;
+ int died = game.getBattlefield()
+ .getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)
+ .stream()
+ .mapToInt(permanent -> permanent.destroy(source.getSourceId(), game, true) ? 1 : 0)
+ .sum();
+ return player.loseLife(2 * died, game, false) > 0;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RepeatedReverberation.java b/Mage.Sets/src/mage/cards/r/RepeatedReverberation.java
index a587f68add3..e017510a8ca 100644
--- a/Mage.Sets/src/mage/cards/r/RepeatedReverberation.java
+++ b/Mage.Sets/src/mage/cards/r/RepeatedReverberation.java
@@ -96,8 +96,8 @@ class RepeatedReverberationTriggeredAbility extends DelayedTriggeredAbility {
@Override
public String getRule() {
- return "When you next cast an instant spell, cast a sorcery spell, or activate a loyalty ability this turn, " +
- "copy that spell or ability twice. You may choose new targets for the copies.";
+ return "When you next cast an instant spell, cast a sorcery spell, or activate a loyalty ability this turn, "
+ + "copy that spell or ability twice. You may choose new targets for the copies.";
}
}
@@ -118,7 +118,7 @@ class RepeatedReverberationEffect extends OneShotEffect {
return false;
}
Player controller = game.getPlayer(source.getControllerId());
- Permanent sourcePermanent = game.getPermanent(stackAbility.getStackAbility().getSourceId());
+ Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(stackAbility.getStackAbility().getSourceId());
if (controller == null || sourcePermanent == null) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/r/RepelIntruders.java b/Mage.Sets/src/mage/cards/r/RepelIntruders.java
index 93f8d7eabe9..2e939e67834 100644
--- a/Mage.Sets/src/mage/cards/r/RepelIntruders.java
+++ b/Mage.Sets/src/mage/cards/r/RepelIntruders.java
@@ -31,10 +31,10 @@ public final class RepelIntruders extends CardImpl {
target.setRequired(false);
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new CreateTokenEffect(new KithkinToken(), 2),
- new ManaWasSpentCondition(ColoredManaSymbol.W), "Create two 1/1 white Kithkin Soldier creature tokens if {W} was spent to cast {this}"));
+ new ManaWasSpentCondition(ColoredManaSymbol.W), "Create two 1/1 white Kithkin Soldier creature tokens if {W} was spent to cast this spell"));
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new CounterTargetEffect(),
- new ManaWasSpentCondition(ColoredManaSymbol.U), " Counter up to one target creature spell if {U} was spent to cast {this}"));
+ new ManaWasSpentCondition(ColoredManaSymbol.U), " Counter up to one target creature spell if {U} was spent to cast this spell"));
this.getSpellAbility().addTarget(target);
this.getSpellAbility().addEffect(new InfoEffect("(Do both if {W}{U} was spent.)"));
this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher());
diff --git a/Mage.Sets/src/mage/cards/r/Repopulate.java b/Mage.Sets/src/mage/cards/r/Repopulate.java
index 0bc07c48ee7..7ceaa5452a0 100644
--- a/Mage.Sets/src/mage/cards/r/Repopulate.java
+++ b/Mage.Sets/src/mage/cards/r/Repopulate.java
@@ -1,4 +1,3 @@
-
package mage.cards.r;
import java.util.Set;
@@ -13,7 +12,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
@@ -25,8 +24,7 @@ import mage.target.TargetPlayer;
public final class Repopulate extends CardImpl {
public Repopulate(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{G}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}");
// Shuffle all creature cards from target player's graveyard into that player's library.
this.getSpellAbility().addTarget(new TargetPlayer());
@@ -60,9 +58,8 @@ class RepopulateEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getFirstTarget());
if (player != null) {
- Set cards = player.getGraveyard().getCards(new FilterCreatureCard(), game);
- for(Card card : cards)
- {
+ Set cards = player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game);
+ for (Card card : cards) {
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
}
player.shuffleLibrary(source, game);
diff --git a/Mage.Sets/src/mage/cards/r/ResoluteRider.java b/Mage.Sets/src/mage/cards/r/ResoluteRider.java
new file mode 100644
index 00000000000..ed3b33441ed
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/ResoluteRider.java
@@ -0,0 +1,49 @@
+package mage.cards.r;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.IndestructibleAbility;
+import mage.abilities.keyword.LifelinkAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ResoluteRider extends CardImpl {
+
+ public ResoluteRider(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W/B}{W/B}{W/B}{W/B}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(2);
+
+ // {W/B}{W/B}: Resolute Rider gains lifelink until end of turn.
+ this.addAbility(new SimpleActivatedAbility(new GainAbilitySourceEffect(
+ LifelinkAbility.getInstance(), Duration.EndOfTurn
+ ), new ManaCostsImpl("{W/B}{W/B}")));
+
+ // {W/B}{W/B}{W/B}: Resolute Rider gains indestructible until end of turn.
+ this.addAbility(new SimpleActivatedAbility(new GainAbilitySourceEffect(
+ IndestructibleAbility.getInstance(), Duration.EndOfTurn
+ ), new ManaCostsImpl("{W/B}{W/B}{W/B}")));
+ }
+
+ private ResoluteRider(final ResoluteRider card) {
+ super(card);
+ }
+
+ @Override
+ public ResoluteRider copy() {
+ return new ResoluteRider(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RestoreBalance.java b/Mage.Sets/src/mage/cards/r/RestoreBalance.java
index bcbaffd8d8d..dec27da79f1 100644
--- a/Mage.Sets/src/mage/cards/r/RestoreBalance.java
+++ b/Mage.Sets/src/mage/cards/r/RestoreBalance.java
@@ -34,7 +34,7 @@ public final class RestoreBalance extends CardImpl {
// Suspend 6-{W}
this.addAbility(new SuspendAbility(6, new ColoredManaCost(ColoredManaSymbol.W), this));
- // Each player chooses a number of lands he or she controls equal to the number of lands controlled by the player who controls the fewest, then sacrifices the rest. Players sacrifice creatures and discard cards the same way.
+ // Each player chooses a number of lands they control equal to the number of lands controlled by the player who controls the fewest, then sacrifices the rest. Players sacrifice creatures and discard cards the same way.
this.getSpellAbility().addEffect(new RestoreBalanceEffect());
}
@@ -53,7 +53,7 @@ class RestoreBalanceEffect extends OneShotEffect {
RestoreBalanceEffect() {
super(Outcome.Sacrifice);
- staticText = "Each player chooses a number of lands he or she controls equal to the number of lands controlled by the player who controls the fewest, then sacrifices the rest. Players sacrifice creatures and discard cards the same way";
+ staticText = "Each player chooses a number of lands they control equal to the number of lands controlled by the player who controls the fewest, then sacrifices the rest. Players sacrifice creatures and discard cards the same way";
}
RestoreBalanceEffect(final RestoreBalanceEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/r/ReturnOfTheWildspeaker.java b/Mage.Sets/src/mage/cards/r/ReturnOfTheWildspeaker.java
new file mode 100644
index 00000000000..ea0ae6927e6
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/ReturnOfTheWildspeaker.java
@@ -0,0 +1,84 @@
+package mage.cards.r;
+
+import mage.MageInt;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.Mode;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+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.constants.SubType;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ReturnOfTheWildspeaker extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Human creatures");
+
+ static {
+ filter.add(Predicates.not(new SubtypePredicate(SubType.HUMAN)));
+ }
+
+ public ReturnOfTheWildspeaker(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{G}");
+
+ // Choose one —
+ // • Draw cards equal to the greatest power among non-Human creatures you control.
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(ReturnOfTheWildspeakerValue.instance)
+ .setText("draw cards equal to the greatest power among non-Human creatures you control"));
+
+ // • Non-Human creatures you control get +3/+3 until end of turn.
+ this.getSpellAbility().addMode(new Mode(
+ new BoostControlledEffect(3, 3, Duration.EndOfTurn, filter)
+ ));
+ }
+
+ private ReturnOfTheWildspeaker(final ReturnOfTheWildspeaker card) {
+ super(card);
+ }
+
+ @Override
+ public ReturnOfTheWildspeaker copy() {
+ return new ReturnOfTheWildspeaker(this);
+ }
+}
+
+enum ReturnOfTheWildspeakerValue implements DynamicValue {
+ instance;
+
+ @Override
+ public int calculate(Game game, Ability sourceAbility, Effect effect) {
+ return game.getBattlefield()
+ .getAllActivePermanents(sourceAbility.getControllerId())
+ .stream()
+ .filter(Permanent::isCreature)
+ .filter(permanent -> !permanent.hasSubtype(SubType.HUMAN, game))
+ .map(MageObject::getPower)
+ .mapToInt(MageInt::getValue)
+ .max()
+ .orElse(0);
+ }
+
+ @Override
+ public DynamicValue copy() {
+ return instance;
+ }
+
+ @Override
+ public String getMessage() {
+ return "";
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/r/RevengeOfRavens.java b/Mage.Sets/src/mage/cards/r/RevengeOfRavens.java
new file mode 100644
index 00000000000..e37f9a5ed68
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RevengeOfRavens.java
@@ -0,0 +1,41 @@
+package mage.cards.r;
+
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksAllTriggeredAbility;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.effects.common.LoseLifeTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SetTargetPointer;
+import mage.filter.StaticFilters;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RevengeOfRavens extends CardImpl {
+
+ public RevengeOfRavens(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}");
+
+ // Whenever a creature attacks you or a planeswalker you control, that creature's controller loses 1 life and you gain 1 life.
+ Ability ability = new AttacksAllTriggeredAbility(
+ new LoseLifeTargetEffect(1).setText("that creature's controller loses 1 life"),
+ false, StaticFilters.FILTER_PERMANENT_CREATURE,
+ SetTargetPointer.PLAYER, true, true
+ );
+ ability.addEffect(new GainLifeEffect(1).concatBy("and"));
+ this.addAbility(ability);
+ }
+
+ private RevengeOfRavens(final RevengeOfRavens card) {
+ super(card);
+ }
+
+ @Override
+ public RevengeOfRavens copy() {
+ return new RevengeOfRavens(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/ReverentHunter.java b/Mage.Sets/src/mage/cards/r/ReverentHunter.java
index 8791c276c59..df8997dc6a4 100644
--- a/Mage.Sets/src/mage/cards/r/ReverentHunter.java
+++ b/Mage.Sets/src/mage/cards/r/ReverentHunter.java
@@ -1,7 +1,5 @@
-
package mage.cards.r;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.common.DevotionCount;
@@ -10,17 +8,17 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
-import mage.constants.ColoredManaSymbol;
import mage.counters.CounterType;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class ReverentHunter extends CardImpl {
public ReverentHunter(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ARCHER);
@@ -28,11 +26,12 @@ public final class ReverentHunter extends CardImpl {
this.toughness = new MageInt(1);
// When Reverent Hunter enters the battlefield, put a number of +1/+1 counters on it equal to your devotion to green.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), new DevotionCount(ColoredManaSymbol.G), true)));
-
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(
+ CounterType.P1P1.createInstance(0), DevotionCount.G, true
+ )).addHint(DevotionCount.G.getHint()));
}
- public ReverentHunter(final ReverentHunter card) {
+ private ReverentHunter(final ReverentHunter card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/r/ReversalOfFortune.java b/Mage.Sets/src/mage/cards/r/ReversalOfFortune.java
index 80f2f9310c0..9d681760b72 100644
--- a/Mage.Sets/src/mage/cards/r/ReversalOfFortune.java
+++ b/Mage.Sets/src/mage/cards/r/ReversalOfFortune.java
@@ -1,4 +1,3 @@
-
package mage.cards.r;
import java.util.UUID;
@@ -28,7 +27,8 @@ public final class ReversalOfFortune extends CardImpl {
public ReversalOfFortune(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}{R}");
- // Target opponent reveals their hand. You may copy an instant or sorcery card in it. If you do, you may cast the copy without paying its mana cost.
+ // Target opponent reveals their hand. You may copy an instant or sorcery
+ // card in it. If you do, you may cast the copy without paying its mana cost.
this.getSpellAbility().addEffect(new ReversalOfFortuneEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
}
@@ -47,7 +47,9 @@ class ReversalOfFortuneEffect extends OneShotEffect {
public ReversalOfFortuneEffect() {
super(Outcome.Copy);
- this.staticText = "Target opponent reveals their hand. You may copy an instant or sorcery card in it. If you do, you may cast the copy without paying its mana cost";
+ this.staticText = "Target opponent reveals their hand. You may copy an "
+ + "instant or sorcery card in it. If you do, you may cast the "
+ + "copy without paying its mana cost";
}
public ReversalOfFortuneEffect(final ReversalOfFortuneEffect effect) {
@@ -64,7 +66,8 @@ class ReversalOfFortuneEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Player opponent = game.getPlayer(source.getFirstTarget());
- if (controller != null && opponent != null) {
+ if (controller != null
+ && opponent != null) {
// Target opponent reveals their hand
Cards revealedCards = new CardsImpl();
revealedCards.addAll(opponent.getHand());
@@ -73,13 +76,16 @@ class ReversalOfFortuneEffect extends OneShotEffect {
//You may copy an instant or sorcery card in it
TargetCard target = new TargetCard(1, Zone.HAND, new FilterInstantOrSorceryCard());
target.setRequired(false);
- if (controller.choose(outcome, revealedCards, target, game)) {
+ if (controller.choose(Outcome.PlayForFree, revealedCards, target, game)) {
Card card = revealedCards.get(target.getFirstTarget(), game);
//If you do, you may cast the copy without paying its mana cost
if (card != null) {
Card copiedCard = game.copyCard(card, source, source.getControllerId());
- if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
- controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ if (controller.chooseUse(Outcome.PlayForFree, "Cast the copied card without paying mana cost?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(copiedCard, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), null);
}
} else {
return false;
diff --git a/Mage.Sets/src/mage/cards/r/Reweave.java b/Mage.Sets/src/mage/cards/r/Reweave.java
index 9f9e44df6fd..73fd171b5f1 100644
--- a/Mage.Sets/src/mage/cards/r/Reweave.java
+++ b/Mage.Sets/src/mage/cards/r/Reweave.java
@@ -29,7 +29,7 @@ public final class Reweave extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{5}{U}");
this.subtype.add(SubType.ARCANE);
- // Target permanent's controller sacrifices it. If he or she does, that player reveals cards from the top of their library until he or she reveals a permanent card that shares a card type with the sacrificed permanent, puts that card onto the battlefield, then shuffles their library.
+ // Target permanent's controller sacrifices it. If they do, that player reveals cards from the top of their library until they reveal a permanent card that shares a card type with the sacrificed permanent, puts that card onto the battlefield, then shuffles their library.
this.getSpellAbility().addEffect(new ReweaveEffect());
Target target = new TargetPermanent();
this.getSpellAbility().addTarget(target);
@@ -54,7 +54,7 @@ class ReweaveEffect extends OneShotEffect {
public ReweaveEffect() {
super(Outcome.Detriment);
- this.staticText = "Target permanent's controller sacrifices it. If he or she does, that player reveals cards from the top of their library until he or she reveals a permanent card that shares a card type with the sacrificed permanent, puts that card onto the battlefield, then shuffles their library";
+ this.staticText = "Target permanent's controller sacrifices it. If they do, that player reveals cards from the top of their library until they reveal a permanent card that shares a card type with the sacrificed permanent, puts that card onto the battlefield, then shuffles their library";
}
public ReweaveEffect(final ReweaveEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/r/RhysticLightning.java b/Mage.Sets/src/mage/cards/r/RhysticLightning.java
index 07e93cf8fd7..9499612475d 100644
--- a/Mage.Sets/src/mage/cards/r/RhysticLightning.java
+++ b/Mage.Sets/src/mage/cards/r/RhysticLightning.java
@@ -20,10 +20,10 @@ public final class RhysticLightning extends CardImpl {
public RhysticLightning(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}");
- // Rhystic Lightning deals 4 damage to any target unless that creature's controller or that player pays {2}. If he or she does, Rhystic Lightning deals 2 damage to the creature or player.
+ // Rhystic Lightning deals 4 damage to any target unless that creature's controller or that player pays {2}. If they do, Rhystic Lightning deals 2 damage to the creature or player.
Effect effect = new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new DamageTargetEffect(4), new DamageTargetEffect(2), new ManaCostsImpl("{2}"),
"Pay {2} to have {this} deal 2 damage instead of 4 damage?");
- effect.setText("{this} deals 4 damage to any target unless that creature's controller or that player pays {2}. If he or she does, {this} deals 2 damage to the creature or player");
+ effect.setText("{this} deals 4 damage to any target unless that creature's controller or that player pays {2}. If they do, {this} deals 2 damage to the creature or player");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetAnyTarget());
}
diff --git a/Mage.Sets/src/mage/cards/r/RhysticSyphon.java b/Mage.Sets/src/mage/cards/r/RhysticSyphon.java
index 92f3c63971c..249e1a7a836 100644
--- a/Mage.Sets/src/mage/cards/r/RhysticSyphon.java
+++ b/Mage.Sets/src/mage/cards/r/RhysticSyphon.java
@@ -21,10 +21,10 @@ public final class RhysticSyphon extends CardImpl {
public RhysticSyphon(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}{B}");
- // Unless target player pays {3}, he or she loses 5 life and you gain 5 life.
+ // Unless target player pays {3}, they lose 5 life and you gain 5 life.
DoUnlessTargetPlayerOrTargetsControllerPaysEffect effect = new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new LoseLifeTargetEffect(5), new ManaCostsImpl("{3}"));
effect.addEffect(new GainLifeEffect(5));
- effect.setText("Unless target player pays {3}, he or she loses 5 life and you gain 5 life");
+ effect.setText("Unless target player pays {3}, they lose 5 life and you gain 5 life");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetPlayer());
}
diff --git a/Mage.Sets/src/mage/cards/r/RibbonsOfNight.java b/Mage.Sets/src/mage/cards/r/RibbonsOfNight.java
index f503fc24bc6..6294cfedec6 100644
--- a/Mage.Sets/src/mage/cards/r/RibbonsOfNight.java
+++ b/Mage.Sets/src/mage/cards/r/RibbonsOfNight.java
@@ -36,7 +36,7 @@ public final class RibbonsOfNight extends CardImpl {
//If {U} was spent to cast Ribbons of Night, draw a card.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new DrawCardSourceControllerEffect(1),
- new ManaWasSpentCondition(ColoredManaSymbol.U), "If {U} was spent to cast {this}, draw a card"));
+ new ManaWasSpentCondition(ColoredManaSymbol.U), "If {U} was spent to cast this spell, draw a card"));
}
public RibbonsOfNight(final RibbonsOfNight card) {
diff --git a/Mage.Sets/src/mage/cards/r/RimrockKnight.java b/Mage.Sets/src/mage/cards/r/RimrockKnight.java
new file mode 100644
index 00000000000..da237fdba34
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RimrockKnight.java
@@ -0,0 +1,45 @@
+package mage.cards.r;
+
+import mage.MageInt;
+import mage.abilities.common.CantBlockAbility;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RimrockKnight extends AdventureCard {
+
+ public RimrockKnight(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.INSTANT}, "{1}{R}", "Boulder Rush", "{R}");
+
+ this.subtype.add(SubType.DWARF);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(1);
+
+ // Rimrock Knight can't block
+ this.addAbility(new CantBlockAbility());
+
+ // Boulder Rush
+ // Target creature gets +2/+0 until end of turn.
+ this.getSpellCard().getSpellAbility().addEffect(new BoostTargetEffect(2, 0, Duration.EndOfTurn));
+ this.getSpellCard().getSpellAbility().addTarget(new TargetCreaturePermanent());
+ }
+
+ private RimrockKnight(final RimrockKnight card) {
+ super(card);
+ }
+
+ @Override
+ public RimrockKnight copy() {
+ return new RimrockKnight(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RishadanBrigand.java b/Mage.Sets/src/mage/cards/r/RishadanBrigand.java
index 2558e74b216..92d4e8f2cea 100644
--- a/Mage.Sets/src/mage/cards/r/RishadanBrigand.java
+++ b/Mage.Sets/src/mage/cards/r/RishadanBrigand.java
@@ -28,7 +28,7 @@ public final class RishadanBrigand extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
- // When Rishadan Brigand enters the battlefield, each opponent sacrifices a permanent unless he or she pays {3}.
+ // When Rishadan Brigand enters the battlefield, each opponent sacrifices a permanent unless they pay {3}.
this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeOpponentsUnlessPayEffect(3)));
// Rishadan Brigand can block only creatures with flying.
diff --git a/Mage.Sets/src/mage/cards/r/RishadanCutpurse.java b/Mage.Sets/src/mage/cards/r/RishadanCutpurse.java
index fd53fa1ee8d..8abd4a7cc27 100644
--- a/Mage.Sets/src/mage/cards/r/RishadanCutpurse.java
+++ b/Mage.Sets/src/mage/cards/r/RishadanCutpurse.java
@@ -23,7 +23,7 @@ public final class RishadanCutpurse extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(1);
- // When Rishadan Cutpurse enters the battlefield, each opponent sacrifices a permanent unless he or she pays {1}.
+ // When Rishadan Cutpurse enters the battlefield, each opponent sacrifices a permanent unless they pay {1}.
this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeOpponentsUnlessPayEffect(1)));
}
diff --git a/Mage.Sets/src/mage/cards/r/RishadanFootpad.java b/Mage.Sets/src/mage/cards/r/RishadanFootpad.java
index 43623a291ed..71dc0e6ce9f 100644
--- a/Mage.Sets/src/mage/cards/r/RishadanFootpad.java
+++ b/Mage.Sets/src/mage/cards/r/RishadanFootpad.java
@@ -23,7 +23,7 @@ public final class RishadanFootpad extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- // When Rishadan Footpad enters the battlefield, each opponent sacrifices a permanent unless he or she pays {2}.
+ // When Rishadan Footpad enters the battlefield, each opponent sacrifices a permanent unless they pay {2}.
this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeOpponentsUnlessPayEffect(2)));
}
diff --git a/Mage.Sets/src/mage/cards/r/RisingWaters.java b/Mage.Sets/src/mage/cards/r/RisingWaters.java
index 845a859371c..9ad45ab02dd 100644
--- a/Mage.Sets/src/mage/cards/r/RisingWaters.java
+++ b/Mage.Sets/src/mage/cards/r/RisingWaters.java
@@ -32,7 +32,7 @@ public final class RisingWaters extends CardImpl {
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new DontUntapInControllersUntapStepAllEffect(Duration.WhileOnBattlefield, TargetController.ANY, StaticFilters.FILTER_LANDS)));
- // At the beginning of each player's upkeep, that player untaps a land he or she controls.
+ // At the beginning of each player's upkeep, that player untaps a land they control.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new RisingWatersUntapEffect(), TargetController.ANY, false));
}
@@ -50,7 +50,7 @@ class RisingWatersUntapEffect extends OneShotEffect {
public RisingWatersUntapEffect() {
super(Outcome.Untap);
- this.staticText = "that player untaps a land he or she controls";
+ this.staticText = "that player untaps a land they control";
}
public RisingWatersUntapEffect(final RisingWatersUntapEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/r/RitualOfTheReturned.java b/Mage.Sets/src/mage/cards/r/RitualOfTheReturned.java
index 8a5c0e84e07..9de5f94614c 100644
--- a/Mage.Sets/src/mage/cards/r/RitualOfTheReturned.java
+++ b/Mage.Sets/src/mage/cards/r/RitualOfTheReturned.java
@@ -1,4 +1,3 @@
-
package mage.cards.r;
import java.util.UUID;
@@ -11,7 +10,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.token.RitualOfTheReturnedZombieToken;
import mage.players.Player;
@@ -28,7 +27,7 @@ public final class RitualOfTheReturned extends CardImpl {
// Exile target creature card from your graveyard. Create a black Zombie creature token with power equal to the exiled card's power and toughness equal to the exiled card's toughness.
this.getSpellAbility().addEffect(new RitualOfTheReturnedExileEffect());
- this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard()));
+ this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE));
}
public RitualOfTheReturned(final RitualOfTheReturned card) {
diff --git a/Mage.Sets/src/mage/cards/r/Rivalry.java b/Mage.Sets/src/mage/cards/r/Rivalry.java
index fc6b92e2d44..7fdfe462de4 100644
--- a/Mage.Sets/src/mage/cards/r/Rivalry.java
+++ b/Mage.Sets/src/mage/cards/r/Rivalry.java
@@ -25,7 +25,7 @@ public final class Rivalry extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}");
- // At the beginning of each player's upkeep, if that player controls more lands than each other player, Rivalry deals 2 damage to him or her.
+ // At the beginning of each player's upkeep, if that player controls more lands than each other player, Rivalry deals 2 damage to them.
this.addAbility(new RivalryTriggeredAbility());
}
@@ -87,6 +87,6 @@ class RivalryTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
- return "At the beginning of each player's upkeep, if that player controls more lands than each other player, Rivalry deals 2 damage to him or her.";
+ return "At the beginning of each player's upkeep, if that player controls more lands than each other player, Rivalry deals 2 damage to them.";
}
}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/r/RiversGrasp.java b/Mage.Sets/src/mage/cards/r/RiversGrasp.java
index e337929ba6b..f050c73502d 100644
--- a/Mage.Sets/src/mage/cards/r/RiversGrasp.java
+++ b/Mage.Sets/src/mage/cards/r/RiversGrasp.java
@@ -38,10 +38,10 @@ public final class RiversGrasp extends CardImpl {
Target targetPlayer = new TargetPlayer();
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new ReturnToHandTargetEffect(),
- new ManaWasSpentCondition(ColoredManaSymbol.U), "If {U} was spent to cast {this}, return up to one target creature to its owner's hand"));
+ new ManaWasSpentCondition(ColoredManaSymbol.U), "If {U} was spent to cast this spell, return up to one target creature to its owner's hand"));
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new RiversGraspEffect(),
- new ManaWasSpentCondition(ColoredManaSymbol.B), " If {B} was spent to cast {this}, target player reveals their hand, you choose a nonland card from it, then that player discards that card"));
+ new ManaWasSpentCondition(ColoredManaSymbol.B), " If {B} was spent to cast this spell, target player reveals their hand, you choose a nonland card from it, then that player discards that card"));
this.getSpellAbility().addTarget(targetCreature);
this.getSpellAbility().addTarget(targetPlayer);
diff --git a/Mage.Sets/src/mage/cards/r/RobberOfTheRich.java b/Mage.Sets/src/mage/cards/r/RobberOfTheRich.java
new file mode 100644
index 00000000000..f86c8b999a5
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RobberOfTheRich.java
@@ -0,0 +1,251 @@
+package mage.cards.r;
+
+import mage.MageInt;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
+import mage.abilities.effects.AsThoughEffectImpl;
+import mage.abilities.effects.AsThoughManaEffect;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.keyword.HasteAbility;
+import mage.abilities.keyword.ReachAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.ExileZone;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.players.ManaPoolItem;
+import mage.players.Player;
+import mage.target.targetpointer.FixedTarget;
+import mage.util.CardUtil;
+import mage.watchers.Watcher;
+
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RobberOfTheRich extends CardImpl {
+
+ public RobberOfTheRich(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.ARCHER);
+ this.subtype.add(SubType.ROGUE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Reach
+ this.addAbility(ReachAbility.getInstance());
+
+ // Haste
+ this.addAbility(HasteAbility.getInstance());
+
+ // Whenever Robber of the Rich attacks, if defending player has more cards in hand than you, exile the top card of their library. During any turn you attacked with a Rogue, you may cast that card and you may spend mana as though it were mana of any color to cast that spell.
+ this.addAbility(new ConditionalInterveningIfTriggeredAbility(
+ new AttacksTriggeredAbility(
+ new RobberOfTheRichEffect(), false, "", SetTargetPointer.PLAYER
+ ), RobberOfTheRichCondition.instance, "Whenever {this} attacks, " +
+ "if defending player has more cards in hand than you, exile the top card of their library. " +
+ "During any turn you attacked with a Rogue, you may cast that card and " +
+ "you may spend mana as though it were mana of any color to cast that spell."
+ ), new RobberOfTheRichWatcher());
+ }
+
+ private RobberOfTheRich(final RobberOfTheRich card) {
+ super(card);
+ }
+
+ @Override
+ public RobberOfTheRich copy() {
+ return new RobberOfTheRich(this);
+ }
+}
+
+enum RobberOfTheRichCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Player player = game.getPlayer(game.getCombat().getDefendingPlayerId(source.getSourceId(), game));
+ return controller != null && player != null && controller.getHand().size() < player.getHand().size();
+ }
+}
+
+class RobberOfTheRichEffect extends OneShotEffect {
+
+ RobberOfTheRichEffect() {
+ super(Outcome.PutCreatureInPlay);
+ }
+
+ private RobberOfTheRichEffect(final RobberOfTheRichEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public RobberOfTheRichEffect copy() {
+ return new RobberOfTheRichEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Player damagedPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
+ if (controller == null || damagedPlayer == null) {
+ return false;
+ }
+ MageObject sourceObject = game.getObject(source.getSourceId());
+ UUID exileId = CardUtil.getCardExileZoneId(game, source);
+ Card card = damagedPlayer.getLibrary().getFromTop(game);
+ if (card == null || sourceObject == null) {
+ return true;
+ }
+ // move card to exile
+ controller.moveCardToExileWithInfo(card, exileId, sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true);
+ // Add effects only if the card has a spellAbility (e.g. not for lands).
+ if (card.getSpellAbility() == null) {
+ return true;
+ }
+ // allow to cast the card
+ game.addEffect(new RobberOfTheRichCastFromExileEffect(card.getId(), exileId), source);
+ // and you may spend mana as though it were mana of any color to cast it
+ ContinuousEffect effect = new RobberOfTheRichSpendAnyManaEffect();
+ effect.setTargetPointer(new FixedTarget(card.getId()));
+ game.addEffect(effect, source);
+ return true;
+ }
+}
+
+class RobberOfTheRichCastFromExileEffect extends AsThoughEffectImpl {
+
+ private UUID cardId;
+ private UUID exileId;
+
+ RobberOfTheRichCastFromExileEffect(UUID cardId, UUID exileId) {
+ super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit);
+ this.cardId = cardId;
+ this.exileId = exileId;
+ }
+
+ private RobberOfTheRichCastFromExileEffect(final RobberOfTheRichCastFromExileEffect effect) {
+ super(effect);
+ this.cardId = effect.cardId;
+ this.exileId = effect.exileId;
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public RobberOfTheRichCastFromExileEffect copy() {
+ return new RobberOfTheRichCastFromExileEffect(this);
+ }
+
+ @Override
+ public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
+ RobberOfTheRichWatcher watcher = game.getState().getWatcher(RobberOfTheRichWatcher.class);
+ if (watcher == null || !watcher.getAttackedWithRogue(source.getControllerId())) {
+ return false;
+ }
+ if (!sourceId.equals(cardId) || !source.isControlledBy(affectedControllerId)) {
+ return false;
+ }
+ ExileZone exileZone = game.getState().getExile().getExileZone(exileId);
+ if (exileZone != null && exileZone.contains(cardId)) {
+ return true;
+ }
+ discard();
+ return false;
+ }
+}
+
+class RobberOfTheRichSpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect {
+
+ RobberOfTheRichSpendAnyManaEffect() {
+ super(AsThoughEffectType.SPEND_OTHER_MANA, Duration.Custom, Outcome.Benefit);
+ }
+
+ private RobberOfTheRichSpendAnyManaEffect(final RobberOfTheRichSpendAnyManaEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public RobberOfTheRichSpendAnyManaEffect copy() {
+ return new RobberOfTheRichSpendAnyManaEffect(this);
+ }
+
+ @Override
+ public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
+ FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
+ return source.isControlledBy(affectedControllerId)
+ && Objects.equals(objectId, fixedTarget.getTarget())
+ && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
+ && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
+ }
+
+ @Override
+ public ManaType getAsThoughManaType(ManaType manaType, ManaPoolItem mana, UUID affectedControllerId, Ability source, Game game) {
+ return mana.getFirstAvailable();
+ }
+}
+
+class RobberOfTheRichWatcher extends Watcher {
+
+ private Set rogueAttackers = new HashSet();
+
+ RobberOfTheRichWatcher() {
+ super(WatcherScope.GAME);
+ }
+
+ private RobberOfTheRichWatcher(final RobberOfTheRichWatcher watcher) {
+ super(watcher);
+ this.rogueAttackers.addAll(watcher.rogueAttackers);
+ }
+
+ @Override
+ public RobberOfTheRichWatcher copy() {
+ return new RobberOfTheRichWatcher(this);
+ }
+
+ @Override
+ public void watch(GameEvent event, Game game) {
+ if (event.getType() != GameEvent.EventType.ATTACKER_DECLARED) {
+ return;
+ }
+ Permanent permanent = game.getPermanent(event.getSourceId());
+ if (permanent == null || !permanent.hasSubtype(SubType.ROGUE, game)) {
+ return;
+ }
+ rogueAttackers.add(event.getPlayerId());
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ rogueAttackers.clear();
+ }
+
+ boolean getAttackedWithRogue(UUID playerId) {
+ return rogueAttackers.contains(playerId);
+ }
+}
+
diff --git a/Mage.Sets/src/mage/cards/r/RollingSpoil.java b/Mage.Sets/src/mage/cards/r/RollingSpoil.java
index ec99f764575..ef6341122ef 100644
--- a/Mage.Sets/src/mage/cards/r/RollingSpoil.java
+++ b/Mage.Sets/src/mage/cards/r/RollingSpoil.java
@@ -30,7 +30,7 @@ public final class RollingSpoil extends CardImpl {
// If {B} was spent to cast Rolling Spoil, all creatures get -1/-1 until end of turn.
this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
new BoostAllEffect(-1, -1, Duration.EndOfTurn),
- new ManaWasSpentCondition(ColoredManaSymbol.B), "If {B} was spent to cast {this}, all creatures get -1/-1 until end of turn"));
+ new ManaWasSpentCondition(ColoredManaSymbol.B), "If {B} was spent to cast this spell, all creatures get -1/-1 until end of turn"));
}
public RollingSpoil(final RollingSpoil card) {
diff --git a/Mage.Sets/src/mage/cards/r/RoninWarclub.java b/Mage.Sets/src/mage/cards/r/RoninWarclub.java
index d3f6624f420..0d4faf7a7b9 100644
--- a/Mage.Sets/src/mage/cards/r/RoninWarclub.java
+++ b/Mage.Sets/src/mage/cards/r/RoninWarclub.java
@@ -1,7 +1,5 @@
-
package mage.cards.r;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleStaticAbility;
@@ -12,8 +10,8 @@ import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
@@ -22,23 +20,24 @@ import mage.game.permanent.Permanent;
import mage.target.Target;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class RoninWarclub extends CardImpl {
public RoninWarclub(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +2/+1.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 1)));
-
+
// Whenever a creature enters the battlefield under your control, attach Ronin Warclub to that creature.
Ability ability = new RoninWarclubTriggeredAbility();
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
-
+
// Equip {5} ({5}: Attach to target creature you control. Equip only as a sorcery.)
this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(5)));
}
@@ -51,11 +50,11 @@ public final class RoninWarclub extends CardImpl {
public RoninWarclub copy() {
return new RoninWarclub(this);
}
-
+
private class RoninWarclubTriggeredAbility extends TriggeredAbilityImpl {
public RoninWarclubTriggeredAbility() {
- super(Zone.BATTLEFIELD, new RoninWarclubAttachEffect(), false);
+ super(Zone.BATTLEFIELD, new RoninWarclubAttachEffect(), false);
}
public RoninWarclubTriggeredAbility(RoninWarclubTriggeredAbility ability) {
@@ -70,8 +69,9 @@ public final class RoninWarclub extends CardImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
- if (permanent.isCreature()
- && (permanent.isControlledBy(this.controllerId))) {
+ if (permanent != null
+ && permanent.isCreature()
+ && permanent.isControlledBy(this.controllerId)) {
if (!this.getTargets().isEmpty()) {
// remove previous target
@@ -94,7 +94,7 @@ public final class RoninWarclub extends CardImpl {
return new RoninWarclubTriggeredAbility(this);
}
}
-
+
private static class RoninWarclubAttachEffect extends OneShotEffect {
public RoninWarclubAttachEffect() {
diff --git a/Mage.Sets/src/mage/cards/r/RosethornAcolyte.java b/Mage.Sets/src/mage/cards/r/RosethornAcolyte.java
new file mode 100644
index 00000000000..354131f372f
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RosethornAcolyte.java
@@ -0,0 +1,42 @@
+package mage.cards.r;
+
+import mage.MageInt;
+import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
+import mage.abilities.mana.AnyColorManaAbility;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RosethornAcolyte extends AdventureCard {
+
+ public RosethornAcolyte(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{2}{G}", "Seasonal Ritual", "{G}");
+
+ this.subtype.add(SubType.ELF);
+ this.subtype.add(SubType.DRUID);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // {T}: Add one mana of any color.
+ this.addAbility(new AnyColorManaAbility());
+
+ // Seasonal Ritual
+ // Add one mana of any color.
+ this.getSpellCard().getSpellAbility().addEffect(new AddManaOfAnyColorEffect());
+ }
+
+ private RosethornAcolyte(final RosethornAcolyte card) {
+ super(card);
+ }
+
+ @Override
+ public RosethornAcolyte copy() {
+ return new RosethornAcolyte(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RosethornHalberd.java b/Mage.Sets/src/mage/cards/r/RosethornHalberd.java
new file mode 100644
index 00000000000..ca2c55f834a
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RosethornHalberd.java
@@ -0,0 +1,61 @@
+package mage.cards.r;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.continuous.BoostEquippedEffect;
+import mage.abilities.keyword.EquipAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RosethornHalberd extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterControlledCreaturePermanent("non-Human creature you control");
+
+ static {
+ filter.add(Predicates.not(new SubtypePredicate(SubType.HUMAN)));
+ }
+
+ public RosethornHalberd(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{G}");
+
+ this.subtype.add(SubType.EQUIPMENT);
+
+ // When Rosethorn Halberd enters the battlefield, attach it to target non-Human creature you control.
+ Ability ability = new EntersBattlefieldTriggeredAbility(
+ new AttachEffect(Outcome.Benefit, "attach it to target non-Human creature you control")
+ );
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(ability);
+
+ // Equipped creature gets +2/+1.
+ this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(2, 1)));
+
+ // Equip {5}
+ this.addAbility(new EquipAbility(5));
+ }
+
+ private RosethornHalberd(final RosethornHalberd card) {
+ super(card);
+ }
+
+ @Override
+ public RosethornHalberd copy() {
+ return new RosethornHalberd(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RovingKeep.java b/Mage.Sets/src/mage/cards/r/RovingKeep.java
new file mode 100644
index 00000000000..05f9af99ad5
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RovingKeep.java
@@ -0,0 +1,57 @@
+package mage.cards.r;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.combat.CanAttackAsThoughItDidntHaveDefenderSourceEffect;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.DefenderAbility;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RovingKeep extends CardImpl {
+
+ public RovingKeep(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{7}");
+
+ this.subtype.add(SubType.WALL);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(7);
+
+ // Defender
+ this.addAbility(DefenderAbility.getInstance());
+
+ // {7}: Roving Keep gets +2/+0 and gains trample until end of turn. It can attack this turn as though it didn't have defender.
+ Ability ability = new SimpleActivatedAbility(
+ new BoostSourceEffect(2, 0, Duration.EndOfTurn)
+ .setText("{this} gets +2/+0"), new GenericManaCost(7)
+ );
+ ability.addEffect(new GainAbilitySourceEffect(
+ TrampleAbility.getInstance(), Duration.EndOfTurn
+ ).setText("and gains trample until end of turn."));
+ ability.addEffect(new CanAttackAsThoughItDidntHaveDefenderSourceEffect(Duration.EndOfTurn)
+ .setText("It can attack this turn as though it didn't have defender"));
+ this.addAbility(ability);
+ }
+
+ private RovingKeep(final RovingKeep card) {
+ super(card);
+ }
+
+ @Override
+ public RovingKeep copy() {
+ return new RovingKeep(this);
+ }
+}
+// sexy hexy is back, baby!
diff --git a/Mage.Sets/src/mage/cards/r/RowanFearlessSparkmage.java b/Mage.Sets/src/mage/cards/r/RowanFearlessSparkmage.java
new file mode 100644
index 00000000000..ade68c0c67f
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RowanFearlessSparkmage.java
@@ -0,0 +1,76 @@
+package mage.cards.r;
+
+import mage.abilities.Ability;
+import mage.abilities.LoyaltyAbility;
+import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.effects.common.UntapAllEffect;
+import mage.abilities.effects.common.combat.CantBlockTargetEffect;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.effects.common.continuous.GainControlAllEffect;
+import mage.abilities.keyword.FirstStrikeAbility;
+import mage.abilities.keyword.HasteAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RowanFearlessSparkmage extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterCreaturePermanent("all creatures");
+
+ public RowanFearlessSparkmage(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{3}{R}{R}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.ROWAN);
+ this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+
+ // +1: Up to one target creature gets +3/+0 and gains first strike until end of turn.
+ Ability ability = new LoyaltyAbility(new BoostTargetEffect(
+ 3, 0, Duration.EndOfTurn
+ ).setText("Up to one target creature gets +3/+0"), 1);
+ ability.addEffect(new GainAbilityTargetEffect(
+ FirstStrikeAbility.getInstance(), Duration.EndOfTurn
+ ).setText("and gains first strike until end of turn"));
+ ability.addTarget(new TargetCreaturePermanent(0, 1));
+ this.addAbility(ability);
+
+ // −2: Rowan, Fearless Sparkmage deals 1 damage to each of up to two target creatures. Those creatures can't block this turn.
+ ability = new LoyaltyAbility(new DamageTargetEffect(1)
+ .setText("deals 1 damage to each of up to two target creatures."), -2);
+ ability.addEffect(new CantBlockTargetEffect(Duration.EndOfTurn)
+ .setText("Those creatures can't block this turn."));
+ ability.addTarget(new TargetCreaturePermanent(0, 2));
+ this.addAbility(ability);
+
+ // −9: Gain control of all creatures until end of turn. Untap them. They gain haste until end of turn.
+ ability = new LoyaltyAbility(new GainControlAllEffect(Duration.EndOfTurn, filter), -9);
+ ability.addEffect(new UntapAllEffect(filter).setText("until end of turn. Untap them."));
+ ability.addEffect(new GainAbilityAllEffect(
+ HasteAbility.getInstance(), Duration.EndOfTurn, filter
+ ).setText("They gain haste until end of turn"));
+ this.addAbility(ability);
+ }
+
+ private RowanFearlessSparkmage(final RowanFearlessSparkmage card) {
+ super(card);
+ }
+
+ @Override
+ public RowanFearlessSparkmage copy() {
+ return new RowanFearlessSparkmage(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RowansBattleguard.java b/Mage.Sets/src/mage/cards/r/RowansBattleguard.java
new file mode 100644
index 00000000000..5b2c730cf89
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RowansBattleguard.java
@@ -0,0 +1,56 @@
+package mage.cards.r;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.decorator.ConditionalContinuousEffect;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.abilities.keyword.FirstStrikeAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPlaneswalkerPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RowansBattleguard extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterControlledPlaneswalkerPermanent(SubType.ROWAN);
+ private static final Condition condition
+ = new PermanentsOnTheBattlefieldCondition(filter);
+
+ public RowansBattleguard(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // First strike
+ this.addAbility(FirstStrikeAbility.getInstance());
+
+ // As long as you control a Rowan planeswalker, Rowan's Battleguard gets +3/+0.
+ this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
+ new BoostSourceEffect(3, 0, Duration.WhileOnBattlefield), condition,
+ "As long as you control a Rowan planeswalker, {this} gets +3/+0"
+ )));
+ }
+
+ private RowansBattleguard(final RowansBattleguard card) {
+ super(card);
+ }
+
+ @Override
+ public RowansBattleguard copy() {
+ return new RowansBattleguard(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RowansStalwarts.java b/Mage.Sets/src/mage/cards/r/RowansStalwarts.java
new file mode 100644
index 00000000000..1dbb4762f23
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RowansStalwarts.java
@@ -0,0 +1,48 @@
+package mage.cards.r;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.search.SearchLibraryGraveyardPutInHandEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterCard;
+import mage.filter.predicate.mageobject.NamePredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RowansStalwarts extends CardImpl {
+
+ private static final FilterCard filter = new FilterCard("Rowan, Fearless Sparkmage");
+
+ static {
+ filter.add(new NamePredicate("Rowan, Fearless Sparkmage"));
+ }
+
+ public RowansStalwarts(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(2);
+
+ // When Rowan's Stalwarts enters the battlefield, you may search your library and/or graveyard for a card named Rowan, Fearless Sparkmage, reveal it, and put it into your hand. If you search your library this way, shuffle it.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(
+ new SearchLibraryGraveyardPutInHandEffect(filter, false, true)
+ ));
+ }
+
+ private RowansStalwarts(final RowansStalwarts card) {
+ super(card);
+ }
+
+ @Override
+ public RowansStalwarts copy() {
+ return new RowansStalwarts(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RunAwayTogether.java b/Mage.Sets/src/mage/cards/r/RunAwayTogether.java
new file mode 100644
index 00000000000..03a7ecd3b39
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RunAwayTogether.java
@@ -0,0 +1,78 @@
+package mage.cards.r;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class RunAwayTogether extends CardImpl {
+
+ public RunAwayTogether(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
+
+ // Choose two target creatures controlled by different players. Return those creatures to their owners' hands.
+ this.getSpellAbility().addEffect(new ReturnToHandTargetEffect(true)
+ .setText("Choose two target creatures controlled by different players. " +
+ "Return those creatures to their owners' hands.")
+ );
+ this.getSpellAbility().addTarget(new RunAwayTogetherTarget());
+ }
+
+ private RunAwayTogether(final RunAwayTogether card) {
+ super(card);
+ }
+
+ @Override
+ public RunAwayTogether copy() {
+ return new RunAwayTogether(this);
+ }
+}
+
+class RunAwayTogetherTarget extends TargetCreaturePermanent {
+
+ private static final FilterCreaturePermanent filter
+ = new FilterCreaturePermanent("creatures controlled by different players");
+
+ RunAwayTogetherTarget() {
+ super(2, 2, filter, false);
+ }
+
+ private RunAwayTogetherTarget(final RunAwayTogetherTarget target) {
+ super(target);
+ }
+
+ @Override
+ public RunAwayTogetherTarget copy() {
+ return new RunAwayTogetherTarget(this);
+ }
+
+ @Override
+ public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) {
+ if (!super.canTarget(controllerId, id, source, game)) {
+ return false;
+ }
+ Permanent creature = game.getPermanent(id);
+ if (creature == null) {
+ return false;
+ }
+ return this.getTargets()
+ .stream()
+ .map(game::getPermanent)
+ .filter(Objects::nonNull)
+ .noneMatch(permanent -> !creature.getId().equals(permanent.getId())
+ && creature.isControlledBy(permanent.getControllerId())
+ );
+ }
+}
+// give carly rae jepsen a sword
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/r/RuneTailKitsuneAscendant.java b/Mage.Sets/src/mage/cards/r/RuneTailKitsuneAscendant.java
index 3f40636c58e..d316ea1c25e 100644
--- a/Mage.Sets/src/mage/cards/r/RuneTailKitsuneAscendant.java
+++ b/Mage.Sets/src/mage/cards/r/RuneTailKitsuneAscendant.java
@@ -1,7 +1,5 @@
-
package mage.cards.r;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.StateTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@@ -9,26 +7,22 @@ import mage.abilities.effects.common.FlipSourceEffect;
import mage.abilities.effects.common.PreventAllDamageToAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Duration;
-import mage.constants.SuperType;
-import mage.constants.Zone;
-import mage.filter.common.FilterControlledCreatureInPlay;
+import mage.constants.*;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.token.TokenImpl;
-import mage.game.permanent.token.Token;
import mage.players.Player;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class RuneTailKitsuneAscendant extends CardImpl {
public RuneTailKitsuneAscendant(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.FOX);
this.subtype.add(SubType.MONK);
@@ -94,8 +88,9 @@ class RuneTailEssence extends TokenImpl {
// Prevent all damage that would be dealt to creatures you control.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
- new PreventAllDamageToAllEffect(Duration.WhileOnBattlefield, new FilterControlledCreatureInPlay("creatures you control"))));
+ new PreventAllDamageToAllEffect(Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_CREATURES)));
}
+
public RuneTailEssence(final RuneTailEssence token) {
super(token);
}
diff --git a/Mage.Sets/src/mage/cards/s/SabertoothCobra.java b/Mage.Sets/src/mage/cards/s/SabertoothCobra.java
index 2cd8feba17d..1e1162a7f8a 100644
--- a/Mage.Sets/src/mage/cards/s/SabertoothCobra.java
+++ b/Mage.Sets/src/mage/cards/s/SabertoothCobra.java
@@ -27,14 +27,14 @@ public final class SabertoothCobra extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- // Whenever Sabertooth Cobra deals damage to a player, he or she gets a poison counter. That player gets another poison counter at the beginning of their next upkeep unless he or she pays {2} before that turn.
+ // Whenever Sabertooth Cobra deals damage to a player, they get a poison counter. That player gets another poison counter at the beginning of their next upkeep unless they pay {2} before that turn.
Effect effect = new AddPoisonCounterTargetEffect(1);
effect.setText("that player gets a poison counter");
Ability ability = new DealsDamageToAPlayerTriggeredAbility(effect, false, true);
effect = new AddPoisonCounterTargetEffect(1);
effect.setText("That player gets another poison counter.");
ability.addEffect(new UnlessPaysDelayedEffect(new ManaCostsImpl("{2}"), effect, PhaseStep.UPKEEP, true,
- "That player gets another poison counter at the beginning of their next upkeep unless he or she pays {2} before that turn."));
+ "That player gets another poison counter at the beginning of their next upkeep unless they pay {2} before that turn."));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/s/SafePassage.java b/Mage.Sets/src/mage/cards/s/SafePassage.java
index 9b5a2b732ea..500efab8dd7 100644
--- a/Mage.Sets/src/mage/cards/s/SafePassage.java
+++ b/Mage.Sets/src/mage/cards/s/SafePassage.java
@@ -1,33 +1,26 @@
-
-
package mage.cards.s;
-import java.util.UUID;
import mage.abilities.effects.common.PreventAllDamageToAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
-import mage.constants.TargetController;
-import mage.filter.common.FilterCreatureOrPlayer;
-import mage.filter.predicate.other.PlayerPredicate;
-import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterPermanentOrPlayer;
+
+import java.util.UUID;
/**
- *
* @author BetaSteward_at_googlemail.com
*/
-public final class SafePassage extends CardImpl {
+public final class SafePassage extends CardImpl {
- private static final FilterCreatureOrPlayer filter = new FilterCreatureOrPlayer("you and creatures you control");
-
- static {
- filter.getCreatureFilter().add(new ControllerPredicate(TargetController.YOU));
- filter.getPlayerFilter().add(new PlayerPredicate(TargetController.YOU));
- }
+ private static final FilterPermanentOrPlayer filter = new FilterPermanentOrPlayer("you and creatures you control",
+ StaticFilters.FILTER_PERMANENT_CREATURES_CONTROLLED,
+ StaticFilters.FILTER_PLAYER_CONTROLLER);
public SafePassage(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}");
this.getSpellAbility().addEffect(new PreventAllDamageToAllEffect(Duration.EndOfTurn, filter));
}
diff --git a/Mage.Sets/src/mage/cards/s/SageOfTheFalls.java b/Mage.Sets/src/mage/cards/s/SageOfTheFalls.java
new file mode 100644
index 00000000000..d8acc2ca0a4
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SageOfTheFalls.java
@@ -0,0 +1,51 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
+import mage.abilities.effects.common.DrawDiscardControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SageOfTheFalls extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterCreaturePermanent("{this} or another non-Human creature");
+
+ static {
+ filter.add(Predicates.not(new SubtypePredicate(SubType.HUMAN)));
+ }
+
+ public SageOfTheFalls(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}");
+
+ this.subtype.add(SubType.MERFOLK);
+ this.subtype.add(SubType.WIZARD);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(5);
+
+ // Whenever Sage of the Falls or another non-Human creature enters the battlefield under you control, you may draw a card. If you do, discard a card.
+ this.addAbility(new EntersBattlefieldControlledTriggeredAbility(
+ new DrawDiscardControllerEffect(1, 1, true), filter
+ ));
+ }
+
+ private SageOfTheFalls(final SageOfTheFalls card) {
+ super(card);
+ }
+
+ @Override
+ public SageOfTheFalls copy() {
+ return new SageOfTheFalls(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SaheeliRai.java b/Mage.Sets/src/mage/cards/s/SaheeliRai.java
index 29dba317881..cc3a069b3bb 100644
--- a/Mage.Sets/src/mage/cards/s/SaheeliRai.java
+++ b/Mage.Sets/src/mage/cards/s/SaheeliRai.java
@@ -1,7 +1,5 @@
-
package mage.cards.s;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.LoyaltyAbility;
@@ -9,20 +7,16 @@ import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.abilities.effects.common.DamagePlayersEffect;
import mage.abilities.effects.common.ExileTargetEffect;
-import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Outcome;
-import mage.constants.SuperType;
-import mage.constants.TargetController;
+import mage.constants.*;
import mage.filter.StaticFilters;
import mage.filter.common.FilterArtifactCard;
import mage.game.Game;
@@ -31,14 +25,15 @@ import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetControlledPermanent;
import mage.target.targetpointer.FixedTarget;
+import java.util.UUID;
+
/**
- *
* @author emerald000
*/
public final class SaheeliRai extends CardImpl {
public SaheeliRai(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{1}{U}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{1}{U}{R}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.SAHEELI);
@@ -121,7 +116,7 @@ class SaheeliRaiTarget extends TargetCardInLibrary {
}
@Override
- public boolean canTarget(UUID id, Cards cards, Game game) {
+ public boolean canTarget(UUID playerId, UUID id, Ability source, Cards cards, Game game) {
Card card = cards.get(id, game);
if (card != null) {
for (UUID targetId : this.getTargets()) {
@@ -130,7 +125,7 @@ class SaheeliRaiTarget extends TargetCardInLibrary {
return false;
}
}
- return filter.match(card, game);
+ return filter.match(card, playerId, game);
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/s/SandsOfTime.java b/Mage.Sets/src/mage/cards/s/SandsOfTime.java
index 07f81339f00..0875eaa5057 100644
--- a/Mage.Sets/src/mage/cards/s/SandsOfTime.java
+++ b/Mage.Sets/src/mage/cards/s/SandsOfTime.java
@@ -34,7 +34,7 @@ public final class SandsOfTime extends CardImpl {
// Each player skips their untap step.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SkipUntapStepEffect()));
- // At the beginning of each player's upkeep, that player simultaneously untaps each tapped artifact, creature, and land he or she controls and taps each untapped artifact, creature, and land he or she controls.
+ // At the beginning of each player's upkeep, that player simultaneously untaps each tapped artifact, creature, and land they control and taps each untapped artifact, creature, and land they control.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SandsOfTimeEffect(), TargetController.ANY, false));
}
@@ -61,7 +61,7 @@ class SandsOfTimeEffect extends OneShotEffect {
public SandsOfTimeEffect() {
super(Outcome.Neutral);
- staticText = "that player simultaneously untaps each tapped artifact, creature, and land he or she controls and taps each untapped artifact, creature, and land he or she controls";
+ staticText = "that player simultaneously untaps each tapped artifact, creature, and land they control and taps each untapped artifact, creature, and land they control";
}
public SandsOfTimeEffect(SandsOfTimeEffect copy) {
diff --git a/Mage.Sets/src/mage/cards/s/Sanguimancy.java b/Mage.Sets/src/mage/cards/s/Sanguimancy.java
index 5fd5fc725b9..4dd87e3bf8f 100644
--- a/Mage.Sets/src/mage/cards/s/Sanguimancy.java
+++ b/Mage.Sets/src/mage/cards/s/Sanguimancy.java
@@ -1,8 +1,5 @@
-
package mage.cards.s;
-import java.util.UUID;
-import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.DevotionCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
@@ -10,26 +7,25 @@ import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.ColoredManaSymbol;
+
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class Sanguimancy extends CardImpl {
public Sanguimancy(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{B}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}");
// You draw X cards and you lose X life, where X is your devotion to black.
- DynamicValue blackDevotion = new DevotionCount(ColoredManaSymbol.B);
- Effect effect = new DrawCardSourceControllerEffect(blackDevotion);
+ Effect effect = new DrawCardSourceControllerEffect(DevotionCount.B);
effect.setText("You draw X cards");
this.getSpellAbility().addEffect(effect);
- effect = new LoseLifeSourceControllerEffect(blackDevotion);
- effect.setText("and you lose X life, where X is your devotion to black");
+ effect = new LoseLifeSourceControllerEffect(DevotionCount.B);
+ effect.setText("and you lose X life, where X is your devotion to black");
this.getSpellAbility().addEffect(effect);
+ this.getSpellAbility().addHint(DevotionCount.B.getHint());
}
public Sanguimancy(final Sanguimancy card) {
diff --git a/Mage.Sets/src/mage/cards/s/SarpadianEmpiresVolVii.java b/Mage.Sets/src/mage/cards/s/SarpadianEmpiresVolVII.java
similarity index 76%
rename from Mage.Sets/src/mage/cards/s/SarpadianEmpiresVolVii.java
rename to Mage.Sets/src/mage/cards/s/SarpadianEmpiresVolVII.java
index a31d1760e2e..7867f2a8437 100644
--- a/Mage.Sets/src/mage/cards/s/SarpadianEmpiresVolVii.java
+++ b/Mage.Sets/src/mage/cards/s/SarpadianEmpiresVolVII.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -21,7 +20,6 @@ import mage.game.permanent.token.CitizenToken;
import mage.game.permanent.token.GoblinToken;
import mage.game.permanent.token.SaprolingToken;
import mage.game.permanent.token.ThrullToken;
-import mage.game.permanent.token.TokenImpl;
import mage.game.permanent.token.Token;
import mage.players.Player;
@@ -29,43 +27,43 @@ import mage.players.Player;
*
* @author LoneFox
*/
-public final class SarpadianEmpiresVolVii extends CardImpl {
+public final class SarpadianEmpiresVolVII extends CardImpl {
- public SarpadianEmpiresVolVii(UUID ownerId, CardSetInfo setInfo) {
+ public SarpadianEmpiresVolVII(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// As Sarpadian Empires, Vol. VII enters the battlefield, choose white Citizen, blue Camarid, black Thrull, red Goblin, or green Saproling.
- this.addAbility(new AsEntersBattlefieldAbility(new ChooseTokenEffect()));
+ this.addAbility(new AsEntersBattlefieldAbility(new SarpadianEmpiresChooseTokenEffect()));
// {3}, {T}: Create a 1/1 creature token of the chosen color and type.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateSelectedTokenEffect(), new ManaCostsImpl("{3}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SarpadianEmpiresCreateSelectedTokenEffect(), new ManaCostsImpl("{3}"));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
- public SarpadianEmpiresVolVii(final SarpadianEmpiresVolVii card) {
+ public SarpadianEmpiresVolVII(final SarpadianEmpiresVolVII card) {
super(card);
}
@Override
- public SarpadianEmpiresVolVii copy() {
- return new SarpadianEmpiresVolVii(this);
+ public SarpadianEmpiresVolVII copy() {
+ return new SarpadianEmpiresVolVII(this);
}
}
-class ChooseTokenEffect extends OneShotEffect {
+class SarpadianEmpiresChooseTokenEffect extends OneShotEffect {
- public ChooseTokenEffect() {
+ public SarpadianEmpiresChooseTokenEffect() {
super(Outcome.Neutral);
this.staticText = "choose white Citizen, blue Camarid, black Thrull, red Goblin, or green Saproling";
}
- public ChooseTokenEffect(final ChooseTokenEffect effect) {
+ public SarpadianEmpiresChooseTokenEffect(final SarpadianEmpiresChooseTokenEffect effect) {
super(effect);
}
@Override
- public ChooseTokenEffect copy() {
- return new ChooseTokenEffect(this);
+ public SarpadianEmpiresChooseTokenEffect copy() {
+ return new SarpadianEmpiresChooseTokenEffect(this);
}
@Override
@@ -90,20 +88,20 @@ class ChooseTokenEffect extends OneShotEffect {
}
}
-class CreateSelectedTokenEffect extends OneShotEffect {
+class SarpadianEmpiresCreateSelectedTokenEffect extends OneShotEffect {
- public CreateSelectedTokenEffect() {
+ public SarpadianEmpiresCreateSelectedTokenEffect() {
super(Outcome.PutCreatureInPlay);
this.staticText = "create a 1/1 creature token of the chosen color and type";
}
- public CreateSelectedTokenEffect(final CreateSelectedTokenEffect effect) {
+ public SarpadianEmpiresCreateSelectedTokenEffect(final SarpadianEmpiresCreateSelectedTokenEffect effect) {
super(effect);
}
@Override
- public CreateSelectedTokenEffect copy() {
- return new CreateSelectedTokenEffect(this);
+ public SarpadianEmpiresCreateSelectedTokenEffect copy() {
+ return new SarpadianEmpiresCreateSelectedTokenEffect(this);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/s/SavvyHunter.java b/Mage.Sets/src/mage/cards/s/SavvyHunter.java
new file mode 100644
index 00000000000..3e184b35b9b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SavvyHunter.java
@@ -0,0 +1,52 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.common.AttacksOrBlocksTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.common.FilterControlledPermanent;
+import mage.game.permanent.token.FoodToken;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SavvyHunter extends CardImpl {
+
+ private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.FOOD, "Foods");
+
+ public SavvyHunter(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{G}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Whenever Savvy Hunter attacks or blocks, create a Food token.
+ this.addAbility(new AttacksOrBlocksTriggeredAbility(new CreateTokenEffect(new FoodToken()), false));
+
+ // Sacrifice two Foods: Draw a card.
+ this.addAbility(new SimpleActivatedAbility(
+ new DrawCardSourceControllerEffect(1),
+ new SacrificeTargetCost(new TargetControlledPermanent(2, filter))
+ ));
+ }
+
+ private SavvyHunter(final SavvyHunter card) {
+ super(card);
+ }
+
+ @Override
+ public SavvyHunter copy() {
+ return new SavvyHunter(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/ScaldingCauldron.java b/Mage.Sets/src/mage/cards/s/ScaldingCauldron.java
new file mode 100644
index 00000000000..39d1685f3cb
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/ScaldingCauldron.java
@@ -0,0 +1,42 @@
+package mage.cards.s;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeSourceCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ScaldingCauldron extends CardImpl {
+
+ public ScaldingCauldron(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
+
+ // {3}, {T}, Sacrifice Scalding Cauldron: It deals 3 damage to target creature.
+ Ability ability = new SimpleActivatedAbility(
+ new DamageTargetEffect(3, "it"), new GenericManaCost(3)
+ );
+ ability.addCost(new TapSourceCost());
+ ability.addCost(new SacrificeSourceCost());
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+ }
+
+ private ScaldingCauldron(final ScaldingCauldron card) {
+ super(card);
+ }
+
+ @Override
+ public ScaldingCauldron copy() {
+ return new ScaldingCauldron(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/Scandalmonger.java b/Mage.Sets/src/mage/cards/s/Scandalmonger.java
index 1e3bff80aeb..c42cbc315f7 100644
--- a/Mage.Sets/src/mage/cards/s/Scandalmonger.java
+++ b/Mage.Sets/src/mage/cards/s/Scandalmonger.java
@@ -29,7 +29,7 @@ public final class Scandalmonger extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(3);
- // {2}: Target player discards a card. Any player may activate this ability but only any time he or she could cast a sorcery.
+ // {2}: Target player discards a card. Any player may activate this ability but only any time they could cast a sorcery.
ActivateAsSorceryActivatedAbility ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new DiscardTargetEffect(1), new ManaCostsImpl("{2}"));
ability.addTarget(new TargetPlayer());
ability.setMayActivate(TargetController.ANY);
diff --git a/Mage.Sets/src/mage/cards/s/ScorchingDragonfire.java b/Mage.Sets/src/mage/cards/s/ScorchingDragonfire.java
new file mode 100644
index 00000000000..c0ca25806ec
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/ScorchingDragonfire.java
@@ -0,0 +1,35 @@
+package mage.cards.s;
+
+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.target.common.TargetCreatureOrPlaneswalker;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ScorchingDragonfire extends CardImpl {
+
+ public ScorchingDragonfire(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}");
+
+ // Scorching Dragonfire deals 3 damage to target creature or planeswalker. If that creature or planeswalker would die this turn, exile it instead.
+ this.getSpellAbility().addEffect(new DamageTargetEffect(3));
+ this.getSpellAbility().addEffect(new ExileTargetIfDiesEffect()
+ .setText("If that creature or planeswalker would die this turn, exile it instead."));
+ this.getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker());
+ }
+
+ private ScorchingDragonfire(final ScorchingDragonfire card) {
+ super(card);
+ }
+
+ @Override
+ public ScorchingDragonfire copy() {
+ return new ScorchingDragonfire(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/Scrambleverse.java b/Mage.Sets/src/mage/cards/s/Scrambleverse.java
index e856b530888..e90639cf5cd 100644
--- a/Mage.Sets/src/mage/cards/s/Scrambleverse.java
+++ b/Mage.Sets/src/mage/cards/s/Scrambleverse.java
@@ -27,7 +27,7 @@ public final class Scrambleverse extends CardImpl {
public Scrambleverse(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{6}{R}{R}");
- // For each nonland permanent, choose a player at random. Then each player gains control of each permanent for which he or she was chosen. Untap those permanents.
+ // For each nonland permanent, choose a player at random. Then each player gains control of each permanent for which they were chosen. Untap those permanents.
this.getSpellAbility().addEffect(new ScrambleverseEffect());
}
@@ -45,7 +45,7 @@ class ScrambleverseEffect extends OneShotEffect {
public ScrambleverseEffect() {
super(Outcome.Damage);
- staticText = "For each nonland permanent, choose a player at random. Then each player gains control of each permanent for which he or she was chosen. Untap those permanents";
+ staticText = "For each nonland permanent, choose a player at random. Then each player gains control of each permanent for which they were chosen. Untap those permanents";
}
public ScrambleverseEffect(ScrambleverseEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/ScrapMastery.java b/Mage.Sets/src/mage/cards/s/ScrapMastery.java
index 4b8ef079d3a..da66896e4a1 100644
--- a/Mage.Sets/src/mage/cards/s/ScrapMastery.java
+++ b/Mage.Sets/src/mage/cards/s/ScrapMastery.java
@@ -28,7 +28,7 @@ public final class ScrapMastery extends CardImpl {
public ScrapMastery(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}{R}");
- // Each player exiles all artifact cards from their graveyard, then sacrifices all artifacts he or she controls, then puts all cards he or she exiled this way onto the battlefield.
+ // Each player exiles all artifact cards from their graveyard, then sacrifices all artifacts they control, then puts all cards they exiled this way onto the battlefield.
this.getSpellAbility().addEffect(new ScrapMasteryEffect());
}
@@ -46,7 +46,7 @@ class ScrapMasteryEffect extends OneShotEffect {
public ScrapMasteryEffect() {
super(Outcome.PutCardInPlay);
- this.staticText = "Each player exiles all artifact cards from their graveyard, then sacrifices all artifacts he or she controls, then puts all cards he or she exiled this way onto the battlefield";
+ this.staticText = "Each player exiles all artifact cards from their graveyard, then sacrifices all artifacts they control, then puts all cards they exiled this way onto the battlefield";
}
public ScrapMasteryEffect(final ScrapMasteryEffect effect) {
@@ -81,7 +81,7 @@ class ScrapMasteryEffect extends OneShotEffect {
}
}
}
- // puts all cards he or she exiled this way onto the battlefield
+ // puts all cards they exiled this way onto the battlefield
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
diff --git a/Mage.Sets/src/mage/cards/s/Seance.java b/Mage.Sets/src/mage/cards/s/Seance.java
index cd3d7031d03..251b1b8e800 100644
--- a/Mage.Sets/src/mage/cards/s/Seance.java
+++ b/Mage.Sets/src/mage/cards/s/Seance.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -7,8 +6,8 @@ import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
+import mage.abilities.effects.common.ExileTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -17,7 +16,7 @@ import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
@@ -35,7 +34,7 @@ public final class Seance extends CardImpl {
// At the beginning of each upkeep, you may exile target creature card from your graveyard. If you do, create a token that's a copy of that card except it's a Spirit in addition to its other types. Exile it at the beginning of the next end step.
Ability ability = new BeginningOfUpkeepTriggeredAbility(new SeanceEffect(), TargetController.ANY, true);
- ability.addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard()));
+ ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/s/SearingBarrage.java b/Mage.Sets/src/mage/cards/s/SearingBarrage.java
new file mode 100644
index 00000000000..3032de92a33
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SearingBarrage.java
@@ -0,0 +1,44 @@
+package mage.cards.s;
+
+import mage.abilities.condition.common.AdamantCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.DamageTargetControllerEffect;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.target.common.TargetCreaturePermanent;
+import mage.watchers.common.ManaSpentToCastWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SearingBarrage extends CardImpl {
+
+ public SearingBarrage(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}");
+
+ // Searing Barrage deals 5 damage to target creature.
+ this.getSpellAbility().addEffect(new DamageTargetEffect(5));
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent());
+
+ // Adamant — If at least three red mana was spent to cast this spell, Searing Barrage deals 3 damage to that creature's controller.
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new DamageTargetControllerEffect(3), AdamantCondition.RED,
+ "
Adamant — If at least three red mana was spent to cast this spell, " +
+ "{this} deals 3 damage to that creature's controller."
+ ));
+ this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher());
+ }
+
+ private SearingBarrage(final SearingBarrage card) {
+ super(card);
+ }
+
+ @Override
+ public SearingBarrage copy() {
+ return new SearingBarrage(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SeasonedPyromancer.java b/Mage.Sets/src/mage/cards/s/SeasonedPyromancer.java
index 64859e69519..f30bcf4b83f 100644
--- a/Mage.Sets/src/mage/cards/s/SeasonedPyromancer.java
+++ b/Mage.Sets/src/mage/cards/s/SeasonedPyromancer.java
@@ -86,7 +86,7 @@ class SeasonedPyromancerEffect extends OneShotEffect {
int toDiscard = Math.min(player.getHand().size(), 2);
if (toDiscard > 0) {
TargetCard target = new TargetCardInHand(toDiscard, StaticFilters.FILTER_CARD);
- if (player.choose(outcome, player.getHand(), target, game)) {
+ if (player.choose(Outcome.Discard, player.getHand(), target, game)) {
Cards cards = new CardsImpl(target.getTargets());
for (Card card : cards.getCards(game)) {
if (player.discard(card, source, game) && !card.isLand()) {
diff --git a/Mage.Sets/src/mage/cards/s/SeedGuardian.java b/Mage.Sets/src/mage/cards/s/SeedGuardian.java
index 4b1223dadb5..ade4624f249 100644
--- a/Mage.Sets/src/mage/cards/s/SeedGuardian.java
+++ b/Mage.Sets/src/mage/cards/s/SeedGuardian.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -11,9 +10,9 @@ import mage.abilities.keyword.ReachAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Outcome;
-import mage.filter.common.FilterCreatureCard;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.token.SeedGuardianToken;
import mage.players.Player;
@@ -66,7 +65,7 @@ class SeedGuardianEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- int creaturesInGraveyard = controller.getGraveyard().count(new FilterCreatureCard(), game);
+ int creaturesInGraveyard = controller.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game);
return new CreateTokenEffect(new SeedGuardianToken(creaturesInGraveyard)).apply(game, source);
}
return false;
diff --git a/Mage.Sets/src/mage/cards/s/SeedSpark.java b/Mage.Sets/src/mage/cards/s/SeedSpark.java
index 2d1a454dc2c..291e2dec9bd 100644
--- a/Mage.Sets/src/mage/cards/s/SeedSpark.java
+++ b/Mage.Sets/src/mage/cards/s/SeedSpark.java
@@ -31,7 +31,7 @@ public final class SeedSpark extends CardImpl {
//If {G} was spent to cast Seed Spark, create two 1/1 green Saproling creature tokens.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new CreateTokenEffect(new SaprolingToken(), 2),
- new ManaWasSpentCondition(ColoredManaSymbol.G), "If {G} was spent to cast {this}, create two 1/1 green Saproling creature tokens"));
+ new ManaWasSpentCondition(ColoredManaSymbol.G), "If {G} was spent to cast this spell, create two 1/1 green Saproling creature tokens"));
}
public SeedSpark(final SeedSpark card) {
diff --git a/Mage.Sets/src/mage/cards/s/SelfInflictedWound.java b/Mage.Sets/src/mage/cards/s/SelfInflictedWound.java
index 9e4665ebc29..52812cd5b7e 100644
--- a/Mage.Sets/src/mage/cards/s/SelfInflictedWound.java
+++ b/Mage.Sets/src/mage/cards/s/SelfInflictedWound.java
@@ -30,7 +30,7 @@ public final class SelfInflictedWound extends CardImpl {
public SelfInflictedWound(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{B}");
- // Target opponent sacrifices a green or white creature. If that player does, he or she loses 2 life.
+ // Target opponent sacrifices a green or white creature. If that player does, they lose 2 life.
this.getSpellAbility().addTarget(new TargetOpponent());
this.getSpellAbility().addEffect(new SelfInflictedWoundEffect());
@@ -50,7 +50,7 @@ class SelfInflictedWoundEffect extends OneShotEffect {
SelfInflictedWoundEffect() {
super(Outcome.Sacrifice);
- staticText = "Target opponent sacrifices a green or white creature. If that player does, he or she loses 2 life";
+ staticText = "Target opponent sacrifices a green or white creature. If that player does, they lose 2 life";
}
SelfInflictedWoundEffect(SelfInflictedWoundEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/SerpentOfYawningDepths.java b/Mage.Sets/src/mage/cards/s/SerpentOfYawningDepths.java
new file mode 100644
index 00000000000..70dd0f83b98
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SerpentOfYawningDepths.java
@@ -0,0 +1,84 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.RestrictionEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SerpentOfYawningDepths extends CardImpl {
+
+ public SerpentOfYawningDepths(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{4}{U}{U}");
+
+ this.subtype.add(SubType.SERPENT);
+ this.power = new MageInt(6);
+ this.toughness = new MageInt(6);
+
+ // Krakens, Leviathans, Octopuses, and Serpents you control can't be blocked except by Krakens, Leviathans, Octopuses, and Serpents.
+ this.addAbility(new SimpleStaticAbility(new SerpentOfYawningDepthsEffect()));
+ }
+
+ private SerpentOfYawningDepths(final SerpentOfYawningDepths card) {
+ super(card);
+ }
+
+ @Override
+ public SerpentOfYawningDepths copy() {
+ return new SerpentOfYawningDepths(this);
+ }
+}
+
+class SerpentOfYawningDepthsEffect extends RestrictionEffect {
+
+ private static final FilterPermanent filter = new FilterCreaturePermanent();
+
+ static {
+ filter.add(Predicates.or(
+ new SubtypePredicate(SubType.KRAKEN),
+ new SubtypePredicate(SubType.LEVIATHAN),
+ new SubtypePredicate(SubType.OCTOPUS),
+ new SubtypePredicate(SubType.SERPENT)
+ ));
+ }
+
+ SerpentOfYawningDepthsEffect() {
+ super(Duration.WhileOnBattlefield);
+ this.staticText = "Krakens, Leviathans, Octopuses, and Serpents you control " +
+ "can't be blocked except by Krakens, Leviathans, Octopuses, and Serpents.";
+ }
+
+ private SerpentOfYawningDepthsEffect(SerpentOfYawningDepthsEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public SerpentOfYawningDepthsEffect copy() {
+ return new SerpentOfYawningDepthsEffect(this);
+ }
+
+ @Override
+ public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game, boolean canUseChooseDialogs) {
+ return filter.match(blocker, game);
+ }
+
+ @Override
+ public boolean applies(Permanent permanent, Ability source, Game game) {
+ return permanent.isControlledBy(source.getControllerId()) && filter.match(permanent, game);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SetessanChampion.java b/Mage.Sets/src/mage/cards/s/SetessanChampion.java
new file mode 100644
index 00000000000..07657fc7424
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SetessanChampion.java
@@ -0,0 +1,45 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.abilityword.ConstellationAbility;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SetessanChampion extends CardImpl {
+
+ public SetessanChampion(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(3);
+
+ // Constellation — Whenever an enchantment enters the battlefield under your control, put a +1/+1 counter on Setessan Champion and draw a card.
+ Ability ability = new ConstellationAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false, false
+ );
+ ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and"));
+ this.addAbility(ability);
+ }
+
+ private SetessanChampion(final SetessanChampion card) {
+ super(card);
+ }
+
+ @Override
+ public SetessanChampion copy() {
+ return new SetessanChampion(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SevenDwarves.java b/Mage.Sets/src/mage/cards/s/SevenDwarves.java
new file mode 100644
index 00000000000..03a6b1caa1b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SevenDwarves.java
@@ -0,0 +1,64 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.effects.common.InfoEffect;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.mageobject.NamePredicate;
+import mage.filter.predicate.permanent.AnotherPredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SevenDwarves extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledCreaturePermanent();
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ filter.add(new NamePredicate("Seven Dwarves"));
+ }
+
+ private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
+
+ public SevenDwarves(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
+
+ this.subtype.add(SubType.DWARF);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Seven Dwarves gets +1/+1 for each other creature named Seven Dwarves you control.
+ this.addAbility(new SimpleStaticAbility(
+ new BoostSourceEffect(xValue, xValue, Duration.WhileOnBattlefield).setText(
+ "{this} gets +1/+1 for each other creature named Seven Dwarves you control"
+ )
+ ));
+
+ // A deck can have up to seven cards named Seven Dwarves.
+ this.addAbility(new SimpleStaticAbility(
+ Zone.ALL, new InfoEffect("A deck can have up to seven cards named Seven Dwarves.")
+ ));
+ }
+
+ private SevenDwarves(final SevenDwarves card) {
+ super(card);
+ }
+
+ @Override
+ public SevenDwarves copy() {
+ return new SevenDwarves(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SevinneTheChronoclasm.java b/Mage.Sets/src/mage/cards/s/SevinneTheChronoclasm.java
index 0c4600499d5..79b6f7f9184 100644
--- a/Mage.Sets/src/mage/cards/s/SevinneTheChronoclasm.java
+++ b/Mage.Sets/src/mage/cards/s/SevinneTheChronoclasm.java
@@ -54,7 +54,7 @@ public final class SevinneTheChronoclasm extends CardImpl {
class SevinneTheChronoclasmTriggeredAbility extends SpellCastControllerTriggeredAbility {
SevinneTheChronoclasmTriggeredAbility() {
- super(Zone.BATTLEFIELD, null, StaticFilters.FILTER_SPELL_INSTANT_OR_SORCERY, false, true);
+ super(Zone.BATTLEFIELD, null, StaticFilters.FILTER_SPELL_INSTANT_OR_SORCERY, false, false);
}
private SevinneTheChronoclasmTriggeredAbility(final SevinneTheChronoclasmTriggeredAbility ability) {
diff --git a/Mage.Sets/src/mage/cards/s/ShadowbornDemon.java b/Mage.Sets/src/mage/cards/s/ShadowbornDemon.java
index 3df0a4f7f86..4ea9420dc09 100644
--- a/Mage.Sets/src/mage/cards/s/ShadowbornDemon.java
+++ b/Mage.Sets/src/mage/cards/s/ShadowbornDemon.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -18,7 +17,6 @@ import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterCreatureCard;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SubtypePredicate;
@@ -83,7 +81,7 @@ class CreatureCardsInControllerGraveCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
Player p = game.getPlayer(source.getControllerId());
- if (p != null && p.getGraveyard().count(new FilterCreatureCard(), game) >= value) {
+ if (p != null && p.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game) >= value) {
return true;
}
return false;
diff --git a/Mage.Sets/src/mage/cards/s/ShadowsOfThePast.java b/Mage.Sets/src/mage/cards/s/ShadowsOfThePast.java
index a231f823b94..7efe75f4e2a 100644
--- a/Mage.Sets/src/mage/cards/s/ShadowsOfThePast.java
+++ b/Mage.Sets/src/mage/cards/s/ShadowsOfThePast.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -15,7 +14,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -24,14 +23,14 @@ import mage.filter.common.FilterCreatureCard;
public final class ShadowsOfThePast extends CardImpl {
public ShadowsOfThePast(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}");
// Whenever a creature dies, scry 1.
this.addAbility(new DiesCreatureTriggeredAbility(new ScryEffect(1), false));
// {4}{B}: Each opponent loses 2 life and you gain 2 life. Activate this ability only if there are four or more creature cards in your graveyard.
Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD,
- new LoseLifeOpponentsEffect(2), new ManaCostsImpl<>("{4}{B}"), new CardsInControllerGraveCondition(4, new FilterCreatureCard()));
+ new LoseLifeOpponentsEffect(2), new ManaCostsImpl<>("{4}{B}"), new CardsInControllerGraveCondition(4, StaticFilters.FILTER_CARD_CREATURE));
Effect effect = new GainLifeEffect(2);
effect.setText("and you gain 2 life");
ability.addEffect(effect);
diff --git a/Mage.Sets/src/mage/cards/s/ShamanOfForgottenWays.java b/Mage.Sets/src/mage/cards/s/ShamanOfForgottenWays.java
index 8718cc44df4..bf767e45919 100644
--- a/Mage.Sets/src/mage/cards/s/ShamanOfForgottenWays.java
+++ b/Mage.Sets/src/mage/cards/s/ShamanOfForgottenWays.java
@@ -44,7 +44,7 @@ public final class ShamanOfForgottenWays extends CardImpl {
// {T}:Add two mana in any combination of colors. Spend this mana only to cast creature spells.
this.addAbility(new ConditionalAnyColorManaAbility(2, new ShamanOfForgottenWaysManaBuilder()));
- // Formidable — {9}{G}{G},{T}:Each player's life total becomes the number of creatures he or she controls. Activate the ability only if creatures you control have total power 8 or greater.
+ // Formidable — {9}{G}{G},{T}:Each player's life total becomes the number of creatures they control. Activate the ability only if creatures you control have total power 8 or greater.
Ability ability = new ActivateIfConditionActivatedAbility(
Zone.BATTLEFIELD,
new ShamanOfForgottenWaysEffect(),
@@ -100,7 +100,7 @@ class ShamanOfForgottenWaysEffect extends OneShotEffect {
public ShamanOfForgottenWaysEffect() {
super(Outcome.Benefit);
- this.staticText = "each player's life total becomes the number of creatures he or she controls";
+ this.staticText = "each player's life total becomes the number of creatures they control";
}
public ShamanOfForgottenWaysEffect(final ShamanOfForgottenWaysEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/ShamblingSuit.java b/Mage.Sets/src/mage/cards/s/ShamblingSuit.java
new file mode 100644
index 00000000000..43efe5a3805
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/ShamblingSuit.java
@@ -0,0 +1,50 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.effects.common.continuous.SetPowerSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterArtifactOrEnchantmentPermanent;
+import mage.filter.predicate.permanent.ControllerPredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ShamblingSuit extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterArtifactOrEnchantmentPermanent("artifacts and/or enchantments you control");
+
+ static {
+ filter.add(new ControllerPredicate(TargetController.YOU));
+ }
+
+ private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
+
+ public ShamblingSuit(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}");
+
+ this.subtype.add(SubType.CONSTRUCT);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(3);
+
+ // Shambling Suit's power is equal to the number of artifacts and/or enchantments you control.
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerSourceEffect(xValue, Duration.EndOfGame)));
+ }
+
+ private ShamblingSuit(final ShamblingSuit card) {
+ super(card);
+ }
+
+ @Override
+ public ShamblingSuit copy() {
+ return new ShamblingSuit(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/ShapeAnew.java b/Mage.Sets/src/mage/cards/s/ShapeAnew.java
index feaef70514d..1e4f0df1a22 100644
--- a/Mage.Sets/src/mage/cards/s/ShapeAnew.java
+++ b/Mage.Sets/src/mage/cards/s/ShapeAnew.java
@@ -24,7 +24,7 @@ public final class ShapeAnew extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}");
// The controller of target artifact sacrifices it, then reveals cards from the top
- // of their library until he or she reveals an artifact card. That player puts
+ // of their library until they reveal an artifact card. That player puts
// that card onto the battlefield, then shuffles all other cards revealed this way into their library.
this.getSpellAbility().addEffect(new ShapeAnewEffect());
this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_AN));
@@ -43,7 +43,7 @@ public final class ShapeAnew extends CardImpl {
public ShapeAnewEffect() {
super(Outcome.PutCardInPlay);
- staticText = "The controller of target artifact sacrifices it, then reveals cards from the top of their library until he or she reveals an artifact card. That player puts that card onto the battlefield, then shuffles all other cards revealed this way into their library";
+ staticText = "The controller of target artifact sacrifices it, then reveals cards from the top of their library until they reveal an artifact card. That player puts that card onto the battlefield, then shuffles all other cards revealed this way into their library";
}
public ShapeAnewEffect(ShapeAnewEffect effect) {
@@ -74,7 +74,7 @@ public final class ShapeAnew extends CardImpl {
if (artifactCard != null) {
targetController.moveCards(artifactCard, Zone.BATTLEFIELD, source, game);
}
- // 1/1/2011: If the first card the player reveals is an artifact card, he or she will still have to shuffle their library even though no other cards were revealed this way.
+ // 1/1/2011: If the first card the player reveals is an artifact card, they will still have to shuffle their library even though no other cards were revealed this way.
targetController.shuffleLibrary(source, game);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/s/SharedFate.java b/Mage.Sets/src/mage/cards/s/SharedFate.java
index af6e235b33c..b778c0c5e45 100644
--- a/Mage.Sets/src/mage/cards/s/SharedFate.java
+++ b/Mage.Sets/src/mage/cards/s/SharedFate.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -9,11 +8,7 @@ import mage.abilities.effects.ReplacementEffectImpl;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.AsThoughEffectType;
-import mage.constants.CardType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.game.ExileZone;
import mage.game.Game;
import mage.game.events.GameEvent;
@@ -24,18 +19,17 @@ import mage.target.common.TargetOpponent;
import mage.util.CardUtil;
/**
- *
* @author emerald000 / HCrescent
*/
public final class SharedFate extends CardImpl {
public SharedFate(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{U}");
// If a player would draw a card, that player exiles the top card of one of their opponents' libraries face down instead.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SharedFateReplacementEffect()));
- // Each player may look at and play cards he or she exiled with Shared Fate.
+ // Each player may look at and play cards they exiled with Shared Fate.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SharedFatePlayEffect()));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SharedFateLookEffect()));
}
@@ -78,12 +72,9 @@ class SharedFateReplacementEffect extends ReplacementEffectImpl {
Card card = chosenPlayer.getLibrary().getFromTop(game);
if (card != null) {
playerToDraw.moveCardsToExile(
- card,
- source,
- game,
- false,
+ card, source, game, false,
CardUtil.getExileZoneId(source.getSourceId().toString() + sourcePermanent.getZoneChangeCounter(game) + playerToDraw.getId().toString(), game),
- "Shared Fate (" + playerToDraw.getName() + ')');
+ sourcePermanent.getIdName() + "-" + sourcePermanent.getZoneChangeCounter(game) + " (" + playerToDraw.getName() + ')');
card.setFaceDown(true, game);
}
}
@@ -107,7 +98,7 @@ class SharedFatePlayEffect extends AsThoughEffectImpl {
SharedFatePlayEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit);
- staticText = "Each player may look at and play cards he or she exiled with {this}";
+ staticText = "Each player may look at and play cards they exiled with {this}";
}
SharedFatePlayEffect(final SharedFatePlayEffect effect) {
@@ -126,18 +117,11 @@ class SharedFatePlayEffect extends AsThoughEffectImpl {
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
- if (game.getState().getZone(objectId) == Zone.EXILED) {
- Player player = game.getPlayer(affectedControllerId);
+ if (game.getState().getZone(objectId) == Zone.EXILED) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
UUID exileId = CardUtil.getExileZoneId(source.getSourceId().toString() + sourcePermanent.getZoneChangeCounter(game) + affectedControllerId.toString(), game);
- if (exileId != null) {
- ExileZone exileZone = game.getExile().getExileZone(exileId);
- if (exileZone != null && exileZone.contains(objectId)) {
- if (player != null && player.chooseUse(outcome, "Play " + game.getCard(objectId).getIdName() + '?', source, game)) {
- return true;
- }
- }
- }
+ ExileZone exileZone = game.getExile().getExileZone(exileId);
+ return exileZone != null && exileZone.contains(objectId);
}
return false;
}
@@ -166,17 +150,13 @@ class SharedFateLookEffect extends AsThoughEffectImpl {
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
- if (game.getState().getZone(objectId) == Zone.EXILED) {
+ if (game.getState().getZone(objectId) == Zone.EXILED) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
UUID exileId = CardUtil.getExileZoneId(source.getSourceId().toString() + sourcePermanent.getZoneChangeCounter(game) + affectedControllerId.toString(), game);
- if (exileId != null) {
- ExileZone exileZone = game.getExile().getExileZone(exileId);
- if (exileZone != null && exileZone.contains(objectId)) {
- Card card = game.getCard(objectId);
- if (card != null && game.getState().getZone(objectId) == Zone.EXILED) {
- return true;
- }
- }
+ ExileZone exileZone = game.getExile().getExileZone(exileId);
+ if (exileZone != null && exileZone.contains(objectId)) {
+ Card card = game.getCard(objectId);
+ return card != null && game.getState().getZone(objectId) == Zone.EXILED;
}
}
return false;
diff --git a/Mage.Sets/src/mage/cards/s/SharedSummons.java b/Mage.Sets/src/mage/cards/s/SharedSummons.java
index 62c9d5edf93..f49b10117ca 100644
--- a/Mage.Sets/src/mage/cards/s/SharedSummons.java
+++ b/Mage.Sets/src/mage/cards/s/SharedSummons.java
@@ -1,5 +1,6 @@
package mage.cards.s;
+import mage.abilities.Ability;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
@@ -55,15 +56,20 @@ class SharedSummonsTarget extends TargetCardInLibrary {
}
@Override
- public boolean canTarget(UUID id, Cards cards, Game game) {
+ public boolean canTarget(UUID playerId, UUID id, Ability source, Cards cards, Game game) {
Card card = cards.get(id, game);
if (card == null || !card.isCreature()) {
return false;
}
- return !this
+
+ if (!filter.match(card, playerId, game)) {
+ return false;
+ }
+
+ return this
.getTargets()
.stream()
- .map(uuid -> game.getCard(uuid))
- .anyMatch(c -> c != null && c.getName().equals(card.getName()));
+ .map(game::getCard)
+ .noneMatch(c -> c != null && c.getName().equals(card.getName()));
}
}
diff --git a/Mage.Sets/src/mage/cards/s/ShellOfTheLastKappa.java b/Mage.Sets/src/mage/cards/s/ShellOfTheLastKappa.java
index ec154e28e83..3f90c146498 100644
--- a/Mage.Sets/src/mage/cards/s/ShellOfTheLastKappa.java
+++ b/Mage.Sets/src/mage/cards/s/ShellOfTheLastKappa.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -38,11 +37,13 @@ import mage.util.CardUtil;
*/
public final class ShellOfTheLastKappa extends CardImpl {
- private static final FilterSpell filter = new FilterSpell("instant or sorcery spell that targets you");
+ private static final FilterSpell filter
+ = new FilterSpell("instant or sorcery spell that targets you");
static {
filter.add(new TargetYouPredicate());
- filter.add(Predicates.or(new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.SORCERY)));
+ filter.add(Predicates.or(new CardTypePredicate(CardType.INSTANT),
+ new CardTypePredicate(CardType.SORCERY)));
}
public ShellOfTheLastKappa(UUID ownerId, CardSetInfo setInfo) {
@@ -50,13 +51,16 @@ public final class ShellOfTheLastKappa extends CardImpl {
addSuperType(SuperType.LEGENDARY);
// {3}, {tap}: Exile target instant or sorcery spell that targets you.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ShellOfTheLastKappaEffect(), new ManaCostsImpl("{3}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
+ new ShellOfTheLastKappaEffect(), new ManaCostsImpl("{3}"));
ability.addCost(new TapSourceCost());
Target target = new TargetSpell(filter);
ability.addTarget(target);
this.addAbility(ability);
- // {3}, {tap}, Sacrifice Shell of the Last Kappa: You may cast a card exiled with Shell of the Last Kappa without paying its mana cost.
- ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ShellOfTheLastKappaCastEffect(), new ManaCostsImpl("{3}"));
+ // {3}, {tap}, Sacrifice Shell of the Last Kappa: You may cast a card
+ // exiled with Shell of the Last Kappa without paying its mana cost.
+ ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
+ new ShellOfTheLastKappaCastEffect(), new ManaCostsImpl("{3}"));
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
this.addAbility(ability);
@@ -100,7 +104,11 @@ class ShellOfTheLastKappaEffect extends OneShotEffect {
if (sourcePermanent != null) {
game.getStack().counter(spell.getId(), source.getSourceId(), game);
Card card = spell.getCard();
- card.moveToExile(CardUtil.getCardExileZoneId(game, source), sourcePermanent.getName(), source.getSourceId(), game);
+ if (card != null) {
+ return card.moveToExile(CardUtil.getExileZoneId(game, source.getSourceId(),
+ sourcePermanent.getZoneChangeCounter(game)),
+ sourcePermanent.getName(), source.getSourceId(), game);
+ }
}
}
return false;
@@ -126,13 +134,23 @@ class ShellOfTheLastKappaCastEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- TargetCardInExile target = new TargetCardInExile(new FilterCard(), CardUtil.getCardExileZoneId(game, source));
- if (controller.choose(Outcome.PlayForFree, game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)), target, game)) {
+ Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
+ if (controller != null
+ && sourcePermanent != null) {
+ TargetCardInExile target = new TargetCardInExile(new FilterCard(),
+ CardUtil.getExileZoneId(game, source.getSourceId(), sourcePermanent.getZoneChangeCounter(game)));
+ if (controller.choose(Outcome.PlayForFree, game.getExile()
+ .getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(),
+ sourcePermanent.getZoneChangeCounter(game))), target, game)) {
Card card = game.getCard(target.getFirstTarget());
- if (card != null) {
- game.getExile().removeCard(card, game);
- return controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ if (card != null
+ && controller.chooseUse(outcome, "Do you wish to cast card exiled with "
+ + sourcePermanent.getLogName() + "?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ return cardWasCast;
}
}
}
diff --git a/Mage.Sets/src/mage/cards/s/ShepherdOfTheFlock.java b/Mage.Sets/src/mage/cards/s/ShepherdOfTheFlock.java
new file mode 100644
index 00000000000..2d08c676f9b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/ShepherdOfTheFlock.java
@@ -0,0 +1,40 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ShepherdOfTheFlock extends AdventureCard {
+
+ public ShepherdOfTheFlock(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.INSTANT}, "{1}{W}", "Usher to Safety", "{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.PEASANT);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(1);
+
+ // Usher to Safety
+ // Return target permanent you control to its owner’s hand.
+ this.getSpellCard().getSpellAbility().addEffect(new ReturnToHandTargetEffect());
+ this.getSpellCard().getSpellAbility().addTarget(new TargetControlledPermanent());
+ }
+
+ private ShepherdOfTheFlock(final ShepherdOfTheFlock card) {
+ super(card);
+ }
+
+ @Override
+ public ShepherdOfTheFlock copy() {
+ return new ShepherdOfTheFlock(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/ShieldOfTheAvatar.java b/Mage.Sets/src/mage/cards/s/ShieldOfTheAvatar.java
index 7439718122b..085410a9fe1 100644
--- a/Mage.Sets/src/mage/cards/s/ShieldOfTheAvatar.java
+++ b/Mage.Sets/src/mage/cards/s/ShieldOfTheAvatar.java
@@ -11,7 +11,9 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.game.permanent.Permanent;
import java.util.UUID;
@@ -72,7 +74,7 @@ class ShieldOfTheAvatarPreventionEffect extends PreventionEffectImpl {
if (equipment != null && equipment.getAttachedTo() != null) {
int numberOfCreaturesControlled = CreaturesYouControlCount.instance.calculate(game, source, this);
int toPrevent = Math.min(numberOfCreaturesControlled, event.getAmount());
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, equipment.getAttachedTo(), source.getSourceId(), source.getControllerId(), toPrevent, false);
+ GameEvent preventEvent = new PreventDamageEvent(equipment.getAttachedTo(), source.getSourceId(), source.getControllerId(), toPrevent, ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
if (event.getAmount() >= toPrevent) {
event.setAmount(event.getAmount() - toPrevent);
diff --git a/Mage.Sets/src/mage/cards/s/ShimianSpecter.java b/Mage.Sets/src/mage/cards/s/ShimianSpecter.java
index a06d58fe985..8ef4aa960c5 100644
--- a/Mage.Sets/src/mage/cards/s/ShimianSpecter.java
+++ b/Mage.Sets/src/mage/cards/s/ShimianSpecter.java
@@ -122,7 +122,7 @@ class ShimianSpecterEffect extends OneShotEffect {
}
// search cards in Library
- // If the player has no nonland cards in their hand, you can still search that player's library and have him or her shuffle it.
+ // If the player has no nonland cards in their hand, you can still search that player's library and have that player shuffle it.
if (chosenCard != null || controller.chooseUse(outcome, "Search library anyway?", source, game)) {
TargetCardInLibrary targetCardsLibrary = new TargetCardInLibrary(0, Integer.MAX_VALUE, filterNamedCards);
controller.searchLibrary(targetCardsLibrary, source, game, targetPlayer.getId());
diff --git a/Mage.Sets/src/mage/cards/s/ShimmerDragon.java b/Mage.Sets/src/mage/cards/s/ShimmerDragon.java
new file mode 100644
index 00000000000..b4c81df30b6
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/ShimmerDragon.java
@@ -0,0 +1,76 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.costs.common.TapTargetCost;
+import mage.abilities.decorator.ConditionalContinuousEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.abilities.keyword.HexproofAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterControlledArtifactPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.permanent.TappedPredicate;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ShimmerDragon extends CardImpl {
+
+ private static final Condition condition = new PermanentsOnTheBattlefieldCondition(
+ StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT, ComparisonType.MORE_THAN, 3
+ );
+ private static final FilterControlledPermanent filter
+ = new FilterControlledArtifactPermanent("untapped artifacts you control");
+
+ static {
+ filter.add(Predicates.not(TappedPredicate.instance));
+ }
+
+ public ShimmerDragon(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{U}");
+
+ this.subtype.add(SubType.DRAGON);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(6);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // As long as you control four or more artifacts, Shimmer Dragon has hexproof.
+ this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
+ new GainAbilitySourceEffect(
+ HexproofAbility.getInstance(), Duration.WhileOnBattlefield
+ ), condition, "as long as you control four or more artifacts, {this} has hexproof"
+ )));
+
+ // Tap two untapped artifacts you control: Draw a card.
+ this.addAbility(new SimpleActivatedAbility(
+ new DrawCardSourceControllerEffect(1),
+ new TapTargetCost(new TargetControlledPermanent(2, filter))
+ ));
+ }
+
+ private ShimmerDragon(final ShimmerDragon card) {
+ super(card);
+ }
+
+ @Override
+ public ShimmerDragon copy() {
+ return new ShimmerDragon(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/Shinechaser.java b/Mage.Sets/src/mage/cards/s/Shinechaser.java
new file mode 100644
index 00000000000..159ac93d056
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/Shinechaser.java
@@ -0,0 +1,55 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.continuous.BoostSourceWhileControlsEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterEnchantmentPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class Shinechaser extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterEnchantmentPermanent("an enchantment");
+
+ public Shinechaser(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}");
+
+ this.subtype.add(SubType.FAERIE);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Vigilance
+ this.addAbility(VigilanceAbility.getInstance());
+
+ // Shinechaser gets +1/+1 as long as you control an artifact.
+ this.addAbility(new SimpleStaticAbility(
+ new BoostSourceWhileControlsEffect(StaticFilters.FILTER_PERMANENT_ARTIFACT_AN, 1, 1)
+ ));
+
+ // Shinechaser gets +1/+1 as long as you control an enchantment.
+ this.addAbility(new SimpleStaticAbility(new BoostSourceWhileControlsEffect(filter, 1, 1)));
+ }
+
+ private Shinechaser(final Shinechaser card) {
+ super(card);
+ }
+
+ @Override
+ public Shinechaser copy() {
+ return new Shinechaser(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/ShiningArmor.java b/Mage.Sets/src/mage/cards/s/ShiningArmor.java
new file mode 100644
index 00000000000..aa0eaaeec50
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/ShiningArmor.java
@@ -0,0 +1,65 @@
+package mage.cards.s;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.continuous.BoostEquippedEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.abilities.keyword.EquipAbility;
+import mage.abilities.keyword.FlashAbility;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.AttachmentType;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ShiningArmor extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledPermanent(SubType.KNIGHT);
+
+ public ShiningArmor(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{W}");
+
+ this.subtype.add(SubType.EQUIPMENT);
+
+ // Flash
+ this.addAbility(FlashAbility.getInstance());
+
+ // When Shining Armor enters the battlefield, attach it to target Knight you control.
+ Ability ability = new EntersBattlefieldTriggeredAbility(
+ new AttachEffect(Outcome.Benefit, "attach it to target Knight you control")
+ );
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(ability);
+
+ // Equipped creature gets +0/+2 and has vigilance.
+ ability = new SimpleStaticAbility(new BoostEquippedEffect(0, 2));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ VigilanceAbility.getInstance(), AttachmentType.EQUIPMENT
+ ).setText("and has vigilance"));
+ this.addAbility(ability);
+
+ // Equip {3}
+ this.addAbility(new EquipAbility(3));
+ }
+
+ private ShiningArmor(final ShiningArmor card) {
+ super(card);
+ }
+
+ @Override
+ public ShiningArmor copy() {
+ return new ShiningArmor(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/Shriekhorn.java b/Mage.Sets/src/mage/cards/s/Shriekhorn.java
index 62130c56e69..9cab21e01f2 100644
--- a/Mage.Sets/src/mage/cards/s/Shriekhorn.java
+++ b/Mage.Sets/src/mage/cards/s/Shriekhorn.java
@@ -1,8 +1,5 @@
-
-
package mage.cards.s;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility;
@@ -13,26 +10,32 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
import mage.counters.CounterType;
import mage.target.TargetPlayer;
+import java.util.UUID;
+
/**
- *
* @author Loki
*/
public final class Shriekhorn extends CardImpl {
- public Shriekhorn (UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}");
- this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.CHARGE.createInstance(3)), "Shriekhorn enters the battlefield with three charge counters on it"));
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutLibraryIntoGraveTargetEffect(2), new TapSourceCost());
+ public Shriekhorn(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
+
+ this.addAbility(new EntersBattlefieldAbility(
+ new AddCountersSourceEffect(
+ CounterType.CHARGE.createInstance(3)
+ ), "with three charge counters on it"
+ ));
+
+ Ability ability = new SimpleActivatedAbility(new PutLibraryIntoGraveTargetEffect(2), new TapSourceCost());
ability.addCost(new RemoveCountersSourceCost(CounterType.CHARGE.createInstance()));
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
}
- public Shriekhorn (final Shriekhorn card) {
+ public Shriekhorn(final Shriekhorn card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/s/ShriekingAffliction.java b/Mage.Sets/src/mage/cards/s/ShriekingAffliction.java
index 50f0cb86e9e..97c8130fb7e 100644
--- a/Mage.Sets/src/mage/cards/s/ShriekingAffliction.java
+++ b/Mage.Sets/src/mage/cards/s/ShriekingAffliction.java
@@ -23,7 +23,7 @@ public final class ShriekingAffliction extends CardImpl {
public ShriekingAffliction(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}");
- // At the beginning of each opponent's upkeep, if that player has one or fewer cards in hand, he or she loses 3 life.
+ // At the beginning of each opponent's upkeep, if that player has one or fewer cards in hand, they lose 3 life.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility(
Zone.BATTLEFIELD, new LoseLifeTargetEffect(3),
diff --git a/Mage.Sets/src/mage/cards/s/ShriekingGrotesque.java b/Mage.Sets/src/mage/cards/s/ShriekingGrotesque.java
index 4cc23ef06a9..8303dd981dc 100644
--- a/Mage.Sets/src/mage/cards/s/ShriekingGrotesque.java
+++ b/Mage.Sets/src/mage/cards/s/ShriekingGrotesque.java
@@ -36,7 +36,7 @@ public final class ShriekingGrotesque extends CardImpl {
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DiscardTargetEffect(1), false);
ability.addTarget(new TargetPlayer());
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new ManaWasSpentCondition(ColoredManaSymbol.B),
- "if {B} was spent to cast {this}, target player discards a card."), new ManaSpentToCastWatcher());
+ "if {B} was spent to cast this spell, target player discards a card."), new ManaSpentToCastWatcher());
}
public ShriekingGrotesque(final ShriekingGrotesque card) {
diff --git a/Mage.Sets/src/mage/cards/s/ShroudedSerpent.java b/Mage.Sets/src/mage/cards/s/ShroudedSerpent.java
index 7f723469095..20f7a79421c 100644
--- a/Mage.Sets/src/mage/cards/s/ShroudedSerpent.java
+++ b/Mage.Sets/src/mage/cards/s/ShroudedSerpent.java
@@ -27,11 +27,11 @@ public final class ShroudedSerpent extends CardImpl {
this.power = new MageInt(4);
this.toughness = new MageInt(4);
- // Whenever Shrouded Serpent attacks, defending player may pay {4}. If he or she doesn't, Shrouded Serpent can't be blocked this turn.
+ // Whenever Shrouded Serpent attacks, defending player may pay {4}. If they don't, Shrouded Serpent can't be blocked this turn.
this.addAbility(new AttacksTriggeredAbility(
new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new CantBeBlockedByAllSourceEffect(new FilterCreaturePermanent(), Duration.EndOfCombat), new ManaCostsImpl("{4}")),
false,
- "Whenever {this} attacks, defending player may pay {4}. If he or she doesn't, {this} can't be blocked this turn.",
+ "Whenever {this} attacks, defending player may pay {4}. If they don't, {this} can't be blocked this turn.",
SetTargetPointer.PLAYER));
}
diff --git a/Mage.Sets/src/mage/cards/s/SidisiUndeadVizier.java b/Mage.Sets/src/mage/cards/s/SidisiUndeadVizier.java
index 05a20269890..df384d65312 100644
--- a/Mage.Sets/src/mage/cards/s/SidisiUndeadVizier.java
+++ b/Mage.Sets/src/mage/cards/s/SidisiUndeadVizier.java
@@ -36,7 +36,7 @@ public final class SidisiUndeadVizier extends CardImpl {
this.addAbility(new ExploitAbility());
// When Sidisi, Undead Vizier exploits a creature, you may search your library for a card, put it into your hand, then shuffle your library.
- this.addAbility(new ExploitCreatureTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(new FilterCard("a card")), false, true), false));
+ this.addAbility(new ExploitCreatureTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(new FilterCard("card")), false, true), false));
}
public SidisiUndeadVizier(final SidisiUndeadVizier card) {
diff --git a/Mage.Sets/src/mage/cards/s/SigardaHostOfHerons.java b/Mage.Sets/src/mage/cards/s/SigardaHostOfHerons.java
index 18cf5924251..0d0e4db5953 100644
--- a/Mage.Sets/src/mage/cards/s/SigardaHostOfHerons.java
+++ b/Mage.Sets/src/mage/cards/s/SigardaHostOfHerons.java
@@ -1,23 +1,20 @@
-
package mage.cards.s;
-import java.util.UUID;
import mage.MageInt;
-import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HexproofAbility;
-import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
-import mage.game.permanent.PermanentCard;
-import mage.game.stack.Spell;
-import mage.game.stack.StackAbility;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+import java.util.UUID;
/**
* @author noxx
@@ -72,28 +69,12 @@ class SigardaHostOfHeronsEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
- if (event.getPlayerId().equals(source.getControllerId())) {
- MageObject object = game.getObject(event.getSourceId());
- if (object instanceof PermanentCard) {
- if (game.getOpponents(source.getControllerId()).contains(((PermanentCard) object).getControllerId())) {
- return true;
- }
- }
- if (object instanceof Spell) {
- if (game.getOpponents(source.getControllerId()).contains(((Spell) object).getControllerId())) {
- return true;
- }
- }
- if (object instanceof Card) {
- if (game.getOpponents(source.getControllerId()).contains(((Card) object).getOwnerId())) {
- return true;
- }
- }
- if (object instanceof StackAbility) {
- if (game.getOpponents(source.getControllerId()).contains(((StackAbility) object).getControllerId())) {
- return true;
- }
- }
+ Player controller = game.getPlayer(source.getControllerId());
+ UUID eventSourceControllerId = game.getControllerId(event.getSourceId());
+ Permanent permanent = game.getPermanent(event.getTargetId());
+
+ if (controller != null && permanent != null && permanent.getControllerId() == source.getControllerId()) {
+ return game.getOpponents(source.getControllerId()).contains(eventSourceControllerId);
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/s/SignalTheClans.java b/Mage.Sets/src/mage/cards/s/SignalTheClans.java
index 44fc5b18e5b..0a9d34bad79 100644
--- a/Mage.Sets/src/mage/cards/s/SignalTheClans.java
+++ b/Mage.Sets/src/mage/cards/s/SignalTheClans.java
@@ -1,6 +1,8 @@
-
package mage.cards.s;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.SearchEffect;
@@ -8,24 +10,19 @@ import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
-import java.util.UUID;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
/**
*
* @author Plopman
*/
public final class SignalTheClans extends CardImpl {
- public SignalTheClans (UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}{G}");
-
+ public SignalTheClans(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}{G}");
// Search your library for three creature cards and reveal them. If you reveal three cards with different names, choose one of them at random and put that card into your hand. Shuffle the rest into your library.
this.getSpellAbility().addEffect(new SignalTheClansEffect());
@@ -36,16 +33,15 @@ public final class SignalTheClans extends CardImpl {
}
@Override
- public SignalTheClans copy() {
+ public SignalTheClans copy() {
return new SignalTheClans(this);
}
}
class SignalTheClansEffect extends SearchEffect {
-
public SignalTheClansEffect() {
- super(new TargetCardInLibrary(3, new FilterCreatureCard()), Outcome.DrawCard);
+ super(new TargetCardInLibrary(3, StaticFilters.FILTER_CARD_CREATURE), Outcome.DrawCard);
staticText = "Search your library for three creature cards and reveal them. If you reveal three cards with different names, choose one of them at random and put that card into your hand. Shuffle the rest into your library";
}
@@ -68,9 +64,9 @@ class SignalTheClansEffect extends SearchEffect {
if (player.searchLibrary(target, source, game)) {
if (!target.getTargets().isEmpty()) {
Cards cards = new CardsImpl();
- for (UUID cardId: target.getTargets()) {
+ for (UUID cardId : target.getTargets()) {
Card card = player.getLibrary().remove(cardId, game);
- if (card != null){
+ if (card != null) {
cards.add(card);
}
}
@@ -78,14 +74,14 @@ class SignalTheClansEffect extends SearchEffect {
player.revealCards("Reveal", cards, game);
Card cardsArray[] = cards.getCards(game).toArray(new Card[0]);
//If you reveal three cards with different names
- if(Stream.of(cardsArray).map(MageObject::getName).collect(Collectors.toSet()).size() == 3){
+ if (Stream.of(cardsArray).map(MageObject::getName).collect(Collectors.toSet()).size() == 3) {
//Choose one of them at random and put that card into your hand
Card randomCard = cards.getRandom(game);
randomCard.moveToZone(Zone.HAND, source.getSourceId(), game, true);
cards.remove(randomCard);
}
//Shuffle the rest into your library
- for(Card card : cards.getCards(game)){
+ for (Card card : cards.getCards(game)) {
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
}
}
diff --git a/Mage.Sets/src/mage/cards/s/SignpostScarecrow.java b/Mage.Sets/src/mage/cards/s/SignpostScarecrow.java
new file mode 100644
index 00000000000..a68cf6434c5
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SignpostScarecrow.java
@@ -0,0 +1,41 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.abilities.mana.AnyColorManaAbility;
+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 SignpostScarecrow extends CardImpl {
+
+ public SignpostScarecrow(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}");
+
+ this.subtype.add(SubType.SCARECROW);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(4);
+
+ // Vigilance
+ this.addAbility(VigilanceAbility.getInstance());
+
+ // {2}: Add one mana of any color.
+ this.addAbility(new AnyColorManaAbility(new GenericManaCost(2)));
+ }
+
+ private SignpostScarecrow(final SignpostScarecrow card) {
+ super(card);
+ }
+
+ @Override
+ public SignpostScarecrow copy() {
+ return new SignpostScarecrow(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SilentAssassin.java b/Mage.Sets/src/mage/cards/s/SilentAssassin.java
new file mode 100644
index 00000000000..d433cbf48bb
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SilentAssassin.java
@@ -0,0 +1,54 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
+import mage.abilities.effects.common.DestroyTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterBlockingCreature;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SilentAssassin extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterBlockingCreature();
+
+ public SilentAssassin(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{B}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.MERCENARY);
+ this.subtype.add(SubType.ASSASSIN);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(1);
+
+ // {3}{B}: Destroy target blocking creature at end of combat.
+ Ability ability = new SimpleActivatedAbility(new CreateDelayedTriggeredAbilityEffect(
+ new AtTheEndOfCombatDelayedTriggeredAbility(
+ new DestroyTargetEffect().setText("destroy target blocking creature")
+ ), true
+ ), new ManaCostsImpl("{3}{B}"));
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(ability);
+ }
+
+ private SilentAssassin(final SilentAssassin card) {
+ super(card);
+ }
+
+ @Override
+ public SilentAssassin copy() {
+ return new SilentAssassin(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SilentBladeOni.java b/Mage.Sets/src/mage/cards/s/SilentBladeOni.java
index 92f8ef6aaf4..3857e2a1c17 100644
--- a/Mage.Sets/src/mage/cards/s/SilentBladeOni.java
+++ b/Mage.Sets/src/mage/cards/s/SilentBladeOni.java
@@ -1,7 +1,5 @@
-
package mage.cards.s;
-import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
@@ -9,22 +7,20 @@ import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.NinjutsuAbility;
-import mage.cards.Card;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-import mage.cards.Cards;
-import mage.cards.CardsImpl;
+import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterNonlandCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
+import java.util.UUID;
+import mage.MageObject;
+
/**
- *
* @author LevelX2
*/
public final class SilentBladeOni extends CardImpl {
@@ -39,12 +35,15 @@ public final class SilentBladeOni extends CardImpl {
// Ninjutsu {4}{U}{B}
this.addAbility(new NinjutsuAbility(new ManaCostsImpl("{4}{U}{B}")));
- // Whenever Silent-Blade Oni deals combat damage to a player, look at that player's hand. You may cast a nonland card in it without paying that card's mana cost.
- this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new SilentBladeOniEffect(), false, true));
+ // Whenever Silent-Blade Oni deals combat damage to a player, look at that player's hand.
+ // You may cast a nonland card in it without paying that card's mana cost.
+ this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(
+ new SilentBladeOniEffect(), false, true
+ ));
}
- public SilentBladeOni(final SilentBladeOni card) {
+ private SilentBladeOni(final SilentBladeOni card) {
super(card);
}
@@ -56,12 +55,13 @@ public final class SilentBladeOni extends CardImpl {
class SilentBladeOniEffect extends OneShotEffect {
- public SilentBladeOniEffect() {
+ SilentBladeOniEffect() {
super(Outcome.PlayForFree);
- this.staticText = "look at that player's hand. You may cast a nonland card in it without paying that card's mana cost";
+ this.staticText = "look at that player's hand. "
+ + "You may cast a nonland card in it without paying that card's mana cost";
}
- public SilentBladeOniEffect(final SilentBladeOniEffect effect) {
+ private SilentBladeOniEffect(final SilentBladeOniEffect effect) {
super(effect);
}
@@ -74,21 +74,30 @@ class SilentBladeOniEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId());
- if (opponent != null && controller != null) {
- Cards cardsInHand = new CardsImpl();
- cardsInHand.addAll(opponent.getHand());
- if (!cardsInHand.isEmpty()) {
- TargetCard target = new TargetCard(1, Zone.HAND, new FilterNonlandCard());
- if (controller.chooseTarget(outcome, cardsInHand, target, source, game)) {
- Card card = game.getCard(target.getFirstTarget());
- if (card != null) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
- }
- }
-
- }
+ if (opponent == null
+ || controller == null) {
+ return false;
+ }
+ Cards cardsInHand = new CardsImpl();
+ cardsInHand.addAll(opponent.getHand());
+ if (cardsInHand.isEmpty()) {
return true;
}
- return false;
+ TargetCard target = new TargetCard(
+ 0, 1, Zone.HAND, StaticFilters.FILTER_CARD_A_NON_LAND
+ );
+ if (!controller.chooseUse(outcome, "Cast a card from " + opponent.getName() + "'s hand?", source, game)
+ || !controller.chooseTarget(outcome, cardsInHand, target, source, game)) {
+ return true;
+ }
+ Card card = game.getCard(target.getFirstTarget());
+ if (card == null) {
+ return false;
+ }
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ return cardWasCast;
}
}
diff --git a/Mage.Sets/src/mage/cards/s/SilverflameRitual.java b/Mage.Sets/src/mage/cards/s/SilverflameRitual.java
new file mode 100644
index 00000000000..c49488678fc
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SilverflameRitual.java
@@ -0,0 +1,77 @@
+package mage.cards.s;
+
+import mage.abilities.Ability;
+import mage.abilities.condition.common.AdamantCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
+import mage.abilities.effects.common.counter.AddCountersAllEffect;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.counters.CounterType;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.watchers.common.ManaSpentToCastWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SilverflameRitual extends CardImpl {
+
+ public SilverflameRitual(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{W}");
+
+ // Put a +1/+1 counter on each creature you control.
+ this.getSpellAbility().addEffect(new AddCountersAllEffect(
+ CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE
+ ));
+
+ // Adamant — If at least three white mana was spent to cast this spell, creatures you control gain vigilance until end of turn.
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new SilverflameRitualEffect(), AdamantCondition.WHITE,
+ "
Adamant — If at least three white mana was spent to cast this spell, " +
+ "creatures you control gain vigilance until end of turn."
+ ));
+ this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher());
+ }
+
+ private SilverflameRitual(final SilverflameRitual card) {
+ super(card);
+ }
+
+ @Override
+ public SilverflameRitual copy() {
+ return new SilverflameRitual(this);
+ }
+}
+
+class SilverflameRitualEffect extends OneShotEffect {
+
+ SilverflameRitualEffect() {
+ super(Outcome.Benefit);
+ }
+
+ private SilverflameRitualEffect(final SilverflameRitualEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public SilverflameRitualEffect copy() {
+ return new SilverflameRitualEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ game.addEffect(new GainAbilityControlledEffect(
+ VigilanceAbility.getInstance(), Duration.EndOfTurn,
+ StaticFilters.FILTER_PERMANENT_CREATURE
+ ), source);
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SilverflameSquire.java b/Mage.Sets/src/mage/cards/s/SilverflameSquire.java
new file mode 100644
index 00000000000..6f0f0b7e8ce
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SilverflameSquire.java
@@ -0,0 +1,43 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.effects.common.UntapTargetEffect;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SilverflameSquire extends AdventureCard {
+
+ public SilverflameSquire(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.INSTANT}, "{1}{W}", "On Alert", "{2}{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.SOLDIER);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(1);
+
+ // On Alert
+ // Target creature gets +2/+2 until end of turn. Untap it.
+ this.getSpellCard().getSpellAbility().addEffect(new BoostTargetEffect(2, 2, Duration.EndOfTurn));
+ this.getSpellCard().getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap it"));
+ this.getSpellCard().getSpellAbility().addTarget(new TargetCreaturePermanent());
+ }
+
+ private SilverflameSquire(final SilverflameSquire card) {
+ super(card);
+ }
+
+ @Override
+ public SilverflameSquire copy() {
+ return new SilverflameSquire(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SilverfurPartisan.java b/Mage.Sets/src/mage/cards/s/SilverfurPartisan.java
index 82648348dab..427708d1de9 100644
--- a/Mage.Sets/src/mage/cards/s/SilverfurPartisan.java
+++ b/Mage.Sets/src/mage/cards/s/SilverfurPartisan.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import mage.MageInt;
@@ -7,7 +6,6 @@ import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.TrampleAbility;
-import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -17,19 +15,18 @@ import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.WolfToken;
-import mage.game.stack.Spell;
+import mage.game.stack.StackObject;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
- *
* @author fireshoes
*/
public final class SilverfurPartisan extends CardImpl {
public SilverfurPartisan(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.WOLF);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(2);
@@ -75,11 +72,15 @@ class CreaturesYouControlBecomesTargetTriggeredAbility extends TriggeredAbilityI
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
- if (permanent != null && permanent.isControlledBy(this.controllerId) && (permanent.hasSubtype(SubType.WOLF, game) || permanent.hasSubtype(SubType.WEREWOLF, game))) {
- MageObject object = game.getObject(event.getSourceId());
- if (object instanceof Spell) {
- Card c = (Spell) object;
- if (c.isInstant() || c.isSorcery()) {
+ MageObject object = game.getObject(event.getSourceId());
+ if (permanent != null
+ && object != null
+ && permanent.isControlledBy(this.controllerId)
+ && (permanent.hasSubtype(SubType.WOLF, game)
+ || permanent.hasSubtype(SubType.WEREWOLF, game))) {
+ if (object instanceof StackObject) {
+ if (object.isInstant()
+ || object.isSorcery()) {
if (getTargets().isEmpty()) {
for (Effect effect : getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getTargetId()));
@@ -89,6 +90,7 @@ class CreaturesYouControlBecomesTargetTriggeredAbility extends TriggeredAbilityI
}
}
}
+
return false;
}
diff --git a/Mage.Sets/src/mage/cards/s/SilverwingSquadron.java b/Mage.Sets/src/mage/cards/s/SilverwingSquadron.java
new file mode 100644
index 00000000000..b240da7e81a
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SilverwingSquadron.java
@@ -0,0 +1,64 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.common.CreaturesYouControlCount;
+import mage.abilities.dynamicvalue.common.OpponentsCount;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect;
+import mage.abilities.hint.common.CreaturesYouControlHint;
+import mage.abilities.keyword.FlyingAbility;
+import mage.abilities.keyword.VigilanceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.game.permanent.token.KnightToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SilverwingSquadron extends CardImpl {
+
+ public SilverwingSquadron(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(0);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Vigilance
+ this.addAbility(VigilanceAbility.getInstance());
+
+ // Silverwing Squadron's power and toughness are each equal to the number of creatures you control.
+ this.addAbility(new SimpleStaticAbility(
+ Zone.ALL, new SetPowerToughnessSourceEffect(CreaturesYouControlCount.instance, Duration.EndOfGame)
+ ).addHint(CreaturesYouControlHint.instance));
+
+ // Whenever Silverwing Squadron attacks, create a number of 2/2 white Knight creature tokens with vigilance equal to the number of opponents you have.
+ this.addAbility(new AttacksTriggeredAbility(
+ new CreateTokenEffect(new KnightToken(), OpponentsCount.instance).setText(
+ "create a number of 2/2 white Knight creature tokens with vigilance " +
+ "equal to the number of opponents you have"
+ ), false
+ ));
+ }
+
+ private SilverwingSquadron(final SilverwingSquadron card) {
+ super(card);
+ }
+
+ @Override
+ public SilverwingSquadron copy() {
+ return new SilverwingSquadron(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SisayWeatherlightCaptain.java b/Mage.Sets/src/mage/cards/s/SisayWeatherlightCaptain.java
index b56fd86b3f4..e34eed618c4 100644
--- a/Mage.Sets/src/mage/cards/s/SisayWeatherlightCaptain.java
+++ b/Mage.Sets/src/mage/cards/s/SisayWeatherlightCaptain.java
@@ -119,7 +119,7 @@ class SisayWeatherlightCaptainEffect extends OneShotEffect {
return false;
}
int power = permanent.getPower().getValue();
- FilterCard filter = new FilterPermanentCard("permanent card with converted mana cost less than " + power);
+ FilterCard filter = new FilterPermanentCard("legendary permanent card with converted mana cost less than " + power);
filter.add(new SupertypePredicate(SuperType.LEGENDARY));
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, power));
return new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter)).apply(game, source);
diff --git a/Mage.Sets/src/mage/cards/s/SistersOfStoneDeath.java b/Mage.Sets/src/mage/cards/s/SistersOfStoneDeath.java
index ab178a600c2..4cb7bc88da9 100644
--- a/Mage.Sets/src/mage/cards/s/SistersOfStoneDeath.java
+++ b/Mage.Sets/src/mage/cards/s/SistersOfStoneDeath.java
@@ -1,5 +1,7 @@
package mage.cards.s;
+import java.util.LinkedList;
+import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -12,7 +14,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.*;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.BlockedByIdPredicate;
@@ -23,9 +25,6 @@ import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCreaturePermanent;
-import java.util.LinkedList;
-import java.util.UUID;
-
/**
* @author jeffwadsworth
*/
@@ -87,7 +86,7 @@ class SistersOfStoneDeathEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
CardsImpl cardsInExile = new CardsImpl();
- TargetCard target = new TargetCard(Zone.EXILED, new FilterCreatureCard());
+ TargetCard target = new TargetCard(Zone.EXILED, StaticFilters.FILTER_CARD_CREATURE);
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
ExileZone exile = game.getExile().getExileZone(exileId);
diff --git a/Mage.Sets/src/mage/cards/s/SithMagic.java b/Mage.Sets/src/mage/cards/s/SithMagic.java
index a45c7569763..5a8049ab2db 100644
--- a/Mage.Sets/src/mage/cards/s/SithMagic.java
+++ b/Mage.Sets/src/mage/cards/s/SithMagic.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -24,7 +23,7 @@ import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
@@ -41,7 +40,7 @@ import mage.watchers.common.LifeLossOtherFromCombatWatcher;
public final class SithMagic extends CardImpl {
public SithMagic(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{U}{B}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{B}{R}");
// Hate — At the beggining of each combat, if opponent lost life from a source other than combat damage this turn, you may return target card from a graveyard to the battlefield under your control. It gains lifelink and haste. Exile it at the beginning of the next end step or if it would leave the battlefield.
TriggeredAbility triggeredAbility = new BeginningOfCombatTriggeredAbility(new SithMagicEffect(), TargetController.ANY, true);
@@ -50,7 +49,7 @@ public final class SithMagic extends CardImpl {
triggeredAbility,
HateCondition.instance,
"Hate — At the beggining of each combat, if opponent lost life from a source other than combat damage this turn, you may return target card from a graveyard to the battlefield under your control. It gains lifelink and haste. Exile it at the beginning of the next end step or if it would leave the battlefield.");
- ability.addTarget(new TargetCardInGraveyard(new FilterCreatureCard()));
+ ability.addTarget(new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE));
this.addAbility(ability, new LifeLossOtherFromCombatWatcher());
}
diff --git a/Mage.Sets/src/mage/cards/s/SivvisRuse.java b/Mage.Sets/src/mage/cards/s/SivvisRuse.java
index 0ebc135c69e..c8d3b108abb 100644
--- a/Mage.Sets/src/mage/cards/s/SivvisRuse.java
+++ b/Mage.Sets/src/mage/cards/s/SivvisRuse.java
@@ -1,7 +1,5 @@
-
package mage.cards.s;
-import java.util.UUID;
import mage.abilities.condition.CompoundCondition;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.OpponentControlsPermanentCondition;
@@ -14,15 +12,16 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
-import mage.filter.common.FilterControlledCreatureInPlay;
+import mage.filter.StaticFilters;
import mage.filter.predicate.mageobject.SubtypePredicate;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class SivvisRuse extends CardImpl {
-
+
private static final FilterPermanent filterMountain = new FilterPermanent();
private static final FilterPermanent filterPlains = new FilterPermanent();
@@ -32,16 +31,16 @@ public final class SivvisRuse extends CardImpl {
}
public SivvisRuse(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{W}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}{W}");
// If an opponent controls a Mountain and you control a Plains, you may cast this spell without paying its mana cost.
Condition condition = new CompoundCondition("If an opponent controls a Mountain and you control a Plains",
new OpponentControlsPermanentCondition(filterMountain),
new PermanentsOnTheBattlefieldCondition(filterPlains));
this.addAbility(new AlternativeCostSourceAbility(null, condition));
-
+
// Prevent all damage that would be dealt this turn to creatures you control.
- this.getSpellAbility().addEffect(new PreventAllDamageToAllEffect(Duration.EndOfTurn, new FilterControlledCreatureInPlay()));
+ this.getSpellAbility().addEffect(new PreventAllDamageToAllEffect(Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURES_CONTROLLED));
}
public SivvisRuse(final SivvisRuse card) {
diff --git a/Mage.Sets/src/mage/cards/s/Skullcage.java b/Mage.Sets/src/mage/cards/s/Skullcage.java
index 6bd4825c45d..5d66345294f 100644
--- a/Mage.Sets/src/mage/cards/s/Skullcage.java
+++ b/Mage.Sets/src/mage/cards/s/Skullcage.java
@@ -23,7 +23,7 @@ public final class Skullcage extends CardImpl {
public Skullcage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
- // At the beginning of each opponent's upkeep, Skullcage deals 2 damage to that player unless he or she has exactly three or exactly four cards in hand.
+ // At the beginning of each opponent's upkeep, Skullcage deals 2 damage to that player unless they have exactly three or exactly four cards in hand.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SkullcageEffect(), TargetController.OPPONENT, false, true));
}
@@ -42,7 +42,7 @@ class SkullcageEffect extends OneShotEffect {
public SkullcageEffect() {
super(Outcome.Damage);
- staticText = "{source} deals 2 damage to that player unless he or she has exactly three or exactly four cards in hand";
+ staticText = "{source} deals 2 damage to that player unless they have exactly three or exactly four cards in hand";
}
public SkullcageEffect(final SkullcageEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/SkullknockerOgre.java b/Mage.Sets/src/mage/cards/s/SkullknockerOgre.java
new file mode 100644
index 00000000000..c4d453f514e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SkullknockerOgre.java
@@ -0,0 +1,72 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.DealsDamageToOpponentTriggeredAbility;
+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.game.Game;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SkullknockerOgre extends CardImpl {
+
+ public SkullknockerOgre(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
+
+ this.subtype.add(SubType.OGRE);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(3);
+
+ // Whenever Skullknocker Ogre deals damage to an opponent, that player discards a card at random. If the player does, they draw a card.
+ this.addAbility(new DealsDamageToOpponentTriggeredAbility(
+ new SkullknockerOgreEffect(), false, false, true
+ ));
+ }
+
+ private SkullknockerOgre(final SkullknockerOgre card) {
+ super(card);
+ }
+
+ @Override
+ public SkullknockerOgre copy() {
+ return new SkullknockerOgre(this);
+ }
+}
+
+class SkullknockerOgreEffect extends OneShotEffect {
+
+ SkullknockerOgreEffect() {
+ super(Outcome.Benefit);
+ staticText = "that player discards a card at random. If the player does, they draw a card";
+ }
+
+ private SkullknockerOgreEffect(final SkullknockerOgreEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public SkullknockerOgreEffect copy() {
+ return new SkullknockerOgreEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(this.getTargetPointer().getFirst(game, source));
+ if (player == null) {
+ return false;
+ }
+ if (player.discard(1, true, source, game).size() > 0) {
+ player.drawCards(1, game);
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/s/Skullscorch.java b/Mage.Sets/src/mage/cards/s/Skullscorch.java
index cbead17436d..e0ec2a6fef3 100644
--- a/Mage.Sets/src/mage/cards/s/Skullscorch.java
+++ b/Mage.Sets/src/mage/cards/s/Skullscorch.java
@@ -24,7 +24,7 @@ public final class Skullscorch extends CardImpl {
public Skullscorch(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{R}{R}");
- // Target player discards two cards at random unless that player has Skullscorch deal 4 damage to him or her.
+ // Target player discards two cards at random unless that player has Skullscorch deal 4 damage to them.
this.getSpellAbility().addEffect(new SkullscorchDiscardEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
}
@@ -43,7 +43,7 @@ class SkullscorchDiscardEffect extends OneShotEffect {
public SkullscorchDiscardEffect() {
super(Outcome.DrawCard);
- staticText = "Target player discards two cards at random unless that player has {source} deal 4 damage to him or her";
+ staticText = "Target player discards two cards at random unless that player has {source} deal 4 damage to them";
}
public SkullscorchDiscardEffect(final SkullscorchDiscardEffect effect) {
@@ -74,7 +74,7 @@ class SkullscorchDiscardEffect extends OneShotEffect {
if (player.chooseUse(Outcome.Detriment, "Have " + spell.getLogName() + " deal 4 damage to you?", source, game)){
discardCards = false;
player.damage(4, source.getSourceId(), game, false, true);
- game.informPlayers(player.getLogName() + " has " + spell.getLogName() + " deal 4 to him or her");
+ game.informPlayers(player.getLogName() + " has " + spell.getLogName() + " deal 4 to them");
}
if (discardCards) {
player.discard(2, true, source, game);
diff --git a/Mage.Sets/src/mage/cards/s/Skyreaping.java b/Mage.Sets/src/mage/cards/s/Skyreaping.java
index 4efbed09ad4..265fd933ada 100644
--- a/Mage.Sets/src/mage/cards/s/Skyreaping.java
+++ b/Mage.Sets/src/mage/cards/s/Skyreaping.java
@@ -1,7 +1,5 @@
-
package mage.cards.s;
-import java.util.UUID;
import mage.abilities.dynamicvalue.common.DevotionCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageAllEffect;
@@ -9,12 +7,12 @@ import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.ColoredManaSymbol;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class Skyreaping extends CardImpl {
@@ -26,13 +24,13 @@ public final class Skyreaping extends CardImpl {
}
public Skyreaping(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{G}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}");
// Skyreaping deals damage to each creature with flying equal to your devotion to green.
- Effect effect = new DamageAllEffect(new DevotionCount(ColoredManaSymbol.G), filter);
+ Effect effect = new DamageAllEffect(DevotionCount.G, filter);
effect.setText("{this} deals damage to each creature with flying equal to your devotion to green (Each {G} in the mana costs of permanents you control counts toward your devotion to green.)");
this.getSpellAbility().addEffect(effect);
+ this.getSpellAbility().addHint(DevotionCount.G.getHint());
}
public Skyreaping(final Skyreaping card) {
diff --git a/Mage.Sets/src/mage/cards/s/SkyshroudVampire.java b/Mage.Sets/src/mage/cards/s/SkyshroudVampire.java
index f91a0f87ee4..6d72660c82d 100644
--- a/Mage.Sets/src/mage/cards/s/SkyshroudVampire.java
+++ b/Mage.Sets/src/mage/cards/s/SkyshroudVampire.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -10,10 +9,10 @@ import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
+import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCardInHand;
/**
@@ -23,19 +22,19 @@ import mage.target.common.TargetCardInHand;
public final class SkyshroudVampire extends CardImpl {
public SkyshroudVampire(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
this.subtype.add(SubType.VAMPIRE);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Flying
this.addAbility(FlyingAbility.getInstance());
-
+
// Discard a creature card: Skyshroud Vampire gets +2/+2 until end of turn.
this.addAbility(new SimpleActivatedAbility(
- Zone.BATTLEFIELD,
- new BoostSourceEffect(2,2, Duration.EndOfTurn),
- new DiscardTargetCost(new TargetCardInHand(new FilterCreatureCard()))));
+ Zone.BATTLEFIELD,
+ new BoostSourceEffect(2, 2, Duration.EndOfTurn),
+ new DiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE))));
}
public SkyshroudVampire(final SkyshroudVampire card) {
diff --git a/Mage.Sets/src/mage/cards/s/SlaughterTheStrong.java b/Mage.Sets/src/mage/cards/s/SlaughterTheStrong.java
index 1765113460c..b54b294cd17 100644
--- a/Mage.Sets/src/mage/cards/s/SlaughterTheStrong.java
+++ b/Mage.Sets/src/mage/cards/s/SlaughterTheStrong.java
@@ -31,7 +31,7 @@ public final class SlaughterTheStrong extends CardImpl {
public SlaughterTheStrong(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{W}{W}");
- // Each player chooses any number of creatures he or she controls with total power 4 or less, then sacrifices all other creatures he or she controls.
+ // Each player chooses any number of creatures they control with total power 4 or less, then sacrifices all other creatures they control.
this.getSpellAbility().addEffect(new SlaughterTheStrongEffect());
}
@@ -49,7 +49,7 @@ class SlaughterTheStrongEffect extends OneShotEffect {
public SlaughterTheStrongEffect() {
super(Outcome.Benefit);
- this.staticText = "Each player chooses any number of creatures he or she controls with total power 4 or less, then sacrifices all other creatures he or she controls";
+ this.staticText = "Each player chooses any number of creatures they control with total power 4 or less, then sacrifices all other creatures they control";
}
public SlaughterTheStrongEffect(final SlaughterTheStrongEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/SlayerOfTheWicked.java b/Mage.Sets/src/mage/cards/s/SlayerOfTheWicked.java
index 8576ee07729..43eeb942389 100644
--- a/Mage.Sets/src/mage/cards/s/SlayerOfTheWicked.java
+++ b/Mage.Sets/src/mage/cards/s/SlayerOfTheWicked.java
@@ -27,7 +27,7 @@ public final class SlayerOfTheWicked extends CardImpl {
filter.add(Predicates.or(
new SubtypePredicate(SubType.VAMPIRE),
new SubtypePredicate(SubType.WEREWOLF),
- new SubtypePredicate(SubType.WEREWOLF)));
+ new SubtypePredicate(SubType.ZOMBIE)));
}
public SlayerOfTheWicked(UUID ownerId, CardSetInfo setInfo) {
diff --git a/Mage.Sets/src/mage/cards/s/SlayingFire.java b/Mage.Sets/src/mage/cards/s/SlayingFire.java
new file mode 100644
index 00000000000..45b715cb314
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SlayingFire.java
@@ -0,0 +1,42 @@
+package mage.cards.s;
+
+import mage.abilities.condition.common.AdamantCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.target.common.TargetAnyTarget;
+import mage.watchers.common.ManaSpentToCastWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SlayingFire extends CardImpl {
+
+ public SlayingFire(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}");
+
+ // Slaying Fire deals 3 damage to any target.
+ // Adamant — If at least three red mana was spent to cast this spell, it deals 4 damage instead.
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new DamageTargetEffect(4), new DamageTargetEffect(3),
+ AdamantCondition.RED, "{this} deals 3 damage to any target." +
+ "
Adamant — If at least three red mana was spent to cast this spell, " +
+ "it deals 4 damage instead."
+ ));
+ this.getSpellAbility().addTarget(new TargetAnyTarget());
+ this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher());
+ }
+
+ private SlayingFire(final SlayingFire card) {
+ super(card);
+ }
+
+ @Override
+ public SlayingFire copy() {
+ return new SlayingFire(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SlowMotion.java b/Mage.Sets/src/mage/cards/s/SlowMotion.java
index 89369f30052..adfd520219b 100644
--- a/Mage.Sets/src/mage/cards/s/SlowMotion.java
+++ b/Mage.Sets/src/mage/cards/s/SlowMotion.java
@@ -40,7 +40,7 @@ public final class SlowMotion extends CardImpl {
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
- // At the beginning of the upkeep of enchanted creature's controller, that player sacrifices that creature unless he or she pays {2}.
+ // At the beginning of the upkeep of enchanted creature's controller, that player sacrifices that creature unless they pay {2}.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeEquipedUnlessPaysEffect(new GenericManaCost(2)), TargetController.CONTROLLER_ATTACHED_TO, false));
// When Slow Motion is put into a graveyard from the battlefield, return Slow Motion to its owner's hand.
@@ -64,7 +64,7 @@ class SacrificeEquipedUnlessPaysEffect extends OneShotEffect {
public SacrificeEquipedUnlessPaysEffect(Cost cost) {
super(Outcome.Sacrifice);
this.cost = cost;
- staticText = "that player sacrifices that creature unless he or she pays {2}";
+ staticText = "that player sacrifices that creature unless they pay {2}";
}
public SacrificeEquipedUnlessPaysEffect(final SacrificeEquipedUnlessPaysEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/SmittenSwordmaster.java b/Mage.Sets/src/mage/cards/s/SmittenSwordmaster.java
new file mode 100644
index 00000000000..673f947b493
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SmittenSwordmaster.java
@@ -0,0 +1,77 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.effects.common.LoseLifeOpponentsEffect;
+import mage.abilities.keyword.LifelinkAbility;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.game.Game;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SmittenSwordmaster extends AdventureCard {
+
+ public SmittenSwordmaster(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{1}{B}", "Curry Favor", "{B}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(1);
+
+ // Lifelink
+ this.addAbility(LifelinkAbility.getInstance());
+
+ // Curry Favor
+ // You gain X life and each opponent loses X life, where X is the number of Knights you control.
+ this.getSpellCard().getSpellAbility().addEffect(new CurryFavorEffect());
+ }
+
+ private SmittenSwordmaster(final SmittenSwordmaster card) {
+ super(card);
+ }
+
+ @Override
+ public SmittenSwordmaster copy() {
+ return new SmittenSwordmaster(this);
+ }
+}
+
+class CurryFavorEffect extends OneShotEffect {
+
+ CurryFavorEffect() {
+ super(Outcome.Benefit);
+ staticText = "you gain X life and each opponent loses X life, where X is the number of Knights you control";
+ }
+
+ private CurryFavorEffect(final CurryFavorEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CurryFavorEffect copy() {
+ return new CurryFavorEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ int xValue = game.getBattlefield()
+ .getAllActivePermanents(source.getControllerId())
+ .stream()
+ .filter(permanent -> permanent != null && permanent.hasSubtype(SubType.KNIGHT, game))
+ .mapToInt(p -> 1)
+ .sum();
+ new GainLifeEffect(xValue).apply(game, source);
+ new LoseLifeOpponentsEffect(xValue).apply(game, source);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/s/Snarespinner.java b/Mage.Sets/src/mage/cards/s/Snarespinner.java
index d738467dd8e..86708a456e8 100644
--- a/Mage.Sets/src/mage/cards/s/Snarespinner.java
+++ b/Mage.Sets/src/mage/cards/s/Snarespinner.java
@@ -68,7 +68,7 @@ class SnarespinnerTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
- return "Whenever {this} blocks a creature with flying, {} gets +2/+0 until end of turn";
+ return "Whenever {this} blocks a creature with flying, {this} gets +2/+0 until end of turn";
}
@Override
diff --git a/Mage.Sets/src/mage/cards/s/SneakAttack.java b/Mage.Sets/src/mage/cards/s/SneakAttack.java
index c9433fd907d..9d0d7508186 100644
--- a/Mage.Sets/src/mage/cards/s/SneakAttack.java
+++ b/Mage.Sets/src/mage/cards/s/SneakAttack.java
@@ -1,9 +1,6 @@
-
package mage.cards.s;
-import java.util.UUID;
import mage.abilities.Ability;
-import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
@@ -19,27 +16,28 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInHand;
import mage.target.targetpointer.FixedTarget;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class SneakAttack extends CardImpl {
public SneakAttack(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
// {R}: You may put a creature card from your hand onto the battlefield. That creature gains haste. Sacrifice the creature at the beginning of the next end step.
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new SneakAttackEffect(), new ManaCostsImpl("{R}")));
+ this.addAbility(new SimpleActivatedAbility(new SneakAttackEffect(), new ManaCostsImpl("{R}")));
}
- public SneakAttack(final SneakAttack card) {
+ private SneakAttack(final SneakAttack card) {
super(card);
}
@@ -53,12 +51,13 @@ class SneakAttackEffect extends OneShotEffect {
private static final String choiceText = "Put a creature card from your hand onto the battlefield?";
- public SneakAttackEffect() {
+ SneakAttackEffect() {
super(Outcome.Benefit);
- this.staticText = "You may put a creature card from your hand onto the battlefield. That creature gains haste. Sacrifice the creature at the beginning of the next end step";
+ this.staticText = "You may put a creature card from your hand onto the battlefield. " +
+ "That creature gains haste. Sacrifice the creature at the beginning of the next end step";
}
- public SneakAttackEffect(final SneakAttackEffect effect) {
+ private SneakAttackEffect(final SneakAttackEffect effect) {
super(effect);
}
@@ -70,32 +69,31 @@ class SneakAttackEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- if (controller.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) {
- TargetCardInHand target = new TargetCardInHand(new FilterCreatureCard());
- if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) {
- Card card = game.getCard(target.getFirstTarget());
- if (card != null) {
- if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
- Permanent permanent = game.getPermanent(card.getId());
- if (permanent != null) {
- ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom);
- effect.setTargetPointer(new FixedTarget(permanent, game));
- game.addEffect(effect, source);
-
- SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("sacrifice " + card.getName(), source.getControllerId());
- sacrificeEffect.setTargetPointer(new FixedTarget(permanent, game));
- DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
- game.addDelayedTriggeredAbility(delayedAbility, source);
- }
- return true;
- }
- }
- return false;
- }
- }
+ if (controller == null || !controller.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) {
return true;
}
- return false;
+ TargetCardInHand target = new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE);
+ if (!controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) {
+ return true;
+ }
+ Card card = game.getCard(target.getFirstTarget());
+ if (card == null || !controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
+ return false;
+ }
+ Permanent permanent = game.getPermanent(card.getId());
+ if (permanent == null) {
+ return true;
+ }
+ ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom);
+ effect.setTargetPointer(new FixedTarget(permanent, game));
+ game.addEffect(effect, source);
+
+ game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
+ new SacrificeTargetEffect(
+ "sacrifice " + card.getName(),
+ source.getControllerId()
+ ).setTargetPointer(new FixedTarget(permanent, game))
+ ), source);
+ return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/s/Snowblind.java b/Mage.Sets/src/mage/cards/s/Snowblind.java
new file mode 100644
index 00000000000..ee0d0551766
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/Snowblind.java
@@ -0,0 +1,103 @@
+package mage.cards.s;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterLandPermanent;
+import mage.filter.predicate.mageobject.SupertypePredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class Snowblind extends CardImpl {
+
+ public Snowblind(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));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // Enchanted creature gets -X/-Y. If that creature is attacking, X is the number of snow lands defending player controls. Otherwise, X is the number of snow lands its controller controls. Y is equal to X or to enchanted creature's toughness minus 1, whichever is smaller.
+ this.addAbility(new SimpleStaticAbility(new BoostEnchantedEffect(
+ SnowblindValue.instanceX, SnowblindValue.instanceY, Duration.WhileOnBattlefield
+ ).setText("Enchanted creature gets -X/-Y. If that creature is attacking, " +
+ "X is the number of snow lands defending player controls. " +
+ "Otherwise, X is the number of snow lands its controller controls. " +
+ "Y is equal to X or to enchanted creature's toughness minus 1, whichever is smaller."
+ )));
+ }
+
+ private Snowblind(final Snowblind card) {
+ super(card);
+ }
+
+ @Override
+ public Snowblind copy() {
+ return new Snowblind(this);
+ }
+}
+
+enum SnowblindValue implements DynamicValue {
+ instanceX,
+ instanceY;
+
+ private static final FilterPermanent filter = new FilterLandPermanent();
+
+ static {
+ filter.add(new SupertypePredicate(SuperType.SNOW));
+ }
+
+ @Override
+ public int calculate(Game game, Ability sourceAbility, Effect effect) {
+ Permanent sourcePerm = game.getPermanent(sourceAbility.getSourceId());
+ if (sourcePerm == null) {
+ return 0;
+ }
+ Permanent permanent = game.getPermanent(sourcePerm.getAttachedTo());
+ if (permanent == null) {
+ return 0;
+ }
+ int xValue = 0;
+ if (permanent.isAttacking()) {
+ xValue = game.getBattlefield().countAll(
+ filter, game.getCombat().getDefendingPlayerId(permanent.getId(), game), game
+ );
+ } else {
+ xValue = game.getBattlefield().countAll(filter, permanent.getControllerId(), game);
+ }
+ if (this == instanceX) {
+ return -xValue;
+ }
+ return -Math.min(xValue, permanent.getToughness().getValue() - 1);
+ }
+
+ @Override
+ public DynamicValue copy() {
+ return this;
+ }
+
+ @Override
+ public String getMessage() {
+ return "";
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/s/SoTiny.java b/Mage.Sets/src/mage/cards/s/SoTiny.java
new file mode 100644
index 00000000000..6b41d69da82
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SoTiny.java
@@ -0,0 +1,88 @@
+package mage.cards.s;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.StaticValue;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.abilities.keyword.FlashAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SoTiny extends CardImpl {
+
+ public SoTiny(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}");
+
+ 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));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // Enchanted creature gets -2/-0. It gets -6/-0 instead as long as its controller has seven or more cards in their graveyard.
+ this.addAbility(new SimpleStaticAbility(
+ new BoostEnchantedEffect(SoTinyValue.instance, StaticValue.getZeroValue())
+ .setText("enchanted creature gets -2/-0. It gets -6/-0 instead as long as " +
+ "its controller has seven or more cards in their graveyard")
+ ));
+ }
+
+ private SoTiny(final SoTiny card) {
+ super(card);
+ }
+
+ @Override
+ public SoTiny copy() {
+ return new SoTiny(this);
+ }
+}
+
+enum SoTinyValue implements DynamicValue {
+ instance;
+
+ @Override
+ public int calculate(Game game, Ability sourceAbility, Effect effect) {
+ Permanent permanent = game.getPermanent(sourceAbility.getSourceId());
+ if (permanent == null) {
+ return -2;
+ }
+ Player player = game.getPlayer(game.getControllerId(permanent.getAttachedTo()));
+ if (player == null || player.getGraveyard().size() < 7) {
+ return -2;
+ }
+ return -6;
+ }
+
+ @Override
+ public DynamicValue copy() {
+ return instance;
+ }
+
+ @Override
+ public String getMessage() {
+ return "";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SongOfBlood.java b/Mage.Sets/src/mage/cards/s/SongOfBlood.java
index a22893a6cba..d786f476dda 100644
--- a/Mage.Sets/src/mage/cards/s/SongOfBlood.java
+++ b/Mage.Sets/src/mage/cards/s/SongOfBlood.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.Set;
@@ -17,7 +16,7 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
@@ -76,7 +75,7 @@ class SongOfBloodEffect extends OneShotEffect {
Set movedCards = controller.moveCardsToGraveyardWithInfo(cardsToGraveyard.getCards(game), source, game, Zone.LIBRARY);
Cards cardsMoved = new CardsImpl();
cardsMoved.addAll(movedCards);
- int creatures = cardsMoved.count(new FilterCreatureCard(), game);
+ int creatures = cardsMoved.count(StaticFilters.FILTER_CARD_CREATURE, game);
if (creatures > 0) {
// Setup a delayed trigger to give +X/+0 to any creature attacking this turn..
DelayedTriggeredAbility delayedAbility = new SongOfBloodTriggeredAbility(creatures);
diff --git a/Mage.Sets/src/mage/cards/s/SongsOfTheDamned.java b/Mage.Sets/src/mage/cards/s/SongsOfTheDamned.java
index aef71cf0bca..1ed0a99acba 100644
--- a/Mage.Sets/src/mage/cards/s/SongsOfTheDamned.java
+++ b/Mage.Sets/src/mage/cards/s/SongsOfTheDamned.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -8,7 +7,7 @@ import mage.abilities.effects.mana.DynamicManaEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -17,10 +16,10 @@ import mage.filter.common.FilterCreatureCard;
public final class SongsOfTheDamned extends CardImpl {
public SongsOfTheDamned(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}");
// Add {B} for each creature card in your graveyard.
- DynamicManaEffect effect = new DynamicManaEffect(Mana.BlackMana(1), new CardsInControllerGraveyardCount(new FilterCreatureCard()));
+ DynamicManaEffect effect = new DynamicManaEffect(Mana.BlackMana(1), new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE));
this.getSpellAbility().addEffect(effect);
}
diff --git a/Mage.Sets/src/mage/cards/s/SorcerersBroom.java b/Mage.Sets/src/mage/cards/s/SorcerersBroom.java
new file mode 100644
index 00000000000..393347aafb3
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SorcerersBroom.java
@@ -0,0 +1,75 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.CreateTokenCopySourceEffect;
+import mage.abilities.effects.common.DoIfCostPaid;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SorcerersBroom extends CardImpl {
+
+ public SorcerersBroom(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}");
+
+ this.subtype.add(SubType.SPIRIT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(1);
+
+ // Whenever you sacrifice another permanent, you may pay {3}. If you do, create a token that's a copy of Sorcerer's Broom.
+ this.addAbility(new SorcerersBroomTriggeredAbility());
+ }
+
+ private SorcerersBroom(final SorcerersBroom card) {
+ super(card);
+ }
+
+ @Override
+ public SorcerersBroom copy() {
+ return new SorcerersBroom(this);
+ }
+}
+
+class SorcerersBroomTriggeredAbility extends TriggeredAbilityImpl {
+
+ SorcerersBroomTriggeredAbility() {
+ super(Zone.BATTLEFIELD, new DoIfCostPaid(new CreateTokenCopySourceEffect(), new GenericManaCost(3)));
+ }
+
+ private SorcerersBroomTriggeredAbility(final SorcerersBroomTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public SorcerersBroomTriggeredAbility copy() {
+ return new SorcerersBroomTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ return event.getPlayerId().equals(this.getControllerId())
+ && !event.getTargetId().equals(sourceId);
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever you sacrifice another permanent, you may pay {3}. " +
+ "If you do, create a token that's a copy of {this}";
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/s/SoulBarrier.java b/Mage.Sets/src/mage/cards/s/SoulBarrier.java
index 928a1ef8bb7..7b96f221c0a 100644
--- a/Mage.Sets/src/mage/cards/s/SoulBarrier.java
+++ b/Mage.Sets/src/mage/cards/s/SoulBarrier.java
@@ -26,7 +26,7 @@ public final class SoulBarrier extends CardImpl {
public SoulBarrier(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
- // Whenever an opponent casts a creature spell, Soul Barrier deals 2 damage to that player unless he or she pays {2}.
+ // Whenever an opponent casts a creature spell, Soul Barrier deals 2 damage to that player unless they pay {2}.
this.addAbility(new SpellCastOpponentTriggeredAbility(Zone.BATTLEFIELD, new SoulBarrierEffect(),
StaticFilters.FILTER_SPELL_A_CREATURE, false, SetTargetPointer.PLAYER));
}
@@ -45,7 +45,7 @@ class SoulBarrierEffect extends OneShotEffect {
SoulBarrierEffect() {
super(Outcome.Damage);
- this.staticText = "{this} deals 2 damage to that player unless he or she pays {2}";
+ this.staticText = "{this} deals 2 damage to that player unless they pay {2}";
}
SoulBarrierEffect(final SoulBarrierEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/SoulCharmer.java b/Mage.Sets/src/mage/cards/s/SoulCharmer.java
index f4340976783..b386cefc725 100644
--- a/Mage.Sets/src/mage/cards/s/SoulCharmer.java
+++ b/Mage.Sets/src/mage/cards/s/SoulCharmer.java
@@ -25,7 +25,7 @@ public final class SoulCharmer extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- // Whenever Soul Charmer deals combat damage to a creature, you gain 2 life unless he or she pays {2}.
+ // Whenever Soul Charmer deals combat damage to a creature, you gain 2 life unless they pay {2}.
this.addAbility(new DealsCombatDamageToACreatureTriggeredAbility(new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new GainLifeEffect(2), new ManaCostsImpl("{2}")), false, true));
}
diff --git a/Mage.Sets/src/mage/cards/s/SoulScourge.java b/Mage.Sets/src/mage/cards/s/SoulScourge.java
index 267b570c2a1..a8323edeca2 100644
--- a/Mage.Sets/src/mage/cards/s/SoulScourge.java
+++ b/Mage.Sets/src/mage/cards/s/SoulScourge.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -6,7 +5,6 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
-import mage.abilities.costs.AdjustingSourceCosts;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.GainLifeTargetEffect;
import mage.abilities.effects.common.LoseLifeTargetEffect;
@@ -29,7 +27,7 @@ import mage.util.CardUtil;
public final class SoulScourge extends CardImpl {
public SoulScourge(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
this.subtype.add(SubType.NIGHTMARE);
this.subtype.add(SubType.HORROR);
@@ -40,7 +38,7 @@ public final class SoulScourge extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// When Soul Scourge enters the battlefield, target player loses 3 life.
- Ability ability = new SoulScourgeEntersBattlefieldTriggeredAbility();
+ Ability ability = new SoulScourgeEntersBattlefieldTriggeredAbility(new LoseLifeTargetEffect(3));
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
// When Soul Scourge leaves the battlefield, that player gains 3 life.
@@ -57,29 +55,33 @@ public final class SoulScourge extends CardImpl {
}
}
-class SoulScourgeEntersBattlefieldTriggeredAbility extends EntersBattlefieldTriggeredAbility implements AdjustingSourceCosts {
+class SoulScourgeEntersBattlefieldTriggeredAbility extends EntersBattlefieldTriggeredAbility {
- public SoulScourgeEntersBattlefieldTriggeredAbility() {
- super(new LoseLifeTargetEffect(3), false);
+ public SoulScourgeEntersBattlefieldTriggeredAbility(Effect effect) {
+ super(effect, false);
}
- public SoulScourgeEntersBattlefieldTriggeredAbility(SoulScourgeEntersBattlefieldTriggeredAbility ability) {
+ public SoulScourgeEntersBattlefieldTriggeredAbility(final SoulScourgeEntersBattlefieldTriggeredAbility ability) {
super(ability);
}
+ @Override
+ public boolean activate(Game game, boolean noMana) {
+ if (super.activate(game, noMana)) {
+ Player player = game.getPlayer(getFirstTarget());
+ if (player != null) {
+ String key = CardUtil.getCardZoneString("targetPlayer", getSourceId(), game);
+ game.getState().setValue(key, player.getId());
+ }
+ return true;
+ }
+ return false;
+ }
+
@Override
public SoulScourgeEntersBattlefieldTriggeredAbility copy() {
return new SoulScourgeEntersBattlefieldTriggeredAbility(this);
}
-
- @Override
- public void adjustCosts(Ability ability, Game game) {
- Player player = game.getPlayer(ability.getFirstTarget());
- if (player != null) {
- String key = CardUtil.getCardZoneString("targetPlayer", this.getSourceId(), game);
- game.getState().setValue(key, player.getId());
- }
- }
}
class SoulScourgeLeavesBattlefieldTriggeredAbility extends LeavesBattlefieldTriggeredAbility {
diff --git a/Mage.Sets/src/mage/cards/s/SoulTithe.java b/Mage.Sets/src/mage/cards/s/SoulTithe.java
index abe0b987b39..89b360a4f57 100644
--- a/Mage.Sets/src/mage/cards/s/SoulTithe.java
+++ b/Mage.Sets/src/mage/cards/s/SoulTithe.java
@@ -26,7 +26,7 @@ import java.util.UUID;
*/
public final class SoulTithe extends CardImpl {
- static final String rule = "At the beginning of the upkeep of enchanted permanent's controller, that player sacrifices it unless he or she pays {X}, where X is its converted mana cost";
+ static final String rule = "At the beginning of the upkeep of enchanted permanent's controller, that player sacrifices it unless they pay {X}, where X is its converted mana cost";
public SoulTithe(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
@@ -40,7 +40,7 @@ public final class SoulTithe extends CardImpl {
this.addAbility(ability);
// At the beginning of the upkeep of enchanted permanent's controller,
- // that player sacrifices it unless he or she pays {X},
+ // that player sacrifices it unless they pay {X},
// where X is its converted mana cost.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SoulTitheEffect(), TargetController.CONTROLLER_ATTACHED_TO, false));
}
@@ -59,7 +59,7 @@ class SoulTitheEffect extends OneShotEffect {
public SoulTitheEffect() {
super(Outcome.Sacrifice);
- staticText = "that player sacrifices it unless he or she pays {X}, where X is its converted mana cost";
+ staticText = "that player sacrifices it unless they pay {X}, where X is its converted mana cost";
}
public SoulTitheEffect(final SoulTitheEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/Soulherder.java b/Mage.Sets/src/mage/cards/s/Soulherder.java
index 263649e04ce..00549d649df 100644
--- a/Mage.Sets/src/mage/cards/s/Soulherder.java
+++ b/Mage.Sets/src/mage/cards/s/Soulherder.java
@@ -1,5 +1,6 @@
package mage.cards.s;
+import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
@@ -14,7 +15,6 @@ import mage.constants.SubType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
-import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.game.Game;
@@ -23,8 +23,6 @@ import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
-import java.util.UUID;
-
/**
* @author TheElk801
*/
@@ -51,7 +49,7 @@ public final class Soulherder extends CardImpl {
Ability ability = new BeginningOfEndStepTriggeredAbility(
new ExileTargetForSourceEffect(), TargetController.YOU, true
);
- ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect().concatBy("then"));
+ ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, true).concatBy("then"));
ability.addTarget(new TargetControlledCreaturePermanent(filter));
this.addAbility(ability);
}
@@ -69,8 +67,8 @@ public final class Soulherder extends CardImpl {
class SoulherderTriggeredAbility extends ZoneChangeTriggeredAbility {
SoulherderTriggeredAbility() {
- super(
- Zone.BATTLEFIELD, Zone.BATTLEFIELD, Zone.EXILED,
+ super(Zone.BATTLEFIELD,
+ Zone.BATTLEFIELD, Zone.EXILED,
new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
"Whenever a creature is exiled from the battlefield, ", false
);
@@ -91,8 +89,9 @@ class SoulherderTriggeredAbility extends ZoneChangeTriggeredAbility {
if (permanent != null && permanent.isCreature()) {
// custom check cause ZoneChangeTriggeredAbility for source object only
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
- return (fromZone == null || zEvent.getFromZone() == fromZone) && (toZone == null || zEvent.getToZone() == toZone);
+ return (fromZone == null || zEvent.getFromZone() == fromZone)
+ && (zEvent.getToZone() == toZone || zEvent.getOriginalToZone() == toZone);
}
return false;
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/s/SparkDouble.java b/Mage.Sets/src/mage/cards/s/SparkDouble.java
index b036665e2fe..f83a6026202 100644
--- a/Mage.Sets/src/mage/cards/s/SparkDouble.java
+++ b/Mage.Sets/src/mage/cards/s/SparkDouble.java
@@ -6,6 +6,7 @@ import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CopyPermanentEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -71,12 +72,16 @@ class SparkDoubleExceptEffectsApplyerToPermanent extends ApplyToPermanent {
@Override
public boolean apply(Game game, MageObject copyFromBlueprint, Ability source, UUID copyToObjectId) {
- Permanent destCard = game.getPermanentEntering(copyToObjectId);
- if (destCard == null) {
- return false;
- }
+ // copyToObjectId can be new token outside from game, don't use it
// it isn’t legendary if that permanent is legendary
+ //
+ // Spark Double isn’t legendary if it copies a legendary permanent, and this exception is copiable. If something
+ // else copies Spark Double later, that copy also won’t be legendary. If you control two or more permanents
+ // with the same name but only one is legendary, the “legend rule” doesn’t apply.
+ // (2019-05-03)
+ //
+ // So, it's must make changes in blueprint (for farther copyable)
copyFromBlueprint.getSuperType().remove(SuperType.LEGENDARY);
// TODO: Blood Moon problem, can't apply on type changing effects (same as TeferisTimeTwist)
@@ -89,14 +94,17 @@ class SparkDoubleExceptEffectsApplyerToPermanent extends ApplyToPermanent {
// doesn't get a +1/+1 counter. On the other hand, if Spark Double copies Gideon Blackblade during your turn,
// Spark Double enters as a planeswalker creature and gets both kinds of counters.
- // enters with an additional +1/+1 counter on it if it’s a creature
- if (copyFromBlueprint.isCreature()) {
- destCard.addCounters(CounterType.P1P1.createInstance(), source, game);
- }
+ // counters only for original card, not copies
+ if (!isCopyOfCopy(source, copyToObjectId)) {
+ // enters with an additional +1/+1 counter on it if it’s a creature
+ if (copyFromBlueprint.isCreature()) {
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance(), false).apply(game, source);
+ }
- // enters with an additional loyalty counter on it if it’s a planeswalker
- if (copyFromBlueprint.isPlaneswalker()) {
- destCard.addCounters(CounterType.LOYALTY.createInstance(), source, game);
+ // enters with an additional loyalty counter on it if it’s a planeswalker
+ if (copyFromBlueprint.isPlaneswalker()) {
+ new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(), false).apply(game, source);
+ }
}
return true;
diff --git a/Mage.Sets/src/mage/cards/s/SpectersShriek.java b/Mage.Sets/src/mage/cards/s/SpectersShriek.java
new file mode 100644
index 00000000000..0a5a41119e7
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SpectersShriek.java
@@ -0,0 +1,94 @@
+package mage.cards.s;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.filter.FilterCard;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.TargetCard;
+import mage.target.common.TargetCardInHand;
+import mage.target.common.TargetOpponent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SpectersShriek extends CardImpl {
+
+ public SpectersShriek(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}");
+
+ // Target opponent reveals their hand. You may choose a nonland card from it. If you do, that player exiles that card. If a nonblack card is exiled this way, exile a card from your hand.
+ this.getSpellAbility().addEffect(new SpectersShriekEffect());
+ this.getSpellAbility().addTarget(new TargetOpponent());
+ }
+
+ private SpectersShriek(final SpectersShriek card) {
+ super(card);
+ }
+
+ @Override
+ public SpectersShriek copy() {
+ return new SpectersShriek(this);
+ }
+}
+
+class SpectersShriekEffect extends OneShotEffect {
+
+ private static final FilterCard filter = new FilterCard("card in your hand (to exile)");
+
+ SpectersShriekEffect() {
+ super(Outcome.Benefit);
+ staticText = "Target opponent reveals their hand. You may choose a nonland card from it. If you do, " +
+ "that player exiles that card. If a nonblack card is exiled this way, exile a card from your hand.";
+ }
+
+ private SpectersShriekEffect(final SpectersShriekEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public SpectersShriekEffect copy() {
+ return new SpectersShriekEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Player player = game.getPlayer(source.getFirstTarget());
+ if (controller == null || player == null) {
+ return false;
+ }
+ player.revealCards(source, player.getHand(), game);
+ if (player.getHand().count(StaticFilters.FILTER_CARD_NON_LAND, game) == 0
+ || !controller.chooseUse(outcome, "Exile a card from " + player.getName() + "'s hand?", source, game)) {
+ return true;
+ }
+ TargetCard target = new TargetCardInHand(StaticFilters.FILTER_CARD_NON_LAND);
+ target.setNotTarget(true);
+ if (!controller.choose(outcome, player.getHand(), target, game)) {
+ return false;
+ }
+ Card card = game.getCard(target.getFirstTarget());
+ if (card == null) {
+ return false;
+ }
+ boolean isBlack = card.getColor(game).isBlack();
+ player.moveCards(card, Zone.EXILED, source, game);
+ if (isBlack || controller.getHand().isEmpty()) {
+ return true;
+ }
+ target = new TargetCardInHand(filter);
+ target.setNotTarget(true);
+ return controller.choose(outcome, controller.getHand(), target, game)
+ && controller.moveCards(game.getCard(target.getFirstTarget()), Zone.EXILED, source, game);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/s/Spellbinder.java b/Mage.Sets/src/mage/cards/s/Spellbinder.java
index bdedc54d136..082b6098bc4 100644
--- a/Mage.Sets/src/mage/cards/s/Spellbinder.java
+++ b/Mage.Sets/src/mage/cards/s/Spellbinder.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -38,10 +37,13 @@ public final class Spellbinder extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
this.subtype.add(SubType.EQUIPMENT);
- // Imprint - When Spellbinder enters the battlefield, you may exile an instant card from your hand.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new SpellbinderImprintEffect(), true, "Imprint — "));
+ // Imprint - When Spellbinder enters the battlefield, you may exile
+ // an instant card from your hand.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(
+ new SpellbinderImprintEffect(), true, "Imprint — "));
- // Whenever equipped creature deals combat damage to a player, you may copy the exiled card. If you do, you may cast the copy without paying its mana cost.
+ // Whenever equipped creature deals combat damage to a player, you may
+ // copy the exiled card. If you do, you may cast the copy without paying its mana cost.
this.addAbility(new SpellbinderTriggeredAbility());
// Equip {4}
@@ -82,12 +84,16 @@ class SpellbinderTriggeredAbility extends TriggeredAbilityImpl {
public boolean checkTrigger(GameEvent event, Game game) {
DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event;
Permanent p = game.getPermanent(event.getSourceId());
- return damageEvent.isCombatDamage() && p != null && p.getAttachments().contains(this.getSourceId());
+ return damageEvent.isCombatDamage()
+ && p != null
+ && p.getAttachments().contains(this.getSourceId());
}
@Override
public String getRule() {
- return "Whenever equipped creature deals combat damage to a player, you may copy the exiled card. If you do, you may cast the copy without paying its mana cost.";
+ return "Whenever equipped creature deals combat damage to a player, "
+ + "you may copy the exiled card. If you do, you may cast "
+ + "the copy without paying its mana cost.";
}
}
@@ -119,11 +125,13 @@ class SpellbinderImprintEffect extends OneShotEffect {
&& controller.choose(Outcome.Benefit, controller.getHand(), target, game)) {
Card card = controller.getHand().get(target.getFirstTarget(), game);
if (card != null) {
- controller.moveCardToExileWithInfo(card, source.getSourceId(), sourcePermanent.getIdName() + " (Imprint)", source.getSourceId(), game, Zone.HAND, true);
+ controller.moveCardToExileWithInfo(card, source.getSourceId(),
+ sourcePermanent.getIdName() + " (Imprint)", source.getSourceId(), game, Zone.HAND, true);
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
permanent.imprint(card.getId(), game);
- permanent.addInfo("imprint", CardUtil.addToolTipMarkTags("[Imprinted card - " + card.getLogName() + ']'), game);
+ permanent.addInfo("imprint", CardUtil.addToolTipMarkTags("[Imprinted card - "
+ + card.getLogName() + ']'), game);
}
}
}
@@ -145,7 +153,8 @@ class SpellbinderCopyEffect extends OneShotEffect {
public SpellbinderCopyEffect() {
super(Outcome.Copy);
- this.staticText = "You may copy the exiled card. If you do, you may cast the copy without paying its mana cost";
+ this.staticText = "You may copy the exiled card. If you do, "
+ + "you may cast the copy without paying its mana cost";
}
public SpellbinderCopyEffect(final SpellbinderCopyEffect effect) {
@@ -172,9 +181,13 @@ class SpellbinderCopyEffect extends OneShotEffect {
game.getState().setZone(copiedCard.getId(), Zone.EXILED);
if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
if (copiedCard.getSpellAbility() != null) {
- controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(copiedCard, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), null);
} else {
- Logger.getLogger(SpellbinderCopyEffect.class).error("Spellbinder: spell ability == null " + copiedCard.getName());
+ Logger.getLogger(SpellbinderCopyEffect.class).error(
+ "Spellbinder: spell ability == null " + copiedCard.getName());
}
}
}
diff --git a/Mage.Sets/src/mage/cards/s/Spellshift.java b/Mage.Sets/src/mage/cards/s/Spellshift.java
index a54d455aa25..686b5920930 100644
--- a/Mage.Sets/src/mage/cards/s/Spellshift.java
+++ b/Mage.Sets/src/mage/cards/s/Spellshift.java
@@ -33,7 +33,7 @@ public final class Spellshift extends CardImpl {
this.getSpellAbility().addTarget(new TargetSpell(new FilterInstantOrSorcerySpell()));
this.getSpellAbility().addEffect(new CounterTargetEffect());
- // Its controller reveals cards from the top of their library until he or she reveals an instant or sorcery card. That player may cast that card without paying its mana cost. Then he or she shuffles their library.
+ // Its controller reveals cards from the top of their library until they reveal an instant or sorcery card. That player may cast that card without paying its mana cost. Then they shuffle their library.
this.getSpellAbility().addEffect(new SpellshiftEffect());
}
@@ -51,7 +51,7 @@ class SpellshiftEffect extends OneShotEffect {
public SpellshiftEffect() {
super(Outcome.Detriment);
- this.staticText = "Its controller reveals cards from the top of their library until he or she reveals an instant or sorcery card. That player may cast that card without paying its mana cost. Then he or she shuffles their library";
+ this.staticText = "Its controller reveals cards from the top of their library until they reveal an instant or sorcery card. That player may cast that card without paying its mana cost. Then they shuffle their library";
}
public SpellshiftEffect(final SpellshiftEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/SpelltitheEnforcer.java b/Mage.Sets/src/mage/cards/s/SpelltitheEnforcer.java
index 49195846a12..020cf588cf5 100644
--- a/Mage.Sets/src/mage/cards/s/SpelltitheEnforcer.java
+++ b/Mage.Sets/src/mage/cards/s/SpelltitheEnforcer.java
@@ -31,7 +31,7 @@ public final class SpelltitheEnforcer extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(3);
- // Whenever an opponent casts a spell, that player sacrifices a permanent unless he or she pays {1}.
+ // Whenever an opponent casts a spell, that player sacrifices a permanent unless they pay {1}.
this.addAbility(new SpellCastOpponentTriggeredAbility(
Zone.BATTLEFIELD,
new SpelltitheEnforcerEffect(),
@@ -55,7 +55,7 @@ class SpelltitheEnforcerEffect extends SacrificeEffect {
SpelltitheEnforcerEffect() {
super(new FilterPermanent("permanent to sacrifice"), 1, "that player");
- this.staticText = "that player sacrifices a permanent unless he or she pays {1}";
+ this.staticText = "that player sacrifices a permanent unless they pay {1}";
}
SpelltitheEnforcerEffect(final SpelltitheEnforcerEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/Spelltwine.java b/Mage.Sets/src/mage/cards/s/Spelltwine.java
index 44d0b3fc1dd..35eea48c864 100644
--- a/Mage.Sets/src/mage/cards/s/Spelltwine.java
+++ b/Mage.Sets/src/mage/cards/s/Spelltwine.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -26,8 +25,10 @@ import mage.target.common.TargetCardInYourGraveyard;
*/
public final class Spelltwine extends CardImpl {
- private static final FilterCard filter = new FilterCard("instant or sorcery card from your graveyard");
- private static final FilterCard filter2 = new FilterCard("instant or sorcery card from an opponent's graveyard");
+ private static final FilterCard filter = new FilterCard(
+ "instant or sorcery card from your graveyard");
+ private static final FilterCard filter2 = new FilterCard(
+ "instant or sorcery card from an opponent's graveyard");
static {
filter.add(Predicates.or(
@@ -42,7 +43,9 @@ public final class Spelltwine extends CardImpl {
public Spelltwine(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{U}");
- // Exile target instant or sorcery card from your graveyard and target instant or sorcery card from an opponent's graveyard. Copy those cards. Cast the copies if able without paying their mana costs. Exile Spelltwine.
+ // Exile target instant or sorcery card from your graveyard and target
+ // instant or sorcery card from an opponent's graveyard. Copy those cards.
+ // Cast the copies if able without paying their mana costs. Exile Spelltwine.
this.getSpellAbility().addEffect(new SpelltwineEffect());
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(filter));
this.getSpellAbility().addTarget(new TargetCardInOpponentsGraveyard(filter2));
@@ -64,7 +67,9 @@ class SpelltwineEffect extends OneShotEffect {
public SpelltwineEffect() {
super(Outcome.PlayForFree);
- staticText = "Exile target instant or sorcery card from your graveyard and target instant or sorcery card from an opponent's graveyard. Copy those cards. Cast the copies if able without paying their mana costs";
+ staticText = "Exile target instant or sorcery card from your graveyard and "
+ + "target instant or sorcery card from an opponent's graveyard. "
+ + "Copy those cards. Cast the copies if able without paying their mana costs";
}
public SpelltwineEffect(final SpelltwineEffect effect) {
@@ -85,18 +90,30 @@ class SpelltwineEffect extends OneShotEffect {
}
boolean castCardOne = true;
MageObjectReference mor = new MageObjectReference(source.getSourceObject(game), game);
- if (cardOne != null && controller.chooseUse(Outcome.Neutral, "Cast the copy of " + cardOne.getName() + " first?", source, game)) {
+ if (cardOne != null
+ && controller.chooseUse(Outcome.Neutral, "Cast the copy of "
+ + cardOne.getName() + " first?", source, game)) {
Card copyOne = game.copyCard(cardOne, source, controller.getId());
- controller.cast(copyOne.getSpellAbility(), game, true, mor);
+ game.getState().setValue("PlayFromNotOwnHandZone" + copyOne.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(copyOne, game, true),
+ game, true, mor);
+ game.getState().setValue("PlayFromNotOwnHandZone" + copyOne.getId(), null);
castCardOne = false;
}
if (cardTwo != null) {
Card copyTwo = game.copyCard(cardTwo, source, controller.getId());
- controller.cast(copyTwo.getSpellAbility(), game, true, mor);
+ game.getState().setValue("PlayFromNotOwnHandZone" + copyTwo.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(copyTwo, game, true),
+ game, true, mor);
+ game.getState().setValue("PlayFromNotOwnHandZone" + copyTwo.getId(), null);
}
- if (cardOne != null && castCardOne) {
+ if (cardOne != null
+ && castCardOne) {
Card copyOne = game.copyCard(cardOne, source, controller.getId());
- controller.cast(copyOne.getSpellAbility(), game, true, mor);
+ game.getState().setValue("PlayFromNotOwnHandZone" + copyOne.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(copyOne, game, true),
+ game, true, mor);
+ game.getState().setValue("PlayFromNotOwnHandZone" + copyOne.getId(), null);
}
return true;
}
diff --git a/Mage.Sets/src/mage/cards/s/SpellweaverHelix.java b/Mage.Sets/src/mage/cards/s/SpellweaverHelix.java
index 43ddda7009e..b0988641891 100644
--- a/Mage.Sets/src/mage/cards/s/SpellweaverHelix.java
+++ b/Mage.Sets/src/mage/cards/s/SpellweaverHelix.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -30,7 +29,7 @@ import mage.util.CardUtil;
* @author emerald000
*/
public final class SpellweaverHelix extends CardImpl {
-
+
private static final FilterCard filter = new FilterCard("sorcery cards from a single graveyard");
static {
@@ -191,7 +190,10 @@ class SpellweaverHelixCastEffect extends OneShotEffect {
if (controller.chooseUse(Outcome.Copy, "Copy " + card.getIdName(), source, game)) {
Card copy = game.copyCard(card, source, source.getControllerId());
if (controller.chooseUse(Outcome.PlayForFree, "Cast " + copy.getIdName() + " without paying its mana cost?", source, game)) {
- controller.cast(copy.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + copy.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(copy, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + copy.getId(), null);
}
}
}
diff --git a/Mage.Sets/src/mage/cards/s/SpellweaverVolute.java b/Mage.Sets/src/mage/cards/s/SpellweaverVolute.java
index c736ee45b82..620654d3903 100644
--- a/Mage.Sets/src/mage/cards/s/SpellweaverVolute.java
+++ b/Mage.Sets/src/mage/cards/s/SpellweaverVolute.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -43,8 +42,10 @@ public final class SpellweaverVolute extends CardImpl {
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
- // Whenever you cast a sorcery spell, copy the enchanted instant card. You may cast the copy without paying its mana cost.
- // If you do, exile the enchanted card and attach Spellweaver Volute to another instant card in a graveyard.
+ // Whenever you cast a sorcery spell, copy the enchanted instant card.
+ // You may cast the copy without paying its mana cost.
+ // If you do, exile the enchanted card and attach Spellweaver Volute
+ // to another instant card in a graveyard.
FilterSpell filterSpell = new FilterSpell("a sorcery spell");
filterSpell.add(new CardTypePredicate(CardType.SORCERY));
this.addAbility(new SpellCastControllerTriggeredAbility(new SpellweaverVoluteEffect(), filterSpell, false));
@@ -63,7 +64,7 @@ public final class SpellweaverVolute extends CardImpl {
class SpellweaverVoluteEffect extends OneShotEffect {
public SpellweaverVoluteEffect() {
- super(Outcome.Benefit);
+ super(Outcome.PlayForFree);
this.staticText = "copy the enchanted instant card. You may cast the copy without paying its mana cost. \n"
+ "If you do, exile the enchanted card and attach {this} to another instant card in a graveyard";
}
@@ -87,21 +88,24 @@ class SpellweaverVoluteEffect extends OneShotEffect {
if (enchantedCard != null && game.getState().getZone(enchantedCard.getId()) == Zone.GRAVEYARD) {
Player ownerEnchanted = game.getPlayer(enchantedCard.getOwnerId());
if (ownerEnchanted != null
- && controller.chooseUse(outcome, "Create a copy of " + enchantedCard.getName() + '?', source, game)) {
+ && controller.chooseUse(Outcome.Copy, "Create a copy of " + enchantedCard.getName() + '?', source, game)) {
Card copiedCard = game.copyCard(enchantedCard, source, source.getControllerId());
if (copiedCard != null) {
ownerEnchanted.getGraveyard().add(copiedCard);
game.getState().setZone(copiedCard.getId(), Zone.GRAVEYARD);
- if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
+ if (controller.chooseUse(Outcome.PlayForFree, "Cast the copied card without paying mana cost?", source, game)) {
if (copiedCard.getSpellAbility() != null) {
- controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(copiedCard, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), null);
}
if (controller.moveCards(enchantedCard, Zone.EXILED, source, game)) {
FilterCard filter = new FilterCard("instant card in a graveyard");
filter.add(new CardTypePredicate(CardType.INSTANT));
TargetCardInGraveyard auraTarget = new TargetCardInGraveyard(filter);
if (auraTarget.canChoose(source.getSourceId(), controller.getId(), game)) {
- controller.choose(outcome, auraTarget, source.getSourceId(), game);
+ controller.choose(Outcome.Benefit, auraTarget, source.getSourceId(), game);
Card newAuraTarget = game.getCard(auraTarget.getFirstTarget());
if (newAuraTarget != null) {
if (enchantedCard.getId().equals(newAuraTarget.getId())) {
diff --git a/Mage.Sets/src/mage/cards/s/SphinxMindbreaker.java b/Mage.Sets/src/mage/cards/s/SphinxMindbreaker.java
new file mode 100644
index 00000000000..9fe7e71f52e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SphinxMindbreaker.java
@@ -0,0 +1,44 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveEachPlayerEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SphinxMindbreaker extends CardImpl {
+
+ public SphinxMindbreaker(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}");
+
+ this.subtype.add(SubType.SPHINX);
+ this.power = new MageInt(6);
+ this.toughness = new MageInt(6);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // When Sphinx Mindbreaker enters the battlefield, each opponent puts the top ten cards of their library into their graveyard.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(
+ new PutTopCardOfLibraryIntoGraveEachPlayerEffect(10, TargetController.OPPONENT)
+ ));
+ }
+
+ private SphinxMindbreaker(final SphinxMindbreaker card) {
+ super(card);
+ }
+
+ @Override
+ public SphinxMindbreaker copy() {
+ return new SphinxMindbreaker(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SphinxOfEnlightenment.java b/Mage.Sets/src/mage/cards/s/SphinxOfEnlightenment.java
new file mode 100644
index 00000000000..9ba513d98cc
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SphinxOfEnlightenment.java
@@ -0,0 +1,47 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.DrawCardTargetEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.target.common.TargetOpponent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SphinxOfEnlightenment extends CardImpl {
+
+ public SphinxOfEnlightenment(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{U}");
+
+ this.subtype.add(SubType.SPHINX);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(5);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // When Sphinx of Enlightenment enters the battlefield, target opponent draws a card and you draw three cards.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new DrawCardTargetEffect(1));
+ ability.addEffect(new DrawCardSourceControllerEffect(3).concatBy("and you"));
+ ability.addTarget(new TargetOpponent());
+ this.addAbility(ability);
+ }
+
+ private SphinxOfEnlightenment(final SphinxOfEnlightenment card) {
+ super(card);
+ }
+
+ @Override
+ public SphinxOfEnlightenment copy() {
+ return new SphinxOfEnlightenment(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SpiderSpawning.java b/Mage.Sets/src/mage/cards/s/SpiderSpawning.java
index ff127fadc1b..f597f564d5f 100644
--- a/Mage.Sets/src/mage/cards/s/SpiderSpawning.java
+++ b/Mage.Sets/src/mage/cards/s/SpiderSpawning.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -10,7 +9,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TimingRule;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.permanent.token.SpiderToken;
/**
@@ -23,7 +22,7 @@ public final class SpiderSpawning extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}");
// Create a 1/2 green Spider creature token with reach for each creature card in your graveyard.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new SpiderToken(), new CardsInControllerGraveyardCount(new FilterCreatureCard())));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new SpiderToken(), new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE)));
// Flashback {6}{B}
this.addAbility(new FlashbackAbility(new ManaCostsImpl("{6}{B}"), TimingRule.SORCERY));
}
diff --git a/Mage.Sets/src/mage/cards/s/SpinningWheel.java b/Mage.Sets/src/mage/cards/s/SpinningWheel.java
new file mode 100644
index 00000000000..f74bb2d6c8a
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SpinningWheel.java
@@ -0,0 +1,42 @@
+package mage.cards.s;
+
+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.common.TapTargetEffect;
+import mage.abilities.mana.AnyColorManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SpinningWheel extends CardImpl {
+
+ public SpinningWheel(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
+
+ // {T}: Add one mana of any color.
+ this.addAbility(new AnyColorManaAbility());
+
+ // {5}, {T}: Tap target creature.
+ Ability ability = new SimpleActivatedAbility(new TapTargetEffect(), new GenericManaCost(5));
+ ability.addCost(new TapSourceCost());
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+ }
+
+ private SpinningWheel(final SpinningWheel card) {
+ super(card);
+ }
+
+ @Override
+ public SpinningWheel copy() {
+ return new SpinningWheel(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SpiritFlare.java b/Mage.Sets/src/mage/cards/s/SpiritFlare.java
new file mode 100644
index 00000000000..c2b78762f6b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SpiritFlare.java
@@ -0,0 +1,94 @@
+package mage.cards.s;
+
+import mage.abilities.Ability;
+import mage.abilities.costs.common.PayLifeCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.keyword.FlashbackAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.TargetController;
+import mage.constants.TimingRule;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterAttackingOrBlockingCreature;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.filter.predicate.permanent.TappedPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SpiritFlare extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterControlledCreaturePermanent("untapped creature you control");
+ private static final FilterPermanent filter2
+ = new FilterAttackingOrBlockingCreature("attacking or blocking creature an opponent controls");
+
+ static {
+ filter.add(Predicates.not(TappedPredicate.instance));
+ filter2.add(new ControllerPredicate(TargetController.OPPONENT));
+ }
+
+ public SpiritFlare(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{W}");
+
+ // Tap target untapped creature you control. If you do, it deals damage equal to its power to target attacking or blocking creature an opponent controls.
+ this.getSpellAbility().addEffect(new SpiritFlareEffect());
+ this.getSpellAbility().addTarget(new TargetPermanent(filter));
+ this.getSpellAbility().addTarget(new TargetPermanent(filter2));
+
+ // Flashback-{1}{W}, Pay 3 life.
+ FlashbackAbility ability = new FlashbackAbility(new ManaCostsImpl("{1}{W}"), TimingRule.INSTANT);
+ ability.addCost(new PayLifeCost(3));
+ this.addAbility(ability);
+ }
+
+ private SpiritFlare(final SpiritFlare card) {
+ super(card);
+ }
+
+ @Override
+ public SpiritFlare copy() {
+ return new SpiritFlare(this);
+ }
+}
+
+class SpiritFlareEffect extends OneShotEffect {
+
+ SpiritFlareEffect() {
+ super(Outcome.Benefit);
+ staticText = "tap target untapped creature you control. If you do, " +
+ "it deals damage equal to its power to target attacking or blocking creature an opponent controls";
+ }
+
+ private SpiritFlareEffect(final SpiritFlareEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public SpiritFlareEffect copy() {
+ return new SpiritFlareEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = game.getPermanent(source.getFirstTarget());
+ if (permanent == null || !permanent.tap(game)) {
+ return false;
+ }
+ Permanent permanent1 = game.getPermanent(source.getTargets().get(1).getFirstTarget());
+ if (permanent1 == null) {
+ return false;
+ }
+ return permanent1.damage(permanent.getPower().getValue(), permanent.getId(), game) > 0;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SpiritualSanctuary.java b/Mage.Sets/src/mage/cards/s/SpiritualSanctuary.java
index f588f7091cd..12d6d812316 100644
--- a/Mage.Sets/src/mage/cards/s/SpiritualSanctuary.java
+++ b/Mage.Sets/src/mage/cards/s/SpiritualSanctuary.java
@@ -31,7 +31,7 @@ public final class SpiritualSanctuary extends CardImpl {
public SpiritualSanctuary(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
- // At the beginning of each player's upkeep, if that player controls a Plains, he or she gains 1 life.
+ // At the beginning of each player's upkeep, if that player controls a Plains, they gain 1 life.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility(
new GainLifeTargetEffect(1).setText("they gain 1 life"),
@@ -39,7 +39,7 @@ public final class SpiritualSanctuary extends CardImpl {
),
new PermanentsOnTheBattlefieldCondition(filter),
"at the beginning of each player's upkeep, "
- + "if that player controls a Plains, they gains 1 life"
+ + "if that player controls a Plains, they gain 1 life"
));
}
diff --git a/Mage.Sets/src/mage/cards/s/SpriteNoble.java b/Mage.Sets/src/mage/cards/s/SpriteNoble.java
index 44888832a9a..e59d4e45547 100644
--- a/Mage.Sets/src/mage/cards/s/SpriteNoble.java
+++ b/Mage.Sets/src/mage/cards/s/SpriteNoble.java
@@ -1,7 +1,5 @@
-
package mage.cards.s;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
@@ -11,16 +9,16 @@ import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
+import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate;
-/**
- *
- * @author LoneFox
+import java.util.UUID;
+/**
+ * @author LoneFox
*/
public final class SpriteNoble extends CardImpl {
@@ -31,8 +29,8 @@ public final class SpriteNoble extends CardImpl {
}
public SpriteNoble(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}{U}");
- this.subtype.add(SubType.FAERIE);
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}");
+ this.subtype.add(SubType.FAERIE, SubType.NOBLE);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
@@ -42,7 +40,7 @@ public final class SpriteNoble extends CardImpl {
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(0, 1, Duration.WhileOnBattlefield, filter, true)));
// {tap}: Other creatures you control with flying get +1/+0 until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 0, Duration.EndOfTurn, filter, true),
- new TapSourceCost()));
+ new TapSourceCost()));
}
public SpriteNoble(final SpriteNoble card) {
diff --git a/Mage.Sets/src/mage/cards/s/SpyNetwork.java b/Mage.Sets/src/mage/cards/s/SpyNetwork.java
index c325541b6cc..a1a645e3c8b 100644
--- a/Mage.Sets/src/mage/cards/s/SpyNetwork.java
+++ b/Mage.Sets/src/mage/cards/s/SpyNetwork.java
@@ -31,7 +31,7 @@ public final class SpyNetwork extends CardImpl {
public SpyNetwork(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}");
- // Look at target player's hand, the top card of that player's library, and any face-down creatures he or she controls. Look at the top four cards of your library, then put them back in any order.
+ // Look at target player's hand, the top card of that player's library, and any face-down creatures they control. Look at the top four cards of your library, then put them back in any order.
this.getSpellAbility().addEffect(new SpyNetworkLookAtTargetPlayerHandEffect());
this.getSpellAbility().addEffect(new LookLibraryTopCardTargetPlayerEffect().setText(" the top card of that player's library"));
this.getSpellAbility().addEffect(new SpyNetworkFaceDownEffect());
@@ -84,7 +84,7 @@ class SpyNetworkFaceDownEffect extends OneShotEffect {
public SpyNetworkFaceDownEffect() {
super(Outcome.Benefit);
- this.staticText = "and any face-down creatures he or she controls";
+ this.staticText = "and any face-down creatures they control";
}
public SpyNetworkFaceDownEffect(final SpyNetworkFaceDownEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/Stabilizer.java b/Mage.Sets/src/mage/cards/s/Stabilizer.java
new file mode 100644
index 00000000000..bd70c9553e1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/Stabilizer.java
@@ -0,0 +1,78 @@
+package mage.cards.s;
+
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.LoyaltyAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class Stabilizer extends CardImpl {
+
+ public Stabilizer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
+
+ // Players can't cycle cards.
+ this.addAbility(new SimpleStaticAbility(new StabilizerEffect()));
+ }
+
+ private Stabilizer(final Stabilizer card) {
+ super(card);
+ }
+
+ @Override
+ public Stabilizer copy() {
+ return new Stabilizer(this);
+ }
+}
+
+class StabilizerEffect extends ContinuousRuleModifyingEffectImpl {
+
+ StabilizerEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.Detriment);
+ staticText = "Players can't cycle cards";
+ }
+
+ private StabilizerEffect(final StabilizerEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public StabilizerEffect copy() {
+ return new StabilizerEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public String getInfoMessage(Ability source, GameEvent event, Game game) {
+ MageObject mageObject = game.getObject(source.getSourceId());
+ if (mageObject == null) {
+ return null;
+ }
+ return "You can't cycle cards (" + mageObject.getIdName() + ").";
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ if (event.getType() != GameEvent.EventType.ACTIVATE_ABILITY) {
+ return false;
+ }
+ Ability ability = game.getAbility(event.getTargetId(), event.getSourceId()).orElse(null);
+ return ability instanceof LoyaltyAbility;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/StaggeringInsight.java b/Mage.Sets/src/mage/cards/s/StaggeringInsight.java
new file mode 100644
index 00000000000..b27cd459685
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/StaggeringInsight.java
@@ -0,0 +1,60 @@
+package mage.cards.s;
+
+import mage.abilities.Ability;
+import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.abilities.keyword.LifelinkAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class StaggeringInsight extends CardImpl {
+
+ public StaggeringInsight(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}{U}");
+
+ this.subtype.add(SubType.AURA);
+
+ // Enchant creature
+ TargetPermanent auraTarget = new TargetCreaturePermanent();
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // Enchanted creature gets +1/+1 and has lifelink and "Whenever this creature deals combat damage to a player, draw a card."
+ ability = new SimpleStaticAbility(new BoostEnchantedEffect(1, 1));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ LifelinkAbility.getInstance(), AttachmentType.AURA,
+ Duration.WhileOnBattlefield, "and has lifelink"
+ ));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ new DealsCombatDamageToAPlayerTriggeredAbility(
+ new DrawCardSourceControllerEffect(1), false
+ ), AttachmentType.AURA, Duration.WhileOnBattlefield,
+ "and \"Whenever this creature deals combat damage to a player, draw a card.\""
+ ));
+ this.addAbility(ability);
+ }
+
+ private StaggeringInsight(final StaggeringInsight card) {
+ super(card);
+ }
+
+ @Override
+ public StaggeringInsight copy() {
+ return new StaggeringInsight(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SteamcoreWeird.java b/Mage.Sets/src/mage/cards/s/SteamcoreWeird.java
index 6cc807ea45e..8d3d9980081 100644
--- a/Mage.Sets/src/mage/cards/s/SteamcoreWeird.java
+++ b/Mage.Sets/src/mage/cards/s/SteamcoreWeird.java
@@ -32,7 +32,7 @@ public final class SteamcoreWeird extends CardImpl {
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(2, "it"));
ability.addTarget(new TargetAnyTarget());
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new ManaWasSpentCondition(ColoredManaSymbol.R),
- "if {R} was spent to cast {this}, it deals 2 damage to any target."),
+ "if {R} was spent to cast this spell, it deals 2 damage to any target."),
new ManaSpentToCastWatcher());
}
diff --git a/Mage.Sets/src/mage/cards/s/SteelbaneHydra.java b/Mage.Sets/src/mage/cards/s/SteelbaneHydra.java
new file mode 100644
index 00000000000..f73bff650c8
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SteelbaneHydra.java
@@ -0,0 +1,49 @@
+package mage.cards.s;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.RemoveCountersSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DestroyTargetEffect;
+import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.filter.StaticFilters;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SteelbaneHydra extends CardImpl {
+
+ public SteelbaneHydra(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{X}{G}{G}");
+
+ this.subtype.add(SubType.TURTLE);
+ this.subtype.add(SubType.HYDRA);
+
+ // Steelbane Hydra enters the battlefield with X +1/+1 counters on it.
+ this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldWithXCountersEffect(CounterType.P1P1.createInstance())));
+
+ // {2}{G}, Remove a +1/+1 counter from Steelbane Hydra: Destroy target artifact or enchantment.
+ Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new ManaCostsImpl("{2}{G}"));
+ ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance(1)));
+ ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT));
+ this.addAbility(ability);
+ }
+
+ private SteelbaneHydra(final SteelbaneHydra card) {
+ super(card);
+ }
+
+ @Override
+ public SteelbaneHydra copy() {
+ return new SteelbaneHydra(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SteelclawLance.java b/Mage.Sets/src/mage/cards/s/SteelclawLance.java
new file mode 100644
index 00000000000..ace1b7684f4
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SteelclawLance.java
@@ -0,0 +1,49 @@
+package mage.cards.s;
+
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.continuous.BoostEquippedEffect;
+import mage.abilities.keyword.EquipAbility;
+import mage.abilities.keyword.EquipFilterAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.filter.common.FilterControlledCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SteelclawLance extends CardImpl {
+
+ private static final FilterControlledCreaturePermanent filter
+ = new FilterControlledCreaturePermanent(SubType.KNIGHT, "Knight");
+
+ public SteelclawLance(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{B}{R}");
+
+ this.subtype.add(SubType.EQUIPMENT);
+
+ // Equipped creature gets +2/+2.
+ this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(2, 2)));
+
+ // Equip Knight {1}
+ this.addAbility(new EquipFilterAbility(filter, new GenericManaCost(1)));
+
+ // Equip {3}
+ this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(3)));
+
+ }
+
+ private SteelclawLance(final SteelclawLance card) {
+ super(card);
+ }
+
+ @Override
+ public SteelclawLance copy() {
+ return new SteelclawLance(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SteelgazeGriffin.java b/Mage.Sets/src/mage/cards/s/SteelgazeGriffin.java
new file mode 100644
index 00000000000..303869131ef
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SteelgazeGriffin.java
@@ -0,0 +1,42 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.common.DrawSecondCardTriggeredAbility;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SteelgazeGriffin extends CardImpl {
+
+ public SteelgazeGriffin(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}");
+
+ this.subtype.add(SubType.GRIFFIN);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(4);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // When you draw your second card each turn, Steelgaze Griffin gets +2/+0 until end of turn.
+ this.addAbility(new DrawSecondCardTriggeredAbility(new BoostSourceEffect(2, 0, Duration.EndOfTurn), false));
+ }
+
+ private SteelgazeGriffin(final SteelgazeGriffin card) {
+ super(card);
+ }
+
+ @Override
+ public SteelgazeGriffin copy() {
+ return new SteelgazeGriffin(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/StenchOfEvil.java b/Mage.Sets/src/mage/cards/s/StenchOfEvil.java
index b85fcf0603d..664e476cfe0 100644
--- a/Mage.Sets/src/mage/cards/s/StenchOfEvil.java
+++ b/Mage.Sets/src/mage/cards/s/StenchOfEvil.java
@@ -25,7 +25,7 @@ public final class StenchOfEvil extends CardImpl {
public StenchOfEvil(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}{B}");
- // Destroy all Plains. For each land destroyed this way, Stench of Evil deals 1 damage to that land's controller unless he or she pays {2}.
+ // Destroy all Plains. For each land destroyed this way, Stench of Evil deals 1 damage to that land's controller unless they pay {2}.
this.getSpellAbility().addEffect(new StenchOfEvilEffect());
}
@@ -50,7 +50,7 @@ class StenchOfEvilEffect extends OneShotEffect {
public StenchOfEvilEffect() {
super(Outcome.Benefit);
- this.staticText = "Destroy all Plains. For each land destroyed this way, {this} deals 1 damage to that land's controller unless he or she pays {2}";
+ this.staticText = "Destroy all Plains. For each land destroyed this way, {this} deals 1 damage to that land's controller unless they pay {2}";
}
public StenchOfEvilEffect(final StenchOfEvilEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/SternJudge.java b/Mage.Sets/src/mage/cards/s/SternJudge.java
index 3661d67b026..3144ed9baa3 100644
--- a/Mage.Sets/src/mage/cards/s/SternJudge.java
+++ b/Mage.Sets/src/mage/cards/s/SternJudge.java
@@ -31,7 +31,7 @@ public final class SternJudge extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- // {tap}: Each player loses 1 life for each Swamp he or she controls.
+ // {tap}: Each player loses 1 life for each Swamp they control.
this.addAbility(new SimpleActivatedAbility(new SternJudgeEffect(), new TapSourceCost()));
}
@@ -55,7 +55,7 @@ class SternJudgeEffect extends OneShotEffect {
SternJudgeEffect() {
super(Outcome.Benefit);
- this.staticText = "Each player loses 1 life for each Swamp he or she controls.";
+ this.staticText = "Each player loses 1 life for each Swamp they control.";
}
SternJudgeEffect(final SternJudgeEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/StolenByTheFae.java b/Mage.Sets/src/mage/cards/s/StolenByTheFae.java
new file mode 100644
index 00000000000..08fd09a5893
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/StolenByTheFae.java
@@ -0,0 +1,57 @@
+package mage.cards.s;
+
+import mage.abilities.Ability;
+import mage.abilities.dynamicvalue.common.ManacostVariableValue;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
+import mage.game.Game;
+import mage.game.permanent.token.FaerieToken;
+import mage.target.common.TargetCreaturePermanent;
+import mage.target.targetadjustment.TargetAdjuster;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class StolenByTheFae extends CardImpl {
+
+ public StolenByTheFae(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}{U}");
+
+ // Return target creature with converted mana cost X to its owner's hand. You create X 1/1 blue Faerie creature tokens with flying.
+ this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()
+ .setText("Return target creature with converted mana cost X to its owner's hand."));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new FaerieToken(), ManacostVariableValue.instance)
+ .setText("You create X 1/1 blue Faerie creature tokens with flying."));
+ this.getSpellAbility().setTargetAdjuster(StolenByTheFaeAdjuster.instance);
+ }
+
+ private StolenByTheFae(final StolenByTheFae card) {
+ super(card);
+ }
+
+ @Override
+ public StolenByTheFae copy() {
+ return new StolenByTheFae(this);
+ }
+}
+
+enum StolenByTheFaeAdjuster implements TargetAdjuster {
+ instance;
+
+ @Override
+ public void adjustTargets(Ability ability, Game game) {
+ ability.getTargets().clear();
+ int xValue = ability.getManaCostsToPay().getX();
+ FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost " + xValue);
+ filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue));
+ ability.addTarget(new TargetCreaturePermanent(filter));
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/s/StolenGoods.java b/Mage.Sets/src/mage/cards/s/StolenGoods.java
index 578d83d51f7..c6588a53285 100644
--- a/Mage.Sets/src/mage/cards/s/StolenGoods.java
+++ b/Mage.Sets/src/mage/cards/s/StolenGoods.java
@@ -29,7 +29,7 @@ public final class StolenGoods extends CardImpl {
public StolenGoods(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}");
- // Target opponent exiles cards from the top of their library until he or she exiles a nonland card. Until end of turn, you may cast that card without paying its mana cost.
+ // Target opponent exiles cards from the top of their library until they exile a nonland card. Until end of turn, you may cast that card without paying its mana cost.
this.getSpellAbility().addEffect(new StolenGoodsEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
}
@@ -48,7 +48,7 @@ class StolenGoodsEffect extends OneShotEffect {
public StolenGoodsEffect() {
super(Outcome.Detriment);
- this.staticText = "Target opponent exiles cards from the top of their library until he or she exiles a nonland card. Until end of turn, you may cast that card without paying its mana cost";
+ this.staticText = "Target opponent exiles cards from the top of their library until they exile a nonland card. Until end of turn, you may cast that card without paying its mana cost";
}
public StolenGoodsEffect(final StolenGoodsEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/StolenStrategy.java b/Mage.Sets/src/mage/cards/s/StolenStrategy.java
index e20f44395ec..d9b04a41c16 100644
--- a/Mage.Sets/src/mage/cards/s/StolenStrategy.java
+++ b/Mage.Sets/src/mage/cards/s/StolenStrategy.java
@@ -1,8 +1,5 @@
-
package mage.cards.s;
-import java.util.Objects;
-import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
@@ -13,13 +10,7 @@ import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.AsThoughEffectType;
-import mage.constants.CardType;
-import mage.constants.Duration;
-import mage.constants.ManaType;
-import mage.constants.Outcome;
-import mage.constants.TargetController;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.game.ExileZone;
import mage.game.Game;
import mage.players.ManaPoolItem;
@@ -27,8 +18,10 @@ import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
+import java.util.Objects;
+import java.util.UUID;
+
/**
- *
* @author TheElk801
*/
public final class StolenStrategy extends CardImpl {
@@ -164,12 +157,12 @@ class StolenStrategySpendAnyManaEffect extends AsThoughEffectImpl implements AsT
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
- objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
+ FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
return source.isControlledBy(affectedControllerId)
- && Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget())
- && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)
- && (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId))
- && game.getState().getZone(objectId) == Zone.STACK;
+ && Objects.equals(objectId, fixedTarget.getTarget())
+ && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
+ && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/s/StonecoilSerpent.java b/Mage.Sets/src/mage/cards/s/StonecoilSerpent.java
new file mode 100644
index 00000000000..74c9c5047b4
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/StonecoilSerpent.java
@@ -0,0 +1,55 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.abilities.keyword.ProtectionAbility;
+import mage.filter.predicate.mageobject.MulticoloredPredicate;
+import mage.filter.FilterObject;
+import mage.abilities.keyword.ReachAbility;
+import mage.abilities.keyword.TrampleAbility;
+
+import java.util.UUID;
+
+/**
+ *
+ * @author Tsirides
+ */
+public final class StonecoilSerpent extends CardImpl {
+
+ private static final FilterObject filter = new FilterObject("multicolored");
+
+ static {
+ filter.add(MulticoloredPredicate.instance);
+ }
+
+ public StonecoilSerpent(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{X}");
+ this.subtype.add(SubType.SNAKE);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(0);
+
+ //Trample, Reach, Protection from Multicolored
+ this.addAbility(new ProtectionAbility(filter));
+ this.addAbility(ReachAbility.getInstance());
+ this.addAbility(TrampleAbility.getInstance());
+
+
+ // Endless One enters the battlefield with X +1/+1 counters on it.
+ this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldWithXCountersEffect(CounterType.P1P1.createInstance())));
+ }
+
+ public StonecoilSerpent(final StonecoilSerpent card) {
+ super(card);
+ }
+
+ @Override
+ public StonecoilSerpent copy() {
+ return new StonecoilSerpent(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/StonewiseFortifier.java b/Mage.Sets/src/mage/cards/s/StonewiseFortifier.java
index 67848f60fa3..7c9fffb4554 100644
--- a/Mage.Sets/src/mage/cards/s/StonewiseFortifier.java
+++ b/Mage.Sets/src/mage/cards/s/StonewiseFortifier.java
@@ -1,7 +1,5 @@
-
package mage.cards.s;
-import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
@@ -11,21 +9,24 @@ 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.SubType;
import mage.constants.Zone;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class StonewiseFortifier extends CardImpl {
public StonewiseFortifier(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
@@ -71,7 +72,7 @@ class StonewiseFortifierPreventAllDamageToEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, event.getTargetId(), event.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(event.getTargetId(), event.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int preventedDamage = event.getAmount();
MageObject damageSource = game.getObject(event.getSourceId());
@@ -91,9 +92,7 @@ class StonewiseFortifierPreventAllDamageToEffect extends PreventionEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game) && event.getTargetId().equals(source.getSourceId())) {
- if (event.getSourceId().equals(targetPointer.getFirst(game, source))) {
- return true;
- }
+ return event.getSourceId().equals(targetPointer.getFirst(game, source));
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/s/StormfistCrusader.java b/Mage.Sets/src/mage/cards/s/StormfistCrusader.java
new file mode 100644
index 00000000000..ab4d35ed3d2
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/StormfistCrusader.java
@@ -0,0 +1,50 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.dynamicvalue.common.StaticValue;
+import mage.abilities.effects.common.DrawCardAllEffect;
+import mage.abilities.effects.common.LoseLifeAllPlayersEffect;
+import mage.abilities.keyword.MenaceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class StormfistCrusader extends CardImpl {
+
+ public StormfistCrusader(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{R}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Menace
+ this.addAbility(new MenaceAbility());
+
+ // At the beginning of your upkeep, each player draws a card and loses 1 life.
+ Ability ability = new BeginningOfUpkeepTriggeredAbility(
+ new DrawCardAllEffect(1), TargetController.YOU, false
+ );
+ ability.addEffect(new LoseLifeAllPlayersEffect(new StaticValue(1), "and loses 1 life"));
+ this.addAbility(ability);
+ }
+
+ private StormfistCrusader(final StormfistCrusader card) {
+ super(card);
+ }
+
+ @Override
+ public StormfistCrusader copy() {
+ return new StormfistCrusader(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/StromkirkNoble.java b/Mage.Sets/src/mage/cards/s/StromkirkNoble.java
index 03254100e4c..1f75187de24 100644
--- a/Mage.Sets/src/mage/cards/s/StromkirkNoble.java
+++ b/Mage.Sets/src/mage/cards/s/StromkirkNoble.java
@@ -1,7 +1,5 @@
-
package mage.cards.s;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.common.SimpleEvasionAbility;
@@ -15,8 +13,9 @@ import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author Alvin
* @author ayratn
*/
@@ -24,7 +23,7 @@ public final class StromkirkNoble extends CardImpl {
public StromkirkNoble(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}");
- this.subtype.add(SubType.VAMPIRE);
+ this.subtype.add(SubType.VAMPIRE, SubType.NOBLE);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
@@ -34,7 +33,6 @@ public final class StromkirkNoble extends CardImpl {
new CantBeBlockedByCreaturesSourceEffect(new FilterCreaturePermanent(SubType.HUMAN, "Humans"), Duration.WhileOnBattlefield)));
// Whenever Stromkirk Noble deals combat damage to a player, put a +1/+1 counter on it.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false));
-
}
public StromkirkNoble(final StromkirkNoble card) {
diff --git a/Mage.Sets/src/mage/cards/s/StrongholdDiscipline.java b/Mage.Sets/src/mage/cards/s/StrongholdDiscipline.java
index 36291d084c4..6912b62a14c 100644
--- a/Mage.Sets/src/mage/cards/s/StrongholdDiscipline.java
+++ b/Mage.Sets/src/mage/cards/s/StrongholdDiscipline.java
@@ -21,7 +21,7 @@ public final class StrongholdDiscipline extends CardImpl {
public StrongholdDiscipline(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}{B}");
- // Each player loses 1 life for each creature he or she controls.
+ // Each player loses 1 life for each creature they control.
this.getSpellAbility().addEffect(new StrongholdDisciplineEffect());
}
@@ -39,7 +39,7 @@ class StrongholdDisciplineEffect extends OneShotEffect {
StrongholdDisciplineEffect() {
super(Outcome.Sacrifice);
- this.staticText = "Each player loses 1 life for each creature he or she controls";
+ this.staticText = "Each player loses 1 life for each creature they control";
}
StrongholdDisciplineEffect(final StrongholdDisciplineEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/StruggleForSanity.java b/Mage.Sets/src/mage/cards/s/StruggleForSanity.java
index 4cc318190cb..d1b21a29a93 100644
--- a/Mage.Sets/src/mage/cards/s/StruggleForSanity.java
+++ b/Mage.Sets/src/mage/cards/s/StruggleForSanity.java
@@ -28,7 +28,7 @@ public final class StruggleForSanity extends CardImpl {
public StruggleForSanity(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}{B}");
- // Target opponent reveals their hand. That player exiles a card from it, then you exile a card from it. Repeat this process until all cards in that hand have been exiled. That player returns the cards he or she exiled this way to their hand and puts the rest into their graveyard.
+ // Target opponent reveals their hand. That player exiles a card from it, then you exile a card from it. Repeat this process until all cards in that hand have been exiled. That player returns the cards they exiled this way to their hand and puts the rest into their graveyard.
this.getSpellAbility().addEffect(new StruggleForSanityEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
}
@@ -47,7 +47,7 @@ class StruggleForSanityEffect extends OneShotEffect {
public StruggleForSanityEffect() {
super(Outcome.Discard); // kind of
- this.staticText = "Target opponent reveals their hand. That player exiles a card from it, then you exile a card from it. Repeat this process until all cards in that hand have been exiled. That player returns the cards he or she exiled this way to their hand and puts the rest into their graveyard";
+ this.staticText = "Target opponent reveals their hand. That player exiles a card from it, then you exile a card from it. Repeat this process until all cards in that hand have been exiled. That player returns the cards they exiled this way to their hand and puts the rest into their graveyard";
}
public StruggleForSanityEffect(final StruggleForSanityEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/StruggleSurvive.java b/Mage.Sets/src/mage/cards/s/StruggleSurvive.java
index fbe4e1050ef..f9a9b6428a8 100644
--- a/Mage.Sets/src/mage/cards/s/StruggleSurvive.java
+++ b/Mage.Sets/src/mage/cards/s/StruggleSurvive.java
@@ -40,7 +40,7 @@ public final class StruggleSurvive extends SplitCard {
// Survive
// Aftermath
getRightHalfCard().addAbility(new AftermathAbility().setRuleAtTheTop(true));
- // Each player shuffles his or graveyard into their library.
+ // Each player shuffles their graveyard into their library.
getRightHalfCard().getSpellAbility().addEffect(new SurviveEffect());
}
diff --git a/Mage.Sets/src/mage/cards/s/SuddenSubstitution.java b/Mage.Sets/src/mage/cards/s/SuddenSubstitution.java
new file mode 100644
index 00000000000..a6deb99443f
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SuddenSubstitution.java
@@ -0,0 +1,82 @@
+package mage.cards.s;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.GainControlTargetEffect;
+import mage.abilities.keyword.SplitSecondAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.game.stack.Spell;
+import mage.target.TargetSpell;
+import mage.target.common.TargetCreaturePermanent;
+import mage.target.targetpointer.FixedTarget;
+
+import java.util.UUID;
+
+import static mage.constants.Outcome.Benefit;
+
+/**
+ * @author TheElk801
+ */
+public final class SuddenSubstitution extends CardImpl {
+
+ public SuddenSubstitution(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{U}");
+
+ // Split second
+ this.addAbility(new SplitSecondAbility());
+
+ // Exchange control of target noncreature spell and target creature. Then the spell's controller may choose new targets for it.
+ this.getSpellAbility().addEffect(new SuddenSubstitutionEffect());
+ this.getSpellAbility().addTarget(new TargetSpell(StaticFilters.FILTER_SPELL_NON_CREATURE));
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent());
+ }
+
+ private SuddenSubstitution(final SuddenSubstitution card) {
+ super(card);
+ }
+
+ @Override
+ public SuddenSubstitution copy() {
+ return new SuddenSubstitution(this);
+ }
+}
+
+class SuddenSubstitutionEffect extends OneShotEffect {
+
+ SuddenSubstitutionEffect() {
+ super(Benefit);
+ staticText = "Exchange control of target noncreature spell and target creature. " +
+ "Then the spell's controller may choose new targets for it.";
+ }
+
+ private SuddenSubstitutionEffect(final SuddenSubstitutionEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public SuddenSubstitutionEffect copy() {
+ return new SuddenSubstitutionEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Spell spell = game.getSpell(source.getTargets().get(0).getFirstTarget());
+ Permanent creature = game.getPermanent(source.getTargets().get(1).getFirstTarget());
+ if (spell == null || creature == null) {
+ return false;
+ }
+ ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, spell.getControllerId());
+ effect.setTargetPointer(new FixedTarget(creature, game));
+ spell.setControllerId(creature.getControllerId());
+ spell.chooseNewTargets(game, creature.getControllerId());
+ game.addEffect(effect, source);
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java
index 0d5e1540dcc..29862fe3d39 100644
--- a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java
+++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java
@@ -35,7 +35,10 @@ public final class SunbirdsInvocation extends CardImpl {
public SunbirdsInvocation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{5}{R}");
- // Whenever you cast a spell from your hand, reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order.
+ // Whenever you cast a spell from your hand, reveal the top X cards of your library,
+ // where X is that spell's converted mana cost. You may cast a card revealed this
+ // way with converted mana cost X or less without paying its mana cost. Put the
+ // rest on the bottom of your library in a random order.
this.addAbility(new SunbirdsInvocationTriggeredAbility());
}
@@ -97,7 +100,10 @@ class SunbirdsInvocationEffect extends OneShotEffect {
public SunbirdsInvocationEffect() {
super(Outcome.PutCardInPlay);
- staticText = "reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order";
+ staticText = "reveal the top X cards of your library, where X is that "
+ + "spell's converted mana cost. You may cast a card revealed this "
+ + "way with converted mana cost X or less without paying its mana cost. "
+ + "Put the rest on the bottom of your library in a random order";
}
public SunbirdsInvocationEffect(final SunbirdsInvocationEffect effect) {
@@ -129,8 +135,13 @@ class SunbirdsInvocationEffect extends OneShotEffect {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
if (controller.chooseUse(Outcome.Benefit, "Cast " + card.getLogName() + " without paying its mana cost?", source, game)) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
- cards.remove(card);
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (cardWasCast) {
+ cards.remove(card);
+ }
}
}
}
diff --git a/Mage.Sets/src/mage/cards/s/SunderingStroke.java b/Mage.Sets/src/mage/cards/s/SunderingStroke.java
new file mode 100644
index 00000000000..fb3feb97f9e
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SunderingStroke.java
@@ -0,0 +1,56 @@
+package mage.cards.s;
+
+import mage.abilities.Ability;
+import mage.abilities.condition.Condition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.DamageMultiEffect;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.hint.StaticHint;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ColoredManaSymbol;
+import mage.game.Game;
+import mage.target.common.TargetAnyTargetAmount;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SunderingStroke extends CardImpl {
+
+ public SunderingStroke(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{6}{R}");
+
+ // Sundering Stroke deals 7 damage divided as you choose among one, two, or three targets. If at least seven red mana was spent to cast this spell, instead Sundering Stroke deals 7 damage to each of those permanents and/or players.
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new DamageTargetEffect(7), new DamageMultiEffect(7), SunderingStrokeCondtition.instance,
+ "{this} deals 7 damage divided as you choose among one, two, or three targets. " +
+ "If at least seven red mana was spent to cast this spell, " +
+ "instead {this} deals 7 damage to each of those permanents and/or players"
+ ));
+ this.getSpellAbility().addTarget(new TargetAnyTargetAmount(7, 3));
+ this.getSpellAbility().addHint(new StaticHint(
+ "(You have to choose how 7 damage is divided even if you spend seven red mana)"
+ ));
+ }
+
+ private SunderingStroke(final SunderingStroke card) {
+ super(card);
+ }
+
+ @Override
+ public SunderingStroke copy() {
+ return new SunderingStroke(this);
+ }
+}
+
+enum SunderingStrokeCondtition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return source.getManaCostsToPay().getPayment().getColor(ColoredManaSymbol.R) >= 6;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/s/Sunforger.java b/Mage.Sets/src/mage/cards/s/Sunforger.java
index fe70654e64e..11e257fe1d7 100644
--- a/Mage.Sets/src/mage/cards/s/Sunforger.java
+++ b/Mage.Sets/src/mage/cards/s/Sunforger.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -46,10 +45,14 @@ public final class Sunforger extends CardImpl {
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +4/+0.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(4, 0, Duration.WhileOnBattlefield)));
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
+ new BoostEquippedEffect(4, 0, Duration.WhileOnBattlefield)));
- // {R}{W}, Unattach Sunforger: Search your library for a red or white instant card with converted mana cost 4 or less and cast that card without paying its mana cost. Then shuffle your library.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SunforgerEffect(), new ManaCostsImpl("{R}{W}"));
+ // {R}{W}, Unattach Sunforger: Search your library for a red or white
+ // instant card with converted mana cost 4 or less and cast that card
+ // without paying its mana cost. Then shuffle your library.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
+ new SunforgerEffect(), new ManaCostsImpl("{R}{W}"));
ability.addCost(new SunforgerUnattachCost(this.getName()));
this.addAbility(ability);
@@ -72,7 +75,9 @@ class SunforgerEffect extends OneShotEffect {
public SunforgerEffect() {
super(Outcome.PlayForFree);
- staticText = "Search your library for a red or white instant card with converted mana cost 4 or less and cast that card without paying its mana cost. Then shuffle your library";
+ staticText = "Search your library for a red or white instant "
+ + "card with converted mana cost 4 or less and cast that "
+ + "card without paying its mana cost. Then shuffle your library";
}
public SunforgerEffect(final SunforgerEffect effect) {
@@ -90,12 +95,11 @@ class SunforgerEffect extends OneShotEffect {
if (controller != null) {
if (controller.getLibrary().hasCards()) {
/**
- * 10/1/2005 Any card you find must be legally castable (for
+ * 10/1/2005 Any card you find must be legally cast-able (for
* example, you have to be able to choose a legal target for
- * it). If you can't find a castable card (or choose not to),
+ * it). If you can't find a cast-able card (or choose not to),
* nothing happens and you shuffle your library.
*/
-
FilterCard filter = new FilterCard("red or white instant card with converted mana cost 4 or less");
TargetCardInLibrary target = new TargetCardInLibrary(filter);
filter.add(Predicates.or(
@@ -108,7 +112,10 @@ class SunforgerEffect extends OneShotEffect {
UUID targetId = target.getFirstTarget();
Card card = game.getCard(targetId);
if (card != null) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
}
diff --git a/Mage.Sets/src/mage/cards/s/SunkenHope.java b/Mage.Sets/src/mage/cards/s/SunkenHope.java
index 24c3aa67c4c..de5547375e7 100644
--- a/Mage.Sets/src/mage/cards/s/SunkenHope.java
+++ b/Mage.Sets/src/mage/cards/s/SunkenHope.java
@@ -27,7 +27,7 @@ public final class SunkenHope extends CardImpl {
public SunkenHope(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}{U}");
- // At the beginning of each player's upkeep, that player returns a creature he or she controls to its owner's hand.
+ // At the beginning of each player's upkeep, that player returns a creature they control to its owner's hand.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SunkenHopeReturnToHandEffect(), TargetController.ANY, false, true));
}
@@ -45,7 +45,7 @@ class SunkenHopeReturnToHandEffect extends OneShotEffect {
public SunkenHopeReturnToHandEffect() {
super(Outcome.ReturnToHand);
- staticText = "that player returns a creature he or she controls to its owner's hand";
+ staticText = "that player returns a creature they control to its owner's hand";
}
public SunkenHopeReturnToHandEffect(final SunkenHopeReturnToHandEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/SwayOfTheStars.java b/Mage.Sets/src/mage/cards/s/SwayOfTheStars.java
index 7379681a6eb..5fd870424fd 100644
--- a/Mage.Sets/src/mage/cards/s/SwayOfTheStars.java
+++ b/Mage.Sets/src/mage/cards/s/SwayOfTheStars.java
@@ -27,7 +27,7 @@ public final class SwayOfTheStars extends CardImpl {
public SwayOfTheStars(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{8}{U}{U}");
- // Each player shuffles their hand, graveyard, and permanents he or she owns into their library, then draws seven cards. Each player's life total becomes 7.
+ // Each player shuffles their hand, graveyard, and permanents they own into their library, then draws seven cards. Each player's life total becomes 7.
this.getSpellAbility().addEffect(new SwayOfTheStarsEffect());
Effect effect = new DrawCardAllEffect(7);
effect.setText(", then draws seven cards");
@@ -50,7 +50,7 @@ class SwayOfTheStarsEffect extends OneShotEffect {
public SwayOfTheStarsEffect() {
super(Outcome.Neutral);
- staticText = "Each player shuffles their hand, graveyard, and permanents he or she owns into their library, then draws seven cards. Each player's life total becomes 7";
+ staticText = "Each player shuffles their hand, graveyard, and permanents they own into their library, then draws seven cards. Each player's life total becomes 7";
}
public SwayOfTheStarsEffect(final SwayOfTheStarsEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/s/SwordOfFeastAndFamine.java b/Mage.Sets/src/mage/cards/s/SwordOfFeastAndFamine.java
index ea4a9d0d289..28862d5ab70 100644
--- a/Mage.Sets/src/mage/cards/s/SwordOfFeastAndFamine.java
+++ b/Mage.Sets/src/mage/cards/s/SwordOfFeastAndFamine.java
@@ -1,8 +1,5 @@
-
-
package mage.cards.s;
-import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleStaticAbility;
@@ -16,11 +13,7 @@ import mage.abilities.keyword.EquipAbility;
import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.AttachmentType;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.game.Game;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent;
@@ -28,18 +21,25 @@ import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
+import java.util.UUID;
+
/**
- *
* @author Viserion
*/
public final class SwordOfFeastAndFamine extends CardImpl {
public SwordOfFeastAndFamine(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
this.subtype.add(SubType.EQUIPMENT);
+
+ // Equip {2}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2)));
+
+ // Equipped creature gets +2/+2 and has protection from black and from green.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2)));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ProtectionAbility.from(ObjectColor.GREEN, ObjectColor.BLACK), AttachmentType.EQUIPMENT)));
+
+ // Whenever equipped creature deals combat damage to a player, that player discards a card and you untap all lands you control.
this.addAbility(new SwordOfFeastAndFamineAbility());
}
@@ -76,7 +76,7 @@ class SwordOfFeastAndFamineAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
- DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event;
+ DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event;
Permanent p = game.getPermanent(event.getSourceId());
if (damageEvent.isCombatDamage() && p != null && p.getAttachments().contains(this.getSourceId())) {
for (Effect effect : this.getEffects()) {
diff --git a/Mage.Sets/src/mage/cards/s/SylvanTutor.java b/Mage.Sets/src/mage/cards/s/SylvanTutor.java
index 8baa1cb363f..e2c3c6c07a6 100644
--- a/Mage.Sets/src/mage/cards/s/SylvanTutor.java
+++ b/Mage.Sets/src/mage/cards/s/SylvanTutor.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -6,7 +5,7 @@ import mage.abilities.effects.common.search.SearchLibraryPutOnLibraryEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCardInLibrary;
/**
@@ -16,11 +15,10 @@ import mage.target.common.TargetCardInLibrary;
public final class SylvanTutor extends CardImpl {
public SylvanTutor(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{G}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{G}");
// Search your library for a creature card and reveal that card. Shuffle your library, then put the card on top of it.
- this.getSpellAbility().addEffect(new SearchLibraryPutOnLibraryEffect(new TargetCardInLibrary(new FilterCreatureCard()), true, true));
+ this.getSpellAbility().addEffect(new SearchLibraryPutOnLibraryEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_CREATURE), true, true));
}
public SylvanTutor(final SylvanTutor card) {
diff --git a/Mage.Sets/src/mage/cards/s/SyphonMind.java b/Mage.Sets/src/mage/cards/s/SyphonMind.java
index d66789f773a..820017992ae 100644
--- a/Mage.Sets/src/mage/cards/s/SyphonMind.java
+++ b/Mage.Sets/src/mage/cards/s/SyphonMind.java
@@ -1,7 +1,5 @@
-
package mage.cards.s;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
@@ -13,15 +11,15 @@ import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInHand;
+import java.util.UUID;
+
/**
- *
* @author jeffwadsworth
*/
public final class SyphonMind extends CardImpl {
public SyphonMind(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}");
// Each other player discards a card. You draw a card for each card discarded this way.
this.getSpellAbility().addEffect(new SyphonMindEffect());
@@ -60,8 +58,8 @@ class SyphonMindEffect extends OneShotEffect {
boolean result = false;
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
- for (UUID playerId : you.getInRange()) {
- if (!playerId.equals(source.getControllerId())) {
+ for (UUID playerId : game.getState().getPlayersInRange(you.getId(), game)) {
+ if (!playerId.equals(you.getId())) {
Player otherPlayer = game.getPlayer(playerId);
if (otherPlayer != null && !otherPlayer.getHand().isEmpty()) {
TargetCardInHand target = new TargetCardInHand();
@@ -77,7 +75,7 @@ class SyphonMindEffect extends OneShotEffect {
}
}
}
- }
+ }
you.drawCards(amount, game);
}
return result;
diff --git a/Mage.Sets/src/mage/cards/s/SyrAlinTheLionsClaw.java b/Mage.Sets/src/mage/cards/s/SyrAlinTheLionsClaw.java
new file mode 100644
index 00000000000..d34ae1e9f4d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SyrAlinTheLionsClaw.java
@@ -0,0 +1,47 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.effects.common.continuous.BoostControlledEffect;
+import mage.abilities.keyword.FirstStrikeAbility;
+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 java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SyrAlinTheLionsClaw extends CardImpl {
+
+ public SyrAlinTheLionsClaw(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(4);
+
+ // First strike
+ this.addAbility(FirstStrikeAbility.getInstance());
+
+ // Whenever Syr Alin, the Lion's Claw attacks, other creatures you control get +1/+1 until end of turn.
+ this.addAbility(new AttacksTriggeredAbility(new BoostControlledEffect(
+ 1, 1, Duration.EndOfTurn, true
+ ), false));
+ }
+
+ private SyrAlinTheLionsClaw(final SyrAlinTheLionsClaw card) {
+ super(card);
+ }
+
+ @Override
+ public SyrAlinTheLionsClaw copy() {
+ return new SyrAlinTheLionsClaw(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SyrCarahTheBold.java b/Mage.Sets/src/mage/cards/s/SyrCarahTheBold.java
new file mode 100644
index 00000000000..1a7a682d009
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SyrCarahTheBold.java
@@ -0,0 +1,160 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.AsThoughEffectImpl;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.game.stack.Spell;
+import mage.players.Library;
+import mage.players.Player;
+import mage.target.common.TargetAnyTarget;
+import mage.target.targetpointer.FixedTarget;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SyrCarahTheBold extends CardImpl {
+
+ public SyrCarahTheBold(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // When Syr Carah, the Bold or an instant or sorcery spell you control deals damage to a player, exile the top card of your library. You may play that card this turn.
+ this.addAbility(new SyrCarahTheBoldTriggeredAbility());
+
+ // {T}: Syr Carah deals 1 damage to any target.
+ Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(1), new TapSourceCost());
+ ability.addTarget(new TargetAnyTarget());
+ this.addAbility(ability);
+ }
+
+ private SyrCarahTheBold(final SyrCarahTheBold card) {
+ super(card);
+ }
+
+ @Override
+ public SyrCarahTheBold copy() {
+ return new SyrCarahTheBold(this);
+ }
+}
+
+class SyrCarahTheBoldTriggeredAbility extends TriggeredAbilityImpl {
+
+ SyrCarahTheBoldTriggeredAbility() {
+ super(Zone.BATTLEFIELD, new SyrCarahTheBoldExileEffect(), false);
+ }
+
+ private SyrCarahTheBoldTriggeredAbility(final SyrCarahTheBoldTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public SyrCarahTheBoldTriggeredAbility copy() {
+ return new SyrCarahTheBoldTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.DAMAGED_PLAYER;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ if (event.getSourceId().equals(this.getSourceId())) {
+ return true;
+ }
+ Spell spell = game.getSpellOrLKIStack(event.getSourceId());
+ return spell != null && spell.isInstantOrSorcery()
+ && spell.isControlledBy(this.getControllerId());
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever {this} or an instant or sorcery spell you control deals damage to a player, " +
+ "exile the top card of your library. You may play that card this turn.";
+ }
+
+}
+
+class SyrCarahTheBoldExileEffect extends OneShotEffect {
+
+ SyrCarahTheBoldExileEffect() {
+ super(Outcome.Detriment);
+ }
+
+ private SyrCarahTheBoldExileEffect(final SyrCarahTheBoldExileEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public SyrCarahTheBoldExileEffect copy() {
+ return new SyrCarahTheBoldExileEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
+ if (sourcePermanent == null || controller == null || !controller.getLibrary().hasCards()) {
+ return false;
+ }
+ Library library = controller.getLibrary();
+ Card card = library.getFromTop(game);
+ if (card == null) {
+ return true;
+ }
+ String exileName = sourcePermanent.getIdName() + " ";
+ controller.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName);
+ ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Duration.EndOfTurn);
+ effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game)));
+ game.addEffect(effect, source);
+ return true;
+ }
+}
+
+class SyrCarahTheBoldCastFromExileEffect extends AsThoughEffectImpl {
+
+ SyrCarahTheBoldCastFromExileEffect() {
+ super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
+ }
+
+ private SyrCarahTheBoldCastFromExileEffect(final SyrCarahTheBoldCastFromExileEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public SyrCarahTheBoldCastFromExileEffect copy() {
+ return new SyrCarahTheBoldCastFromExileEffect(this);
+ }
+
+ @Override
+ public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
+ return source.isControlledBy(affectedControllerId)
+ && objectId.equals(getTargetPointer().getFirst(game, source));
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SyrElenoraTheDiscerning.java b/Mage.Sets/src/mage/cards/s/SyrElenoraTheDiscerning.java
new file mode 100644
index 00000000000..0be67605193
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SyrElenoraTheDiscerning.java
@@ -0,0 +1,100 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.Mode;
+import mage.abilities.SpellAbility;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.common.CardsInControllerHandCount;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.continuous.SetPowerSourceEffect;
+import mage.abilities.effects.common.cost.CostModificationEffectImpl;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.target.Target;
+import mage.util.CardUtil;
+
+import java.util.Collection;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SyrElenoraTheDiscerning extends CardImpl {
+
+ public SyrElenoraTheDiscerning(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(4);
+
+ // Syr Elenora the Discerning's power is equal to the number of cards in your hand.
+ this.addAbility(new SimpleStaticAbility(
+ Zone.ALL, new SetPowerSourceEffect(CardsInControllerHandCount.instance, Duration.EndOfGame)
+ ));
+
+ // When Syr Elenora enters the battlefield, draw a card.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)));
+
+ // Spells your opponents cast that target Syr Elenora cost {2} more to cast.
+ this.addAbility(new SimpleStaticAbility(new SyrElenoraTheDiscerningCostIncreaseEffect()));
+ }
+
+ private SyrElenoraTheDiscerning(final SyrElenoraTheDiscerning card) {
+ super(card);
+ }
+
+ @Override
+ public SyrElenoraTheDiscerning copy() {
+ return new SyrElenoraTheDiscerning(this);
+ }
+}
+
+class SyrElenoraTheDiscerningCostIncreaseEffect extends CostModificationEffectImpl {
+
+ SyrElenoraTheDiscerningCostIncreaseEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.INCREASE_COST);
+ staticText = "Spells your opponents cast that target {this} cost {2} more to cast";
+ }
+
+ private SyrElenoraTheDiscerningCostIncreaseEffect(SyrElenoraTheDiscerningCostIncreaseEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source, Ability abilityToModify) {
+ SpellAbility spellAbility = (SpellAbility) abilityToModify;
+ CardUtil.adjustCost(spellAbility, -2);
+ return true;
+ }
+
+ @Override
+ public boolean applies(Ability abilityToModify, Ability source, Game game) {
+ if (!(abilityToModify instanceof SpellAbility)
+ || !game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) {
+ return false;
+ }
+ return abilityToModify
+ .getModes()
+ .getSelectedModes()
+ .stream()
+ .map(uuid -> abilityToModify.getModes().get(uuid))
+ .map(Mode::getTargets)
+ .flatMap(Collection::stream)
+ .map(Target::getTargets)
+ .flatMap(Collection::stream)
+ .anyMatch(uuid -> uuid.equals(source.getSourceId()));
+ }
+
+ @Override
+ public SyrElenoraTheDiscerningCostIncreaseEffect copy() {
+ return new SyrElenoraTheDiscerningCostIncreaseEffect(this);
+ }
+
+}
diff --git a/Mage.Sets/src/mage/cards/s/SyrFarenTheHengehammer.java b/Mage.Sets/src/mage/cards/s/SyrFarenTheHengehammer.java
new file mode 100644
index 00000000000..85b8461de3d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SyrFarenTheHengehammer.java
@@ -0,0 +1,60 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.SourcePermanentPowerCount;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterAttackingCreature;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SyrFarenTheHengehammer extends CardImpl {
+
+ private static final DynamicValue xValue = new SourcePermanentPowerCount();
+ private static final FilterPermanent filter
+ = new FilterAttackingCreature("another target attacking creature");
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ }
+
+ public SyrFarenTheHengehammer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{G}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Whenever Syr Faren, the Hengehammer attacks, another target attacking creature gets +X/+X until end of turn, where X is Syr Faren's power.
+ Ability ability = new AttacksTriggeredAbility(
+ new BoostTargetEffect(xValue, xValue, Duration.EndOfTurn, true), false
+ );
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(ability);
+ }
+
+ private SyrFarenTheHengehammer(final SyrFarenTheHengehammer card) {
+ super(card);
+ }
+
+ @Override
+ public SyrFarenTheHengehammer copy() {
+ return new SyrFarenTheHengehammer(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SyrGwynHeroOfAshvale.java b/Mage.Sets/src/mage/cards/s/SyrGwynHeroOfAshvale.java
new file mode 100644
index 00000000000..6034bc81491
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SyrGwynHeroOfAshvale.java
@@ -0,0 +1,79 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
+import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
+import mage.abilities.keyword.EquipFilterAbility;
+import mage.abilities.keyword.MenaceAbility;
+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.filter.FilterPermanent;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.permanent.EquippedPredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SyrGwynHeroOfAshvale extends CardImpl {
+
+ private static final FilterControlledCreaturePermanent filter
+ = new FilterControlledCreaturePermanent("an equipped creature you control");
+ private static final FilterPermanent filter2
+ = new FilterControlledPermanent(SubType.EQUIPMENT);
+ private static final FilterControlledCreaturePermanent filter3
+ = new FilterControlledCreaturePermanent(SubType.KNIGHT, "Knight");
+
+ static {
+ filter.add(EquippedPredicate.instance);
+ }
+
+ public SyrGwynHeroOfAshvale(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{W}{B}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(5);
+
+ // Vigilance
+ this.addAbility(VigilanceAbility.getInstance());
+
+ // Menace
+ this.addAbility(new MenaceAbility());
+
+ // Whenever an equipped creature you control attacks, you draw a card and you lose 1 life.
+ Ability ability = new AttacksCreatureYouControlTriggeredAbility(
+ new DrawCardSourceControllerEffect(1).setText("you draw a card and"), false, filter
+ );
+ ability.addEffect(new LoseLifeSourceControllerEffect(1));
+ this.addAbility(ability);
+
+ // Equipment you control have equip Knight {0}.
+ this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
+ new EquipFilterAbility(filter3, new GenericManaCost(0)), Duration.WhileOnBattlefield, filter2
+ )));
+ }
+
+ private SyrGwynHeroOfAshvale(final SyrGwynHeroOfAshvale card) {
+ super(card);
+ }
+
+ @Override
+ public SyrGwynHeroOfAshvale copy() {
+ return new SyrGwynHeroOfAshvale(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SyrKonradTheGrim.java b/Mage.Sets/src/mage/cards/s/SyrKonradTheGrim.java
new file mode 100644
index 00000000000..967fc744528
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SyrKonradTheGrim.java
@@ -0,0 +1,102 @@
+package mage.cards.s;
+
+import mage.MageInt;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DamagePlayersEffect;
+import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveEachPlayerEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.events.ZoneChangeEvent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SyrKonradTheGrim extends CardImpl {
+
+ public SyrKonradTheGrim(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(4);
+
+ // Whenever another creature dies, or a creature card is put into a graveyard from anywhere other than the battlefield, or a creature card leaves your graveyard, Syr Konrad, the Grim deals 1 damage to each opponent.
+ this.addAbility(new SyrKonradTheGrimTriggeredAbility());
+
+ // {1}{B}: Each player puts the top card of their library into their graveyard.
+ this.addAbility(new SimpleActivatedAbility(new PutTopCardOfLibraryIntoGraveEachPlayerEffect(
+ 1, TargetController.ANY
+ ), new ManaCostsImpl("{1}{B}")));
+ }
+
+ private SyrKonradTheGrim(final SyrKonradTheGrim card) {
+ super(card);
+ }
+
+ @Override
+ public SyrKonradTheGrim copy() {
+ return new SyrKonradTheGrim(this);
+ }
+}
+
+class SyrKonradTheGrimTriggeredAbility extends TriggeredAbilityImpl {
+
+ SyrKonradTheGrimTriggeredAbility() {
+ super(Zone.BATTLEFIELD, new DamagePlayersEffect(1, TargetController.OPPONENT));
+ }
+
+ private SyrKonradTheGrimTriggeredAbility(final SyrKonradTheGrimTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public SyrKonradTheGrimTriggeredAbility copy() {
+ return new SyrKonradTheGrimTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.ZONE_CHANGE;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
+ // Whenever another creature dies
+ if (zEvent.isDiesEvent()
+ && zEvent.getTarget() != null
+ && !zEvent.getTargetId().equals(this.getSourceId())
+ && zEvent.getTarget().isCreature()) {
+ return true;
+ }
+ Card card = game.getCard(zEvent.getTargetId());
+ // Or a creature card is put into a graveyard from anywhere other than the battlefield
+ if (card == null || !card.isCreature()) {
+ return false;
+ }
+ if (zEvent.getToZone() == Zone.GRAVEYARD
+ && zEvent.getFromZone() != Zone.BATTLEFIELD) {
+ return true;
+ }
+ // Or a creature card leaves your graveyard
+ return zEvent.getFromZone() == Zone.GRAVEYARD
+ && zEvent.getPlayerId() == this.getControllerId();
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever another creature dies, or a creature card is put into a graveyard " +
+ "from anywhere other than the battlefield, or a creature card leaves your graveyard, " +
+ "{this} deals 1 damage to each opponent.";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TahngarthFirstMate.java b/Mage.Sets/src/mage/cards/t/TahngarthFirstMate.java
new file mode 100644
index 00000000000..693bf559f08
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TahngarthFirstMate.java
@@ -0,0 +1,157 @@
+package mage.cards.t;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.combat.CantBeBlockedByMoreThanOneSourceEffect;
+import mage.abilities.effects.common.continuous.GainControlTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.common.FilterPlayerOrPlaneswalker;
+import mage.filter.predicate.Predicate;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.common.TargetPlayerOrPlaneswalker;
+import mage.target.targetpointer.FixedTarget;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TahngarthFirstMate extends CardImpl {
+
+ public TahngarthFirstMate(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{G}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.MINOTAUR);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(5);
+
+ // Tahngarth, First Mate can't be blocked by more than one creature.
+ this.addAbility(new SimpleStaticAbility(new CantBeBlockedByMoreThanOneSourceEffect()));
+
+ // Whenever an opponent attacks with one or more creatures, if Tahngarth is tapped, you may have that opponent gain control of Tahngarth until end of combat. If you do, choose a player or planeswalker that opponent is attacking. Tahngarth is attacking that player or planeswalker.
+ this.addAbility(new TahngarthFirstMateTriggeredAbility());
+ }
+
+ private TahngarthFirstMate(final TahngarthFirstMate card) {
+ super(card);
+ }
+
+ @Override
+ public TahngarthFirstMate copy() {
+ return new TahngarthFirstMate(this);
+ }
+}
+
+class TahngarthFirstMateTriggeredAbility extends TriggeredAbilityImpl {
+
+ TahngarthFirstMateTriggeredAbility() {
+ super(Zone.BATTLEFIELD, new TahngarthFirstMateEffect(), true);
+ }
+
+ private TahngarthFirstMateTriggeredAbility(final TahngarthFirstMateTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public TahngarthFirstMateTriggeredAbility copy() {
+ return new TahngarthFirstMateTriggeredAbility(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.getOpponents(getControllerId()).contains(game.getActivePlayerId())
+ && !game.getCombat().getAttackers().isEmpty();
+ }
+
+ @Override
+ public boolean checkInterveningIfClause(Game game) {
+ Permanent permanent = game.getPermanent(getSourceId());
+ return permanent != null && permanent.isTapped();
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever an opponent attacks with one or more creatures, " +
+ "if {this} is tapped, you may have that opponent gain control of {this} until end of combat. " +
+ "If you do, choose a player or planeswalker that opponent is attacking. " +
+ "{this} is attacking that player or planeswalker.";
+ }
+}
+
+class TahngarthFirstMateEffect extends OneShotEffect {
+
+ private static final FilterPlayerOrPlaneswalker filter
+ = new FilterPlayerOrPlaneswalker("player or planeswalker active player is attacking");
+
+ static {
+ filter.getPlayerFilter().add(TahngarthFirstMatePlayerPredicate.instance);
+ filter.getPermanentFilter().add(TahngarthFirstMatePermanentPredicate.instance);
+ }
+
+ TahngarthFirstMateEffect() {
+ super(Outcome.Benefit);
+ }
+
+ private TahngarthFirstMateEffect(final TahngarthFirstMateEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public TahngarthFirstMateEffect copy() {
+ return new TahngarthFirstMateEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Player player = game.getPlayer(game.getActivePlayerId());
+ Permanent permanent = game.getPermanent(source.getSourceId());
+ if (controller == null || player == null || permanent == null) {
+ return false;
+ }
+ TargetPlayerOrPlaneswalker target = new TargetPlayerOrPlaneswalker(filter);
+ target.setNotTarget(true);
+ if (!controller.choose(outcome, target, source.getSourceId(), game)) {
+ return false;
+ }
+ ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfCombat, player.getId());
+ effect.setTargetPointer(new FixedTarget(permanent, game));
+ game.addEffect(effect, source);
+ game.applyEffects();
+ return game.getCombat().addAttackerToCombat(permanent.getId(), target.getFirstTarget(), game);
+ }
+}
+
+enum TahngarthFirstMatePlayerPredicate implements Predicate {
+ instance;
+
+ @Override
+ public boolean apply(Player input, Game game) {
+ return game.getCombat().getDefenders().contains(input.getId());
+ }
+}
+
+enum TahngarthFirstMatePermanentPredicate implements Predicate {
+ instance;
+
+ @Override
+ public boolean apply(Permanent input, Game game) {
+ return game.getCombat().getDefenders().contains(input.getId());
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/t/TajuruPreserver.java b/Mage.Sets/src/mage/cards/t/TajuruPreserver.java
index 27f8fac2ced..205342ceab5 100644
--- a/Mage.Sets/src/mage/cards/t/TajuruPreserver.java
+++ b/Mage.Sets/src/mage/cards/t/TajuruPreserver.java
@@ -1,9 +1,6 @@
-
package mage.cards.t;
-import java.util.UUID;
import mage.MageInt;
-import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl;
@@ -13,8 +10,9 @@ import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
-import mage.game.permanent.PermanentCard;
-import mage.game.stack.Spell;
+import mage.players.Player;
+
+import java.util.UUID;
/**
* @author noxx
@@ -22,7 +20,7 @@ import mage.game.stack.Spell;
public final class TajuruPreserver extends CardImpl {
public TajuruPreserver(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.ELF);
this.subtype.add(SubType.SHAMAN);
@@ -63,28 +61,22 @@ class TajuruPreserverEffect extends ReplacementEffectImpl {
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
return true;
}
-
+
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICE_PERMANENT;
- }
+ }
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
+ Player controller = game.getPlayer(source.getControllerId());
+ UUID eventSourceControllerId = game.getControllerId(event.getSourceId());
Permanent permanent = game.getPermanent(event.getTargetId());
- if (permanent != null && permanent.isControlledBy(source.getControllerId())) {
- MageObject object = game.getObject(event.getSourceId());
- if (object instanceof PermanentCard) {
- if (game.getOpponents(source.getControllerId()).contains(((PermanentCard)object).getControllerId())) {
- return true;
- }
- }
- if (object instanceof Spell) {
- if (game.getOpponents(source.getControllerId()).contains(((Spell)object).getControllerId())) {
- return true;
- }
- }
+
+ if (controller != null && permanent != null && permanent.getControllerId() == source.getControllerId()) {
+ return game.getOpponents(source.getControllerId()).contains(eventSourceControllerId);
}
+
return false;
}
diff --git a/Mage.Sets/src/mage/cards/t/TalentOfTheTelepath.java b/Mage.Sets/src/mage/cards/t/TalentOfTheTelepath.java
index 5751791d2e4..9c68824eb1b 100644
--- a/Mage.Sets/src/mage/cards/t/TalentOfTheTelepath.java
+++ b/Mage.Sets/src/mage/cards/t/TalentOfTheTelepath.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.Set;
@@ -32,8 +31,12 @@ public final class TalentOfTheTelepath extends CardImpl {
public TalentOfTheTelepath(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}{U}");
- // Target opponent reveals the top seven cards of their library. You may cast an instant or sorcery card from among them without paying its mana cost. Then that player puts the rest into their graveyard.
- // Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, you may cast up to two revealed instant and/or sorcery cards instead of one.
+ // Target opponent reveals the top seven cards of their library.
+ // You may cast an instant or sorcery card from among them without paying
+ // its mana cost. Then that player puts the rest into their graveyard.
+ // Spell mastery — If there are two or more instant and/or
+ // sorcery cards in your graveyard, you may cast up to two revealed instant
+ // and/or sorcery cards instead of one.
getSpellAbility().addEffect(new TalentOfTheTelepathEffect());
getSpellAbility().addTarget(new TargetOpponent());
@@ -55,8 +58,12 @@ class TalentOfTheTelepathEffect extends OneShotEffect {
public TalentOfTheTelepathEffect() {
super(Outcome.PlayForFree);
- this.staticText = "Target opponent reveals the top seven cards of their library. You may cast an instant or sorcery card from among them without paying its mana cost. Then that player puts the rest into their graveyard. "
- + "
Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, you may cast up to two revealed instant and/or sorcery cards instead of one.";
+ this.staticText = "Target opponent reveals the top seven cards of their "
+ + "library. You may cast an instant or sorcery card from among them "
+ + "without paying its mana cost. Then that player puts the rest into their graveyard. "
+ + "
Spell mastery — If there are two or more instant "
+ + "and/or sorcery cards in your graveyard, you may cast up to two "
+ + "revealed instant and/or sorcery cards instead of one.";
}
public TalentOfTheTelepathEffect(final TalentOfTheTelepathEffect effect) {
@@ -76,7 +83,8 @@ class TalentOfTheTelepathEffect extends OneShotEffect {
if (targetOpponent != null && sourceObject != null) {
Set allCards = targetOpponent.getLibrary().getTopCards(game, 7);
Cards cards = new CardsImpl(allCards);
- targetOpponent.revealCards(sourceObject.getIdName() + " - " + targetOpponent.getName() + "'s top library cards", cards, game);
+ targetOpponent.revealCards(sourceObject.getIdName() + " - "
+ + targetOpponent.getName() + "'s top library cards", cards, game);
for (Card card : allCards) {
if (filter.match(card, game)) {
cardsToCast.add(card);
@@ -95,14 +103,20 @@ class TalentOfTheTelepathEffect extends OneShotEffect {
target.setNotTarget(true);
while (numberOfSpells > 0
&& !cardsToCast.isEmpty()
- && controller.chooseUse(outcome, "Cast an instant or sorcery card from among them for free?", source, game)
- && controller.choose(outcome, cardsToCast, target, game)) {
+ && controller.chooseUse(outcome, "Cast an instant or sorcery card "
+ + "from among them for free?", source, game)
+ && controller.choose(Outcome.PlayForFree, cardsToCast, target, game)) {
Card card = cardsToCast.get(target.getFirstTarget(), game);
if (card != null) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
- numberOfSpells--;
- cardsToCast.remove(card);
- allCards.remove(card);
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (cardWasCast) {
+ numberOfSpells--;
+ cardsToCast.remove(card);
+ allCards.remove(card);
+ }
}
if (!controller.canRespond()) {
return false;
diff --git a/Mage.Sets/src/mage/cards/t/TallAsABeanstalk.java b/Mage.Sets/src/mage/cards/t/TallAsABeanstalk.java
new file mode 100644
index 00000000000..fbb5509206b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TallAsABeanstalk.java
@@ -0,0 +1,57 @@
+package mage.cards.t;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.continuous.AddCardSubtypeAttachedEffect;
+import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.abilities.keyword.ReachAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TallAsABeanstalk extends CardImpl {
+
+ public TallAsABeanstalk(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));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // Enchanted creature gets +3/+3, has reach, and is a Giant in addition to its other types.
+ ability = new SimpleStaticAbility(
+ new BoostEnchantedEffect(3, 3).setText("enchanted creature gets +3/+3,")
+ );
+ ability.addEffect(new GainAbilityAttachedEffect(
+ ReachAbility.getInstance(), AttachmentType.AURA
+ ).setText("has reach,"));
+ ability.addEffect(new AddCardSubtypeAttachedEffect(
+ SubType.GIANT, Duration.WhileOnBattlefield, AttachmentType.AURA
+ ).setText("and is a Giant in addition to its other types"));
+ this.addAbility(ability);
+ }
+
+ private TallAsABeanstalk(final TallAsABeanstalk card) {
+ super(card);
+ }
+
+ @Override
+ public TallAsABeanstalk copy() {
+ return new TallAsABeanstalk(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TamiyoCollectorOfTales.java b/Mage.Sets/src/mage/cards/t/TamiyoCollectorOfTales.java
index b2352caa2ec..ce2b23fde24 100644
--- a/Mage.Sets/src/mage/cards/t/TamiyoCollectorOfTales.java
+++ b/Mage.Sets/src/mage/cards/t/TamiyoCollectorOfTales.java
@@ -1,6 +1,5 @@
package mage.cards.t;
-import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
@@ -15,9 +14,7 @@ import mage.choices.ChoiceImpl;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
-import mage.game.permanent.PermanentCard;
-import mage.game.stack.Spell;
-import mage.game.stack.StackAbility;
+import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
@@ -63,8 +60,8 @@ class TamiyoCollectorOfTalesRuleEffect extends ContinuousRuleModifyingEffectImpl
TamiyoCollectorOfTalesRuleEffect() {
super(Duration.WhileOnBattlefield, Benefit);
- staticText = "Spells and abilities your opponents control can't " +
- "cause you to discard cards or sacrifice permanents";
+ staticText = "Spells and abilities your opponents control can't "
+ + "cause you to discard cards or sacrifice permanents";
}
private TamiyoCollectorOfTalesRuleEffect(final TamiyoCollectorOfTalesRuleEffect effect) {
@@ -84,28 +81,17 @@ class TamiyoCollectorOfTalesRuleEffect extends ContinuousRuleModifyingEffectImpl
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
- if (event.getPlayerId().equals(source.getControllerId())) {
- MageObject object = game.getObject(event.getSourceId());
- if (object instanceof PermanentCard) {
- if (game.getOpponents(source.getControllerId()).contains(((PermanentCard) object).getControllerId())) {
- return true;
- }
- }
- if (object instanceof Spell) {
- if (game.getOpponents(source.getControllerId()).contains(((Spell) object).getControllerId())) {
- return true;
- }
- }
- if (object instanceof Card) {
- if (game.getOpponents(source.getControllerId()).contains(((Card) object).getOwnerId())) {
- return true;
- }
- }
- if (object instanceof StackAbility) {
- if (game.getOpponents(source.getControllerId()).contains(((StackAbility) object).getControllerId())) {
- return true;
- }
- }
+ Player controller = game.getPlayer(source.getControllerId());
+ UUID eventSourceControllerId = game.getControllerId(event.getSourceId());
+
+ Permanent permanent = game.getPermanent(event.getTargetId());
+ if (controller != null && permanent != null && permanent.getControllerId() == source.getControllerId()) {
+ return game.getOpponents(source.getControllerId()).contains(eventSourceControllerId);
+ }
+
+ Card cardInHand = game.getCard(event.getTargetId());
+ if (controller != null && cardInHand != null && cardInHand.getOwnerId() == source.getControllerId()) {
+ return game.getOpponents(source.getControllerId()).contains(eventSourceControllerId);
}
return false;
}
@@ -115,8 +101,8 @@ class TamiyoCollectorOfTalesEffect extends OneShotEffect {
TamiyoCollectorOfTalesEffect() {
super(Outcome.Benefit);
- staticText = "Choose a nonland card name, then reveal the top four cards of your library. " +
- "Put all cards with the chosen name from among them into your hand and the rest into your graveyard.";
+ staticText = "Choose a nonland card name, then reveal the top four cards of your library. "
+ + "Put all cards with the chosen name from among them into your hand and the rest into your graveyard.";
}
private TamiyoCollectorOfTalesEffect(final TamiyoCollectorOfTalesEffect effect) {
@@ -145,6 +131,12 @@ class TamiyoCollectorOfTalesEffect extends OneShotEffect {
Cards cards2 = new CardsImpl();
player.revealCards(source, cards, game);
for (Card card : cards.getCards(game)) {
+ if (card.isSplitCard()) {
+ if (((SplitCard) card).getLeftHalfCard().getName().equals(choice.getChoice())
+ || ((SplitCard) card).getRightHalfCard().getName().equals(choice.getChoice())) {
+ cards2.add(card);
+ }
+ }
if (card.getName().equals(choice.getChoice())) {
cards2.add(card);
}
@@ -154,4 +146,5 @@ class TamiyoCollectorOfTalesEffect extends OneShotEffect {
player.moveCards(cards2, Zone.HAND, source, game);
return true;
}
-}
\ No newline at end of file
+
+}
diff --git a/Mage.Sets/src/mage/cards/t/TangleWire.java b/Mage.Sets/src/mage/cards/t/TangleWire.java
index befb444899a..7f084991328 100644
--- a/Mage.Sets/src/mage/cards/t/TangleWire.java
+++ b/Mage.Sets/src/mage/cards/t/TangleWire.java
@@ -34,7 +34,7 @@ public final class TangleWire extends CardImpl {
// Fading 4
this.addAbility(new FadingAbility(4, this));
- // At the beginning of each player's upkeep, that player taps an untapped artifact, creature, or land he or she controls for each fade counter on Tangle Wire.
+ // At the beginning of each player's upkeep, that player taps an untapped artifact, creature, or land they control for each fade counter on Tangle Wire.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new TangleWireEffect(), TargetController.ANY, false, true));
}
@@ -49,7 +49,7 @@ public final class TangleWire extends CardImpl {
}
class TangleWireEffect extends OneShotEffect {
- private static final FilterControlledPermanent filter = new FilterControlledPermanent("untapped artifact, creature, or land he or she controls");
+ private static final FilterControlledPermanent filter = new FilterControlledPermanent("untapped artifact, creature, or land they control");
static{
filter.add(Predicates.not(TappedPredicate.instance));
filter.add(Predicates.or(
@@ -60,7 +60,7 @@ class TangleWireEffect extends OneShotEffect {
TangleWireEffect() {
super(Outcome.Sacrifice);
- staticText = "that player taps an untapped artifact, creature, or land he or she controls for each fade counter on Tangle Wire";
+ staticText = "that player taps an untapped artifact, creature, or land they control for each fade counter on Tangle Wire";
}
TangleWireEffect(final TangleWireEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/t/TarielReckonerOfSouls.java b/Mage.Sets/src/mage/cards/t/TarielReckonerOfSouls.java
index 4419c28ba58..12963524942 100644
--- a/Mage.Sets/src/mage/cards/t/TarielReckonerOfSouls.java
+++ b/Mage.Sets/src/mage/cards/t/TarielReckonerOfSouls.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.UUID;
@@ -11,11 +10,11 @@ import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.*;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetOpponent;
@@ -76,7 +75,7 @@ class TarielReckonerOfSoulsEffect extends OneShotEffect {
Player targetOpponent = game.getPlayer(getTargetPointer().getFirst(game, source));
if (controller != null && targetOpponent != null) {
Cards creatureCards = new CardsImpl();
- for (Card card : targetOpponent.getGraveyard().getCards(new FilterCreatureCard(), game)) {
+ for (Card card : targetOpponent.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game)) {
creatureCards.add(card);
}
if (!creatureCards.isEmpty()) {
diff --git a/Mage.Sets/src/mage/cards/t/Tariff.java b/Mage.Sets/src/mage/cards/t/Tariff.java
index 04ca7709ae7..88ba621659b 100644
--- a/Mage.Sets/src/mage/cards/t/Tariff.java
+++ b/Mage.Sets/src/mage/cards/t/Tariff.java
@@ -1,9 +1,5 @@
-
package mage.cards.t;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCosts;
@@ -24,17 +20,20 @@ import mage.players.Player;
import mage.players.PlayerList;
import mage.target.TargetCard;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
/**
- *
* @author Quercitron
*/
public final class Tariff extends CardImpl {
public Tariff(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{W}");
- // Each player sacrifices the creature he or she controls with the highest converted mana cost unless he or she pays that creature's mana cost. If two or more creatures a player controls are tied for highest cost, that player chooses one.
+ // Each player sacrifices the creature they control with the highest converted mana cost unless they pay that creature's mana cost. If two or more creatures a player controls are tied for highest cost, that player chooses one.
this.getSpellAbility().addEffect(new TariffEffect());
}
@@ -49,12 +48,12 @@ public final class Tariff extends CardImpl {
}
class TariffEffect extends OneShotEffect {
-
+
public TariffEffect() {
super(Outcome.DestroyPermanent);
- this.staticText = "Each player sacrifices the creature he or she controls with the highest converted mana cost unless he or she pays that creature's mana cost. If two or more creatures a player controls are tied for highest cost, that player chooses one.";
+ this.staticText = "Each player sacrifices the creature they control with the highest converted mana cost unless they pay that creature's mana cost. If two or more creatures a player controls are tied for highest cost, that player chooses one.";
}
-
+
public TariffEffect(final TariffEffect effect) {
super(effect);
}
@@ -63,21 +62,20 @@ class TariffEffect extends OneShotEffect {
public TariffEffect copy() {
return new TariffEffect(this);
}
-
+
@Override
public boolean apply(Game game, Ability source) {
PlayerList playerList = game.getPlayerList().copy();
playerList.setCurrent(game.getActivePlayerId());
Player player = game.getPlayer(game.getActivePlayerId());
-
do {
processPlayer(game, source, player);
- player = playerList.getNext(game);
+ player = playerList.getNext(game, false);
} while (!player.getId().equals(game.getActivePlayerId()));
-
+
return true;
}
-
+
private void processPlayer(Game game, Ability source, Player player) {
MageObject sourceObject = game.getObject(source.getSourceId());
@@ -100,7 +98,7 @@ class TariffEffect extends OneShotEffect {
creatureToPayFor.sacrifice(source.getSourceId(), game);
}
}
-
+
private List getPermanentsWithTheHighestCMC(Game game, UUID playerId, FilterPermanent filter) {
List permanents = game.getBattlefield().getAllActivePermanents(filter, playerId, game);
int highestCMC = -1;
@@ -135,5 +133,5 @@ class TariffEffect extends OneShotEffect {
}
return permanent;
}
-
+
}
diff --git a/Mage.Sets/src/mage/cards/t/TaskMageAssembly.java b/Mage.Sets/src/mage/cards/t/TaskMageAssembly.java
index d1e5947df39..13a75268898 100644
--- a/Mage.Sets/src/mage/cards/t/TaskMageAssembly.java
+++ b/Mage.Sets/src/mage/cards/t/TaskMageAssembly.java
@@ -31,7 +31,7 @@ public final class TaskMageAssembly extends CardImpl {
// When there are no creatures on the battlefield, sacrifice Task Mage Assembly.
this.addAbility(new TaskMageAssemblyStateTriggeredAbility());
- // {2}: Task Mage Assembly deals 1 damage to target creature. Any player may activate this ability but only any time he or she could cast a sorcery.
+ // {2}: Task Mage Assembly deals 1 damage to target creature. Any player may activate this ability but only any time they could cast a sorcery.
ActivateAsSorceryActivatedAbility ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{2}"));
ability.addTarget(new TargetCreaturePermanent());
ability.setMayActivate(TargetController.ANY);
diff --git a/Mage.Sets/src/mage/cards/t/TasteOfDeath.java b/Mage.Sets/src/mage/cards/t/TasteOfDeath.java
new file mode 100644
index 00000000000..21cb865cc0f
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TasteOfDeath.java
@@ -0,0 +1,37 @@
+package mage.cards.t;
+
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.SacrificeAllEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.game.permanent.token.FoodToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TasteOfDeath extends CardImpl {
+
+ private static final FilterControlledPermanent filter = new FilterControlledCreaturePermanent("creatures");
+
+ public TasteOfDeath(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}{B}");
+
+ // Each player sacrifices three creatures. You create three Food tokens.
+ this.getSpellAbility().addEffect(new SacrificeAllEffect(3, filter));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new FoodToken(), 3).concatBy("You"));
+ }
+
+ private TasteOfDeath(final TasteOfDeath card) {
+ super(card);
+ }
+
+ @Override
+ public TasteOfDeath copy() {
+ return new TasteOfDeath(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TectonicHellion.java b/Mage.Sets/src/mage/cards/t/TectonicHellion.java
index 0bb8208f515..d6757793bb5 100644
--- a/Mage.Sets/src/mage/cards/t/TectonicHellion.java
+++ b/Mage.Sets/src/mage/cards/t/TectonicHellion.java
@@ -70,9 +70,8 @@ class TectonicHellionEffect extends OneShotEffect {
Map landMap = new HashMap<>();
game.getState()
.getPlayersInRange(source.getControllerId(), game)
- .stream()
- .map(uuid -> landMap.put(uuid, game.getBattlefield().getActivePermanents(
- StaticFilters.FILTER_LAND, uuid, source.getSourceId(), game
+ .forEach(uuid -> landMap.put(uuid, game.getBattlefield().getActivePermanents(
+ StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND, uuid, source.getSourceId(), game
).size()));
int max = landMap
.values()
diff --git a/Mage.Sets/src/mage/cards/t/TeferiMageOfZhalfir.java b/Mage.Sets/src/mage/cards/t/TeferiMageOfZhalfir.java
index e1efa6ce2df..b968489bbac 100644
--- a/Mage.Sets/src/mage/cards/t/TeferiMageOfZhalfir.java
+++ b/Mage.Sets/src/mage/cards/t/TeferiMageOfZhalfir.java
@@ -37,7 +37,7 @@ public final class TeferiMageOfZhalfir extends CardImpl {
// Creature cards you own that aren't on the battlefield have flash.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TeferiMageOfZhalfirAddFlashEffect()));
- // Each opponent can cast spells only any time he or she could cast a sorcery.
+ // Each opponent can cast spells only any time they could cast a sorcery.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TeferiMageOfZhalfirReplacementEffect()));
}
diff --git a/Mage.Sets/src/mage/cards/t/TeleminPerformance.java b/Mage.Sets/src/mage/cards/t/TeleminPerformance.java
index aafbc313c97..b1b7aca67ae 100644
--- a/Mage.Sets/src/mage/cards/t/TeleminPerformance.java
+++ b/Mage.Sets/src/mage/cards/t/TeleminPerformance.java
@@ -24,7 +24,7 @@ public final class TeleminPerformance extends CardImpl {
public TeleminPerformance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}{U}");
- // Target opponent reveals cards from the top of their library until he or she reveals a creature card. That player puts all noncreature cards revealed this way into their graveyard, then you put the creature card onto the battlefield under your control.
+ // Target opponent reveals cards from the top of their library until they reveal a creature card. That player puts all noncreature cards revealed this way into their graveyard, then you put the creature card onto the battlefield under your control.
this.getSpellAbility().addEffect(new TeleminPerformanceEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
@@ -44,7 +44,7 @@ class TeleminPerformanceEffect extends OneShotEffect {
public TeleminPerformanceEffect() {
super(Outcome.PutCreatureInPlay);
- this.staticText = "Target opponent reveals cards from the top of their library until he or she reveals a creature card. That player puts all noncreature cards revealed this way into their graveyard, then you put the creature card onto the battlefield under your control";
+ this.staticText = "Target opponent reveals cards from the top of their library until they reveal a creature card. That player puts all noncreature cards revealed this way into their graveyard, then you put the creature card onto the battlefield under your control";
}
public TeleminPerformanceEffect(final TeleminPerformanceEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/t/Temper.java b/Mage.Sets/src/mage/cards/t/Temper.java
index b0bdd776b14..6ce5de5ee15 100644
--- a/Mage.Sets/src/mage/cards/t/Temper.java
+++ b/Mage.Sets/src/mage/cards/t/Temper.java
@@ -1,7 +1,5 @@
-
package mage.cards.t;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
@@ -12,12 +10,15 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.counters.CounterType;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author TheElk801
*/
public final class Temper extends CardImpl {
@@ -76,7 +77,7 @@ class TemperPreventDamageTargetEffect extends PreventionEffectImpl {
amount = dVal.calculate(game, source, this);
initialized = true;
}
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int prevented = 0;
if (event.getAmount() >= this.amount) {
@@ -109,9 +110,7 @@ class TemperPreventDamageTargetEffect extends PreventionEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!this.used && super.applies(event, source, game)) {
- if (source.getTargets().getFirstTarget().equals(event.getTargetId())) {
- return true;
- }
+ return source.getTargets().getFirstTarget().equals(event.getTargetId());
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/t/TemptWithGlory.java b/Mage.Sets/src/mage/cards/t/TemptWithGlory.java
index fb01c2d2bde..9a5c6e5c096 100644
--- a/Mage.Sets/src/mage/cards/t/TemptWithGlory.java
+++ b/Mage.Sets/src/mage/cards/t/TemptWithGlory.java
@@ -24,7 +24,7 @@ public final class TemptWithGlory extends CardImpl {
public TemptWithGlory(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{W}");
- // Tempting offer - Put a +1/+1 counter on each creature you control. Each opponent may put a +1/+1 counter on each creature he or she controls. For each opponent who does, put a +1/+1 counter on each creature you control.
+ // Tempting offer - Put a +1/+1 counter on each creature you control. Each opponent may put a +1/+1 counter on each creature they control. For each opponent who does, put a +1/+1 counter on each creature you control.
this.getSpellAbility().addEffect(new TemptWithGloryEffect());
}
@@ -45,7 +45,7 @@ class TemptWithGloryEffect extends OneShotEffect {
public TemptWithGloryEffect() {
super(Outcome.PutLandInPlay);
- this.staticText = "Tempting offer — Put a +1/+1 counter on each creature you control. Each opponent may put a +1/+1 counter on each creature he or she controls. For each opponent who does, put a +1/+1 counter on each creature you control";
+ this.staticText = "Tempting offer — Put a +1/+1 counter on each creature you control. Each opponent may put a +1/+1 counter on each creature they control. For each opponent who does, put a +1/+1 counter on each creature you control";
}
public TemptWithGloryEffect(final TemptWithGloryEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/t/TemptWithImmortality.java b/Mage.Sets/src/mage/cards/t/TemptWithImmortality.java
index ad8c586bcad..fb9e6f0cf0a 100644
--- a/Mage.Sets/src/mage/cards/t/TemptWithImmortality.java
+++ b/Mage.Sets/src/mage/cards/t/TemptWithImmortality.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.UUID;
@@ -11,6 +10,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.other.OwnerIdPredicate;
import mage.game.Game;
@@ -26,7 +26,7 @@ import mage.target.common.TargetCardInYourGraveyard;
public final class TemptWithImmortality extends CardImpl {
public TemptWithImmortality(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}");
// Tempting offer - Return a creature card from your graveyard to the battlefield. Each opponent may return a creature card from their graveyard to the battlefield. For each opponent who does, return a creature card from your graveyard to the battlefield.
this.getSpellAbility().addEffect(new TemptWithImmortalityEffect());
@@ -98,7 +98,7 @@ class TemptWithImmortalityEffect extends OneShotEffect {
}
private boolean returnCreatureFromGraveToBattlefield(Player player, Ability source, Game game) {
- Target target = new TargetCardInYourGraveyard(new FilterCreatureCard());
+ Target target = new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE);
target.setNotTarget(false);
if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
if (player.chooseTarget(outcome, target, source, game)) {
diff --git a/Mage.Sets/src/mage/cards/t/TemptWithReflections.java b/Mage.Sets/src/mage/cards/t/TemptWithReflections.java
index 7c644e6bd03..8df6b4f317d 100644
--- a/Mage.Sets/src/mage/cards/t/TemptWithReflections.java
+++ b/Mage.Sets/src/mage/cards/t/TemptWithReflections.java
@@ -1,9 +1,5 @@
-
package mage.cards.t;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
@@ -18,8 +14,11 @@ import mage.players.Player;
import mage.players.PlayerList;
import mage.target.common.TargetControlledCreaturePermanent;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class TemptWithReflections extends CardImpl {
@@ -81,7 +80,7 @@ class TemptWithReflectionsEffect extends OneShotEffect {
}
game.informPlayers((player.getLogName() + decision + permanent.getName()));
}
- player = playerList.getNext(game);
+ player = playerList.getNext(game, false);
} while (!player.getId().equals(game.getActivePlayerId()));
for (UUID playerId : playersSaidYes) {
diff --git a/Mage.Sets/src/mage/cards/t/TemptingWitch.java b/Mage.Sets/src/mage/cards/t/TemptingWitch.java
new file mode 100644
index 00000000000..2af415f5284
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TemptingWitch.java
@@ -0,0 +1,59 @@
+package mage.cards.t;
+
+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.common.TapSourceCost;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.LoseLifeTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.common.FilterControlledPermanent;
+import mage.game.permanent.token.FoodToken;
+import mage.target.TargetPlayer;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TemptingWitch extends CardImpl {
+
+ private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.FOOD, "a Food");
+
+ public TemptingWitch(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.WARLOCK);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(3);
+
+ // When Tempting Witch enters the battlefield, create a Food token.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new FoodToken())));
+
+ // {2}, {T}, Sacrifice a Food: Target player loses 3 life.
+ Ability ability = new SimpleActivatedAbility(
+ new LoseLifeTargetEffect(3), new GenericManaCost(2)
+ );
+ ability.addCost(new TapSourceCost());
+ ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter)));
+ ability.addTarget(new TargetPlayer());
+ this.addAbility(ability);
+ }
+
+ private TemptingWitch(final TemptingWitch card) {
+ super(card);
+ }
+
+ @Override
+ public TemptingWitch copy() {
+ return new TemptingWitch(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TerrorOfMountVelus.java b/Mage.Sets/src/mage/cards/t/TerrorOfMountVelus.java
new file mode 100644
index 00000000000..191d3e79684
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TerrorOfMountVelus.java
@@ -0,0 +1,50 @@
+package mage.cards.t;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
+import mage.abilities.keyword.DoubleStrikeAbility;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.StaticFilters;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TerrorOfMountVelus extends CardImpl {
+
+ public TerrorOfMountVelus(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}{R}");
+
+ this.subtype.add(SubType.DRAGON);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(5);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Double strike
+ this.addAbility(DoubleStrikeAbility.getInstance());
+
+ // When Terror of Mount Velus enters the battlefield, creatures you control gain double strike until end of turn.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new GainAbilityControlledEffect(
+ DoubleStrikeAbility.getInstance(), Duration.EndOfTurn,
+ StaticFilters.FILTER_PERMANENT_CREATURES
+ )));
+ }
+
+ private TerrorOfMountVelus(final TerrorOfMountVelus card) {
+ super(card);
+ }
+
+ @Override
+ public TerrorOfMountVelus copy() {
+ return new TerrorOfMountVelus(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TestOfFaith.java b/Mage.Sets/src/mage/cards/t/TestOfFaith.java
index 4314b4dea39..c3fc5605193 100644
--- a/Mage.Sets/src/mage/cards/t/TestOfFaith.java
+++ b/Mage.Sets/src/mage/cards/t/TestOfFaith.java
@@ -1,7 +1,5 @@
-
package mage.cards.t;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.PreventionEffectImpl;
import mage.cards.CardImpl;
@@ -10,18 +8,21 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.counters.CounterType;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class TestOfFaith extends CardImpl {
public TestOfFaith(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");
// Prevent the next 3 damage that would be dealt to target creature this turn. For each 1 damage prevented this way, put a +1/+1 counter on that creature.
this.getSpellAbility().addEffect(new TestOfFaithPreventDamageTargetEffect(Duration.EndOfTurn));
@@ -64,7 +65,7 @@ class TestOfFaithPreventDamageTargetEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int prevented = 0;
if (event.getAmount() >= this.amount) {
@@ -97,9 +98,7 @@ class TestOfFaithPreventDamageTargetEffect extends PreventionEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!this.used && super.applies(event, source, game)) {
- if (source.getTargets().getFirstTarget().equals(event.getTargetId())) {
- return true;
- }
+ return source.getTargets().getFirstTarget().equals(event.getTargetId());
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/t/TezzeretCruelMachinist.java b/Mage.Sets/src/mage/cards/t/TezzeretCruelMachinist.java
index 0f1d8ca68a0..c47ecd602ac 100644
--- a/Mage.Sets/src/mage/cards/t/TezzeretCruelMachinist.java
+++ b/Mage.Sets/src/mage/cards/t/TezzeretCruelMachinist.java
@@ -1,6 +1,5 @@
package mage.cards.t;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
@@ -9,17 +8,8 @@ import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.AddCardTypeTargetEffect;
import mage.abilities.effects.common.continuous.SetPowerToughnessTargetEffect;
-import mage.cards.Card;
-import mage.constants.SubType;
-import mage.constants.SuperType;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-import mage.cards.Cards;
-import mage.cards.CardsImpl;
-import mage.constants.CardType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.cards.*;
+import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
@@ -29,8 +19,9 @@ import mage.target.TargetPermanent;
import mage.target.common.TargetCardInHand;
import mage.target.targetpointer.FixedTarget;
+import java.util.UUID;
+
/**
- *
* @author TheElk801
*/
public final class TezzeretCruelMachinist extends CardImpl {
@@ -98,25 +89,29 @@ class TezzeretCruelMachinistEffect extends OneShotEffect {
return false;
}
Cards cardsToMove = new CardsImpl();
+
for (UUID cardId : target.getTargets()) {
Card card = game.getCard(cardId);
if (card == null) {
continue;
}
cardsToMove.add(card);
- ContinuousEffect effect = new TezzeretCruelMachinistCardTypeEffect();
- effect.setTargetPointer(new FixedTarget(
+
+ ContinuousEffect effectCardType = new TezzeretCruelMachinistCardTypeEffect();
+ effectCardType.setTargetPointer(new FixedTarget(
card.getId(),
card.getZoneChangeCounter(game) + 1
));
- game.addEffect(effect, source);
- effect = new TezzeretCruelMachinistPowerToughnessEffect();
- effect.setTargetPointer(new FixedTarget(
+ game.addEffect(effectCardType, source);
+
+ ContinuousEffect effectPowerToughness = new TezzeretCruelMachinistPowerToughnessEffect();
+ effectPowerToughness.setTargetPointer(new FixedTarget(
card.getId(),
card.getZoneChangeCounter(game) + 1
));
- game.addEffect(effect, source);
+ game.addEffect(effectPowerToughness, source);
}
+
return player.moveCards(cardsToMove.getCards(game), Zone.BATTLEFIELD, source, game, false, true, true, null);
}
}
@@ -137,13 +132,24 @@ class TezzeretCruelMachinistCardTypeEffect extends AddCardTypeTargetEffect {
}
@Override
- public boolean apply(Game game, Ability source) {
- Permanent permanent = game.getPermanent(source.getFirstTarget());
- if (permanent == null || !permanent.isFaceDown(game)) {
- this.discard();
- return false;
+ public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
+ for (UUID targetId : targetPointer.getTargets(game, source)) {
+ Permanent target = game.getPermanent(targetId);
+ if (target != null
+ && target.isFaceDown(game)) {
+ switch (layer) {
+ case TypeChangingEffects_4:
+ target.getSuperType().clear();
+ target.getCardType().clear();
+ target.getSubtype(game).clear();
+ target.addCardType(CardType.ARTIFACT);
+ target.addCardType(CardType.CREATURE);
+ break;
+ }
+ return true;
+ }
}
- return super.apply(game, source);
+ return false;
}
}
@@ -164,11 +170,15 @@ class TezzeretCruelMachinistPowerToughnessEffect extends SetPowerToughnessTarget
@Override
public boolean apply(Game game, Ability source) {
- Permanent permanent = game.getPermanent(source.getFirstTarget());
- if (permanent == null || !permanent.isFaceDown(game)) {
- this.discard();
- return false;
+ for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
+ Permanent target = game.getPermanent(targetId);
+ if (target != null
+ && target.isFaceDown(game)) {
+ target.getPower().setValue(5);
+ target.getToughness().setValue(5);
+ return true;
+ }
}
- return super.apply(game, source);
+ return false;
}
}
diff --git a/Mage.Sets/src/mage/cards/t/TezzeretMasterOfTheBridge.java b/Mage.Sets/src/mage/cards/t/TezzeretMasterOfTheBridge.java
index 5171330f063..c89cdad2b53 100644
--- a/Mage.Sets/src/mage/cards/t/TezzeretMasterOfTheBridge.java
+++ b/Mage.Sets/src/mage/cards/t/TezzeretMasterOfTheBridge.java
@@ -48,7 +48,7 @@ public final class TezzeretMasterOfTheBridge extends CardImpl {
this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
// Creature and planeswalker spells you cast have affinity for artifacts.
- this.addAbility(new SimpleStaticAbility(new GainAbilityControlledSpellsEffect(
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledSpellsEffect(
new AffinityForArtifactsAbility(), filter
)));
diff --git a/Mage.Sets/src/mage/cards/t/ThassaGodOfTheSea.java b/Mage.Sets/src/mage/cards/t/ThassaGodOfTheSea.java
index 04643c1604e..0b774119ffe 100644
--- a/Mage.Sets/src/mage/cards/t/ThassaGodOfTheSea.java
+++ b/Mage.Sets/src/mage/cards/t/ThassaGodOfTheSea.java
@@ -1,8 +1,5 @@
-
-
package mage.cards.t;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
@@ -10,7 +7,6 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.DevotionCount;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect;
import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect;
import mage.abilities.effects.keyword.ScryEffect;
@@ -20,15 +16,16 @@ import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.target.common.TargetControlledCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class ThassaGodOfTheSea extends CardImpl {
public ThassaGodOfTheSea(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{2}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{2}{U}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.GOD);
@@ -38,21 +35,24 @@ public final class ThassaGodOfTheSea extends CardImpl {
// Indestructible
this.addAbility(IndestructibleAbility.getInstance());
- // As long as your devotion to white is less than five, Thassa isn't a creature.(Each {U} in the mana costs of permanents you control counts towards your devotion to white.)
- Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.U), 5);
- effect.setText("As long as your devotion to blue is less than five, Thassa isn't a creature.(Each {U} in the mana costs of permanents you control counts towards your devotion to blue.)");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ // As long as your devotion to blue is less than five, Thassa isn't a creature.(Each {U} in the mana costs of permanents you control counts towards your devotion to white.)
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.U, 5))
+ .addHint(DevotionCount.U.getHint()));
// At the beginning of your upkeep, scry 1.
- this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new ScryEffect(1), TargetController.YOU, false));
+ this.addAbility(new BeginningOfUpkeepTriggeredAbility(
+ new ScryEffect(1), TargetController.YOU, false
+ ));
- // 1{U}: Target creature you control can't be blocked this turn.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantBeBlockedTargetEffect(Duration.EndOfTurn), new ManaCostsImpl("{1}{U}"));
+ // {1}{U}: Target creature you control can't be blocked this turn.
+ Ability ability = new SimpleActivatedAbility(
+ new CantBeBlockedTargetEffect(Duration.EndOfTurn), new ManaCostsImpl("{1}{U}")
+ );
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}
- public ThassaGodOfTheSea(final ThassaGodOfTheSea card) {
+ private ThassaGodOfTheSea(final ThassaGodOfTheSea card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/t/ThassasRebuff.java b/Mage.Sets/src/mage/cards/t/ThassasRebuff.java
index 6e4b146c6cb..889c7a79fff 100644
--- a/Mage.Sets/src/mage/cards/t/ThassasRebuff.java
+++ b/Mage.Sets/src/mage/cards/t/ThassasRebuff.java
@@ -1,31 +1,29 @@
-
package mage.cards.t;
-import java.util.UUID;
import mage.abilities.dynamicvalue.common.DevotionCount;
import mage.abilities.effects.common.CounterUnlessPaysEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.ColoredManaSymbol;
import mage.target.TargetSpell;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class ThassasRebuff extends CardImpl {
public ThassasRebuff(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
// Counter target spell unless its controller pays {X}, where X is your devotion to blue.
- this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new DevotionCount(ColoredManaSymbol.U)));
+ this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(DevotionCount.U));
this.getSpellAbility().addTarget(new TargetSpell());
+ this.getSpellAbility().addHint(DevotionCount.U.getHint());
}
- public ThassasRebuff(final ThassasRebuff card) {
+ private ThassasRebuff(final ThassasRebuff card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/t/TheAkroanWar.java b/Mage.Sets/src/mage/cards/t/TheAkroanWar.java
new file mode 100644
index 00000000000..c8aefabdd80
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TheAkroanWar.java
@@ -0,0 +1,103 @@
+package mage.cards.t;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SagaAbility;
+import mage.abilities.condition.common.SourceOnBattlefieldCondition;
+import mage.abilities.decorator.ConditionalContinuousEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.combat.AttacksIfAbleAllEffect;
+import mage.abilities.effects.common.continuous.GainControlTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.common.FilterOpponentsCreaturePermanent;
+import mage.filter.predicate.permanent.TappedPredicate;
+import mage.game.Game;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TheAkroanWar extends CardImpl {
+
+ private static final FilterCreaturePermanent filter
+ = new FilterOpponentsCreaturePermanent("creatures your opponents control");
+
+ public TheAkroanWar(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
+
+ this.subtype.add(SubType.SAGA);
+
+ // (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)
+ SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_III);
+
+ // I — Gain control of target creature for as long as The Akroan War remains on the battlefield.
+ sagaAbility.addChapterEffect(
+ this,
+ SagaChapter.CHAPTER_I,
+ SagaChapter.CHAPTER_I,
+ new ConditionalContinuousEffect(
+ new GainControlTargetEffect(Duration.Custom, true),
+ SourceOnBattlefieldCondition.instance, "gain control of target creature " +
+ "for as long as {this} remains on the battlefield"
+ ), new TargetCreaturePermanent()
+ );
+
+ // II — Until your next turn, creatures your opponents control attack each combat if able.
+ sagaAbility.addChapterEffect(
+ this,
+ SagaChapter.CHAPTER_II,
+ new AttacksIfAbleAllEffect(
+ filter, Duration.UntilYourNextTurn, true
+ )
+ );
+
+ // III — Each tapped creature deals damage to itself equal to its power.
+ sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new TheAkroanWarEffect());
+ }
+
+ private TheAkroanWar(final TheAkroanWar card) {
+ super(card);
+ }
+
+ @Override
+ public TheAkroanWar copy() {
+ return new TheAkroanWar(this);
+ }
+}
+
+class TheAkroanWarEffect extends OneShotEffect {
+
+ private static final FilterPermanent filter = new FilterCreaturePermanent();
+
+ static {
+ filter.add(TappedPredicate.instance);
+ }
+
+ TheAkroanWarEffect() {
+ super(Outcome.Benefit);
+ staticText = "each tapped creature deals damage to itself equal to its power";
+ }
+
+ private TheAkroanWarEffect(final TheAkroanWarEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public TheAkroanWarEffect copy() {
+ return new TheAkroanWarEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ game.getBattlefield()
+ .getActivePermanents(filter, source.getControllerId(), game)
+ .stream()
+ .forEach(permanent -> permanent.damage(permanent.getPower().getValue(), permanent.getId(), game));
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/t/TheBattleOfYavin.java b/Mage.Sets/src/mage/cards/t/TheBattleOfYavin.java
index 90ec0851cdf..e13a60cde8b 100644
--- a/Mage.Sets/src/mage/cards/t/TheBattleOfYavin.java
+++ b/Mage.Sets/src/mage/cards/t/TheBattleOfYavin.java
@@ -26,7 +26,7 @@ public final class TheBattleOfYavin extends CardImpl {
public TheBattleOfYavin(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}{B}");
- // For each nonland permanent target opponent controls, that player sacrificies it unless he or she pays X life.
+ // For each nonland permanent target opponent controls, that player sacrificies it unless they pay X life.
this.getSpellAbility().addEffect(new TheBattleOfYavinEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
@@ -46,7 +46,7 @@ class TheBattleOfYavinEffect extends OneShotEffect {
public TheBattleOfYavinEffect() {
super(Outcome.Sacrifice);
- this.staticText = "For each nonland permanent target opponent controls, that player sacrificies it unless he or she pays X life";
+ this.staticText = "For each nonland permanent target opponent controls, that player sacrificies it unless they pay X life";
}
public TheBattleOfYavinEffect(final TheBattleOfYavinEffect effect) {
@@ -77,7 +77,7 @@ class TheBattleOfYavinEffect extends OneShotEffect {
for (Permanent permanent : permanents) {
String message = "Pay " + amount + " life? If you don't, " + permanent.getName() + " will be sacrificed.";
if (playerLife - amount - lifePaid >= 0 && opponent.chooseUse(Outcome.Neutral, message, source, game)) {
- game.informPlayers(opponent.getLogName() + " pays " + amount + " life. He will not sacrifice " + permanent.getName());
+ game.informPlayers(opponent.getLogName() + " pays " + amount + " life. They will not sacrifice " + permanent.getName());
lifePaid += amount;
} else {
game.informPlayers(opponent.getLogName() + " will sacrifice " + permanent.getName());
diff --git a/Mage.Sets/src/mage/cards/t/TheBindingOfTheTitans.java b/Mage.Sets/src/mage/cards/t/TheBindingOfTheTitans.java
new file mode 100644
index 00000000000..a6c83669872
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TheBindingOfTheTitans.java
@@ -0,0 +1,119 @@
+package mage.cards.t;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SagaAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveEachPlayerEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
+import mage.cards.*;
+import mage.constants.*;
+import mage.filter.FilterCard;
+import mage.filter.StaticFilters;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.Target;
+import mage.target.common.TargetCardInGraveyard;
+import mage.target.common.TargetCardInYourGraveyard;
+
+import java.util.Collection;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * @author TheElk801
+ */
+public final class TheBindingOfTheTitans extends CardImpl {
+
+ private static final FilterCard filter = new FilterCard("creature or land card from your graveyard");
+
+ static {
+ filter.add(Predicates.or(
+ new CardTypePredicate(CardType.CREATURE),
+ new CardTypePredicate(CardType.LAND)
+ ));
+ }
+
+ public TheBindingOfTheTitans(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
+
+ this.subtype.add(SubType.SAGA);
+
+ // (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)
+ SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_III);
+
+ // I — Each player puts the top three cards of their library into their graveyard.
+ sagaAbility.addChapterEffect(
+ this, SagaChapter.CHAPTER_I, new PutTopCardOfLibraryIntoGraveEachPlayerEffect(
+ 3, TargetController.ANY
+ )
+ );
+
+ // II — Exile up to two target cards from graveyards. For each creature card exiled this way, you gain 1 life.
+ sagaAbility.addChapterEffect(
+ this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II, new TheBindingOfTheTitansEffect(),
+ new TargetCardInGraveyard(0, 2, StaticFilters.FILTER_CARD)
+ );
+
+ // III — Return target creature or land card from your graveyard to your hand.
+ sagaAbility.addChapterEffect(
+ this, SagaChapter.CHAPTER_III, SagaChapter.CHAPTER_III,
+ new ReturnFromGraveyardToHandTargetEffect(), new TargetCardInYourGraveyard(filter)
+ );
+ this.addAbility(sagaAbility);
+ }
+
+ private TheBindingOfTheTitans(final TheBindingOfTheTitans card) {
+ super(card);
+ }
+
+ @Override
+ public TheBindingOfTheTitans copy() {
+ return new TheBindingOfTheTitans(this);
+ }
+}
+
+class TheBindingOfTheTitansEffect extends OneShotEffect {
+
+ TheBindingOfTheTitansEffect() {
+ super(Outcome.Benefit);
+ staticText = "Exile up to two target cards from graveyards. " +
+ "For each creature card exiled this way, you gain 1 life.";
+ }
+
+ private TheBindingOfTheTitansEffect(final TheBindingOfTheTitansEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public TheBindingOfTheTitansEffect copy() {
+ return new TheBindingOfTheTitansEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ Cards cards = new CardsImpl(
+ source.getTargets()
+ .stream()
+ .map(Target::getTargets)
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList())
+ );
+ player.moveCards(cards, Zone.EXILED, source, game);
+ int lifeToGain = cards
+ .getCards(game)
+ .stream()
+ .filter(Card::isCreature)
+ .map(Card::getId)
+ .map(game.getState()::getZone)
+ .map(Zone.EXILED::equals)
+ .mapToInt(b -> b ? 1 : 0)
+ .sum();
+ return player.gainLife(lifeToGain, game, source) > 0;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/t/TheCauldronOfEternity.java b/Mage.Sets/src/mage/cards/t/TheCauldronOfEternity.java
new file mode 100644
index 00000000000..e4a8026e2e6
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TheCauldronOfEternity.java
@@ -0,0 +1,104 @@
+package mage.cards.t;
+
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.SpellAbility;
+import mage.abilities.common.ActivateAsSorceryActivatedAbility;
+import mage.abilities.common.DiesCreatureTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.PayLifeCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.PutOnLibraryTargetEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
+import mage.abilities.effects.common.cost.CostModificationEffectImpl;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.common.TargetCardInYourGraveyard;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TheCauldronOfEternity extends CardImpl {
+
+ public TheCauldronOfEternity(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{10}{B}{B}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+
+ // This spell costs {2} less to cast for each creature card in your graveyard.
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new TheCauldronOfEternityCostReductionEffect()));
+
+ // Whenever a creature you control dies, put it on the bottom of its owner's library.
+ this.addAbility(new DiesCreatureTriggeredAbility(
+ new PutOnLibraryTargetEffect(false, "put it on the bottom of its owner's library"),
+ false, StaticFilters.FILTER_CONTROLLED_A_CREATURE, true
+ ));
+
+ // {2}{B}, {T}, Pay 2 life: Return target creature card from your graveyard to the battlefield. Activate this ability only any time you could cast a sorcery.
+ Ability ability = new ActivateAsSorceryActivatedAbility(
+ Zone.BATTLEFIELD, new ReturnFromGraveyardToBattlefieldTargetEffect(), new ManaCostsImpl("{2}{B}")
+ );
+ ability.addCost(new TapSourceCost());
+ ability.addCost(new PayLifeCost(2));
+ ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
+ this.addAbility(ability);
+ }
+
+ private TheCauldronOfEternity(final TheCauldronOfEternity card) {
+ super(card);
+ }
+
+ @Override
+ public TheCauldronOfEternity copy() {
+ return new TheCauldronOfEternity(this);
+ }
+}
+
+class TheCauldronOfEternityCostReductionEffect extends CostModificationEffectImpl {
+
+ TheCauldronOfEternityCostReductionEffect() {
+ super(Duration.WhileOnStack, Outcome.Benefit, CostModificationType.REDUCE_COST);
+ staticText = "This spell costs {2} less to cast for each creature card in your graveyard";
+ }
+
+ private TheCauldronOfEternityCostReductionEffect(final TheCauldronOfEternityCostReductionEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source, Ability abilityToModify) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ int reductionAmount = player
+ .getGraveyard()
+ .getCards(game)
+ .stream()
+ .filter(MageObject::isCreature)
+ .mapToInt(card -> 2)
+ .sum();
+ CardUtil.reduceCost(abilityToModify, reductionAmount);
+ return true;
+ }
+
+ @Override
+ public boolean applies(Ability abilityToModify, Ability source, Game game) {
+ return abilityToModify instanceof SpellAbility
+ && abilityToModify.getSourceId().equals(source.getSourceId())
+ && game.getCard(abilityToModify.getSourceId()) != null;
+ }
+
+ @Override
+ public TheCauldronOfEternityCostReductionEffect copy() {
+ return new TheCauldronOfEternityCostReductionEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TheCircleOfLoyalty.java b/Mage.Sets/src/mage/cards/t/TheCircleOfLoyalty.java
new file mode 100644
index 00000000000..3c07a315f14
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TheCircleOfLoyalty.java
@@ -0,0 +1,104 @@
+package mage.cards.t;
+
+import mage.abilities.Ability;
+import mage.abilities.SpellAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.common.SpellCastControllerTriggeredAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.continuous.BoostControlledEffect;
+import mage.abilities.effects.common.cost.CostModificationEffectImpl;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterPermanent;
+import mage.filter.FilterSpell;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.mageobject.SupertypePredicate;
+import mage.game.Game;
+import mage.game.permanent.token.KnightToken;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TheCircleOfLoyalty extends CardImpl {
+
+ private static final FilterSpell filter = new FilterSpell("a legendary spell");
+
+ static {
+ filter.add(new SupertypePredicate(SuperType.LEGENDARY));
+ }
+
+ public TheCircleOfLoyalty(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}{W}{W}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+
+ // This spell costs {1} less to cast for each Knight you control.
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new TheCircleOfLoyaltyCostReductionEffect()));
+
+ // Creatures you control get +1/+1.
+ this.addAbility(new SimpleStaticAbility(
+ new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield)
+ ));
+
+ // Whenever you cast a legendary spell, create a 2/2 white Knight creature token with vigilance.
+ this.addAbility(new SpellCastControllerTriggeredAbility(
+ new CreateTokenEffect(new KnightToken()), filter, false
+ ));
+
+ // {3}{W}, {T}: Create a 2/2 white Knight creature token with vigilance.
+ Ability ability = new SimpleActivatedAbility(
+ new CreateTokenEffect(new KnightToken()), new ManaCostsImpl("{3}{W}")
+ );
+ ability.addCost(new TapSourceCost());
+ this.addAbility(ability);
+ }
+
+ private TheCircleOfLoyalty(final TheCircleOfLoyalty card) {
+ super(card);
+ }
+
+ @Override
+ public TheCircleOfLoyalty copy() {
+ return new TheCircleOfLoyalty(this);
+ }
+}
+
+class TheCircleOfLoyaltyCostReductionEffect extends CostModificationEffectImpl {
+
+ private static final FilterPermanent filter = new FilterControlledPermanent(SubType.KNIGHT);
+
+ TheCircleOfLoyaltyCostReductionEffect() {
+ super(Duration.WhileOnStack, Outcome.Benefit, CostModificationType.REDUCE_COST);
+ staticText = "This spell costs {1} less to cast for each Knight you control";
+ }
+
+ private TheCircleOfLoyaltyCostReductionEffect(final TheCircleOfLoyaltyCostReductionEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source, Ability abilityToModify) {
+ int reductionAmount = game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game);
+ CardUtil.reduceCost(abilityToModify, reductionAmount);
+ return true;
+ }
+
+ @Override
+ public boolean applies(Ability abilityToModify, Ability source, Game game) {
+ return abilityToModify instanceof SpellAbility
+ && abilityToModify.getSourceId().equals(source.getSourceId())
+ && game.getCard(abilityToModify.getSourceId()) != null;
+ }
+
+ @Override
+ public TheCircleOfLoyaltyCostReductionEffect copy() {
+ return new TheCircleOfLoyaltyCostReductionEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TheGreatAurora.java b/Mage.Sets/src/mage/cards/t/TheGreatAurora.java
index 1a999296e11..5756d961aaa 100644
--- a/Mage.Sets/src/mage/cards/t/TheGreatAurora.java
+++ b/Mage.Sets/src/mage/cards/t/TheGreatAurora.java
@@ -28,7 +28,7 @@ public final class TheGreatAurora extends CardImpl {
public TheGreatAurora(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{6}{G}{G}{G}");
- // Each player shuffles all cards from their hand and all permanents he or she owns into their library, then draws that many cards. Each player may put any number of land cards from their hand onto the battlefield. Exile The Great Aurora.
+ // Each player shuffles all cards from their hand and all permanents they own into their library, then draws that many cards. Each player may put any number of land cards from their hand onto the battlefield. Exile The Great Aurora.
this.getSpellAbility().addEffect(new TheGreatAuroraEffect());
this.getSpellAbility().addEffect(ExileSpellEffect.getInstance());
}
@@ -47,7 +47,7 @@ class TheGreatAuroraEffect extends OneShotEffect {
public TheGreatAuroraEffect() {
super(Outcome.Benefit);
- this.staticText = "Each player shuffles all cards from their hand and all permanents he or she owns into their library, then draws that many cards. Each player may put any number of land cards from their hand onto the battlefield";
+ this.staticText = "Each player shuffles all cards from their hand and all permanents they own into their library, then draws that many cards. Each player may put any number of land cards from their hand onto the battlefield";
}
public TheGreatAuroraEffect(final TheGreatAuroraEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/t/TheGreatHenge.java b/Mage.Sets/src/mage/cards/t/TheGreatHenge.java
new file mode 100644
index 00000000000..3c81dc3e097
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TheGreatHenge.java
@@ -0,0 +1,110 @@
+package mage.cards.t;
+
+import mage.MageInt;
+import mage.Mana;
+import mage.abilities.Ability;
+import mage.abilities.SpellAbility;
+import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.abilities.effects.common.cost.CostModificationEffectImpl;
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.abilities.mana.SimpleManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.counters.CounterType;
+import mage.filter.FilterPermanent;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.permanent.TokenPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TheGreatHenge extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterCreaturePermanent();
+
+ static {
+ filter.add(Predicates.not(TokenPredicate.instance));
+ }
+
+ public TheGreatHenge(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{7}{G}{G}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+
+ // This spell costs {X} less to cast, where X is the greatest power among creatures you control.
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new TheGreatHengeCostReductionEffect()));
+
+ // {T}: Add {G}{G}. You gain 2 life.
+ Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, Mana.GreenMana(2), new TapSourceCost());
+ ability.addEffect(new GainLifeEffect(2).setText("You gain 2 life."));
+ this.addAbility(ability);
+
+ // Whenever a nontoken creature enters the battlefield under your control, put a +1/+1 counter on it and draw a card.
+ ability = new EntersBattlefieldControlledTriggeredAbility(
+ Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()),
+ filter, false, SetTargetPointer.PERMANENT, "Whenever a nontoken creature " +
+ "enters the battlefield under your control, put a +1/+1 counter on it and draw a card."
+ );
+ ability.addEffect(new DrawCardSourceControllerEffect(1));
+ this.addAbility(ability);
+ }
+
+ private TheGreatHenge(final TheGreatHenge card) {
+ super(card);
+ }
+
+ @Override
+ public TheGreatHenge copy() {
+ return new TheGreatHenge(this);
+ }
+}
+
+class TheGreatHengeCostReductionEffect extends CostModificationEffectImpl {
+
+ TheGreatHengeCostReductionEffect() {
+ super(Duration.WhileOnStack, Outcome.Benefit, CostModificationType.REDUCE_COST);
+ staticText = "This spell costs {X} less to cast, where X is the greatest power among creatures you control";
+ }
+
+ private TheGreatHengeCostReductionEffect(final TheGreatHengeCostReductionEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source, Ability abilityToModify) {
+ int reductionAmount = game.getBattlefield()
+ .getAllActivePermanents(
+ StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game
+ ).stream()
+ .map(Permanent::getPower)
+ .mapToInt(MageInt::getValue)
+ .max()
+ .orElse(0);
+ CardUtil.reduceCost(abilityToModify, Math.max(0, reductionAmount));
+ return true;
+ }
+
+ @Override
+ public boolean applies(Ability abilityToModify, Ability source, Game game) {
+ return abilityToModify instanceof SpellAbility
+ && abilityToModify.getSourceId().equals(source.getSourceId())
+ && game.getCard(abilityToModify.getSourceId()) != null;
+ }
+
+ @Override
+ public TheGreatHengeCostReductionEffect copy() {
+ return new TheGreatHengeCostReductionEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TheMagicMirror.java b/Mage.Sets/src/mage/cards/t/TheMagicMirror.java
new file mode 100644
index 00000000000..9090a80225b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TheMagicMirror.java
@@ -0,0 +1,62 @@
+package mage.cards.t;
+
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.CountersSourceCount;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect;
+import mage.abilities.effects.common.cost.SourceCostReductionForEachCardInGraveyardEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.counters.CounterType;
+import mage.filter.StaticFilters;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TheMagicMirror extends CardImpl {
+
+ private static final DynamicValue xValue = new CountersSourceCount(CounterType.KNOWLEDGE);
+
+ public TheMagicMirror(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{6}{U}{U}{U}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+
+ // This spell costs {1} less to cast for each instant and sorcery card in your graveyard.
+ this.addAbility(new SimpleStaticAbility(
+ Zone.ALL, new SourceCostReductionForEachCardInGraveyardEffect(
+ StaticFilters.FILTER_CARD_INSTANT_AND_SORCERY
+ )).setRuleAtTheTop(true));
+
+ // You have no maximum hand size.
+ this.addAbility(new SimpleStaticAbility(new MaximumHandSizeControllerEffect(
+ Integer.MAX_VALUE, Duration.WhileOnBattlefield,
+ MaximumHandSizeControllerEffect.HandSizeModification.SET
+ )));
+
+ // At the beginning of your upkeep, put a knowledge counter on The Magic Mirror, then draw a card for each knowledge counter on The Magic Mirror.
+ Ability ability = new BeginningOfUpkeepTriggeredAbility(
+ new AddCountersSourceEffect(CounterType.KNOWLEDGE.createInstance())
+ .setText("put a knowledge counter on {this},"),
+ TargetController.YOU, false
+ );
+ ability.addEffect(new DrawCardSourceControllerEffect(xValue).concatBy("then"));
+ this.addAbility(ability);
+ }
+
+ private TheMagicMirror(final TheMagicMirror card) {
+ super(card);
+ }
+
+ @Override
+ public TheMagicMirror copy() {
+ return new TheMagicMirror(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TheMimeoplasm.java b/Mage.Sets/src/mage/cards/t/TheMimeoplasm.java
index 888e1b8beb3..13b76c6478f 100644
--- a/Mage.Sets/src/mage/cards/t/TheMimeoplasm.java
+++ b/Mage.Sets/src/mage/cards/t/TheMimeoplasm.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.UUID;
@@ -11,6 +10,7 @@ import mage.abilities.effects.common.CopyEffect;
import mage.cards.*;
import mage.constants.*;
import mage.counters.CounterType;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardIdPredicate;
@@ -67,7 +67,7 @@ class TheMimeoplasmEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanentEntering(source.getSourceId());
if (controller != null && permanent != null) {
- if (new CardsInAllGraveyardsCount(new FilterCreatureCard()).calculate(game, source, this) >= 2) {
+ if (new CardsInAllGraveyardsCount(StaticFilters.FILTER_CARD_CREATURE).calculate(game, source, this) >= 2) {
if (controller.chooseUse(Outcome.Benefit, "Do you want to exile two creature cards from graveyards?", source, game)) {
TargetCardInGraveyard targetCopy = new TargetCardInGraveyard(new FilterCreatureCard("creature card to become a copy of"));
targetCopy.setNotTarget(true);
diff --git a/Mage.Sets/src/mage/cards/t/TheRoyalScions.java b/Mage.Sets/src/mage/cards/t/TheRoyalScions.java
new file mode 100644
index 00000000000..83fda327c07
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TheRoyalScions.java
@@ -0,0 +1,129 @@
+package mage.cards.t;
+
+import mage.abilities.Ability;
+import mage.abilities.DelayedTriggeredAbility;
+import mage.abilities.LoyaltyAbility;
+import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
+import mage.abilities.dynamicvalue.common.CardsInControllerHandCount;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.DrawDiscardControllerEffect;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.keyword.FirstStrikeAbility;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.target.common.TargetAnyTarget;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TheRoyalScions extends CardImpl {
+
+ public TheRoyalScions(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{1}{U}{R}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.WILL);
+ this.subtype.add(SubType.ROWAN);
+ this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
+
+ // +1: Draw a card, then discard a card.
+ this.addAbility(new LoyaltyAbility(new DrawDiscardControllerEffect(1, 1), 1));
+
+ // +1: Target creature gets +2/+0 and gains first strike and trample until end of turn.
+ Ability ability = new LoyaltyAbility(new BoostTargetEffect(
+ 2, 0, Duration.EndOfTurn
+ ).setText("Target creature gets +2/+0"), 1);
+ ability.addEffect(new GainAbilityTargetEffect(
+ FirstStrikeAbility.getInstance(), Duration.EndOfTurn
+ ).setText("and gains first strike"));
+ ability.addEffect(new GainAbilityTargetEffect(
+ TrampleAbility.getInstance(), Duration.EndOfTurn
+ ).setText("and trample until end of turn"));
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+
+ // −8: Draw four cards. When you do, The Royal Scions deals damage to any target equal to the number of cards in your hand.
+ this.addAbility(new LoyaltyAbility(new TheRoyalScionsCreateReflexiveTriggerEffect(), -8));
+ }
+
+ private TheRoyalScions(final TheRoyalScions card) {
+ super(card);
+ }
+
+ @Override
+ public TheRoyalScions copy() {
+ return new TheRoyalScions(this);
+ }
+}
+
+class TheRoyalScionsCreateReflexiveTriggerEffect extends OneShotEffect {
+
+ private static final Effect effect = new DrawCardSourceControllerEffect(4);
+
+ TheRoyalScionsCreateReflexiveTriggerEffect() {
+ super(Outcome.Benefit);
+ staticText = "Draw four cards. When you do, {this} deals damage " +
+ "to any target equal to the number of cards in your hand.";
+ }
+
+ private TheRoyalScionsCreateReflexiveTriggerEffect(final TheRoyalScionsCreateReflexiveTriggerEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public TheRoyalScionsCreateReflexiveTriggerEffect copy() {
+ return new TheRoyalScionsCreateReflexiveTriggerEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ effect.apply(game, source);
+ game.addDelayedTriggeredAbility(new TheRoyalScionsReflexiveTriggeredAbility(), source);
+ game.fireEvent(GameEvent.getEvent(GameEvent.EventType.OPTION_USED, source.getOriginalId(), source.getSourceId(), source.getControllerId(), 0));
+ return true;
+ }
+}
+
+class TheRoyalScionsReflexiveTriggeredAbility extends DelayedTriggeredAbility {
+
+ TheRoyalScionsReflexiveTriggeredAbility() {
+ super(new DamageTargetEffect(CardsInControllerHandCount.instance), Duration.OneUse, true);
+ this.addTarget(new TargetAnyTarget());
+ }
+
+ private TheRoyalScionsReflexiveTriggeredAbility(final TheRoyalScionsReflexiveTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public TheRoyalScionsReflexiveTriggeredAbility copy() {
+ return new TheRoyalScionsReflexiveTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.OPTION_USED;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ return event.getPlayerId().equals(this.getControllerId())
+ && event.getSourceId().equals(this.getSourceId());
+ }
+
+ @Override
+ public String getRule() {
+ return "When you do, {this} deals damage to any target equal to the number of cards in your hand.";
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/t/ThelonsChant.java b/Mage.Sets/src/mage/cards/t/ThelonsChant.java
index 5c8c914a081..2a92d1a093f 100644
--- a/Mage.Sets/src/mage/cards/t/ThelonsChant.java
+++ b/Mage.Sets/src/mage/cards/t/ThelonsChant.java
@@ -43,9 +43,9 @@ public final class ThelonsChant extends CardImpl {
// At the beginning of your upkeep, sacrifice Thelon's Chant unless you pay {G}.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl("{G}")), TargetController.YOU, false));
- // Whenever a player puts a Swamp onto the battlefield, Thelon's Chant deals 3 damage to that player unless he or she puts a -1/-1 counter on a creature he or she controls.
+ // Whenever a player puts a Swamp onto the battlefield, Thelon's Chant deals 3 damage to that player unless they put a -1/-1 counter on a creature they control.
this.addAbility(new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new ThelonsChantEffect(), filter, false, SetTargetPointer.PLAYER,
- "Whenever a player puts a Swamp onto the battlefield, {this} deals 3 damage to that player unless he or she puts a -1/-1 counter on a creature he or she controls."));
+ "Whenever a player puts a Swamp onto the battlefield, {this} deals 3 damage to that player unless they put a -1/-1 counter on a creature they control."));
}
public ThelonsChant(final ThelonsChant card) {
@@ -62,7 +62,7 @@ class ThelonsChantEffect extends OneShotEffect {
public ThelonsChantEffect() {
super(Outcome.Damage);
- staticText = "{this} deals 3 damage to that player unless he or she puts a -1/-1 counter on a creature he or she controls";
+ staticText = "{this} deals 3 damage to that player unless they put a -1/-1 counter on a creature they control";
}
public ThelonsChantEffect(final ThelonsChantEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/t/ThelonsCurse.java b/Mage.Sets/src/mage/cards/t/ThelonsCurse.java
index 07ebd1cf241..2446105417c 100644
--- a/Mage.Sets/src/mage/cards/t/ThelonsCurse.java
+++ b/Mage.Sets/src/mage/cards/t/ThelonsCurse.java
@@ -45,7 +45,7 @@ public final class ThelonsCurse extends CardImpl {
// Blue creatures don't untap during their controllers' untap steps.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepAllEffect(Duration.WhileOnBattlefield, TargetController.ANY, filterCreature)));
- // At the beginning of each player's upkeep, that player may choose any number of tapped blue creatures he or she controls and pay {U} for each creature chosen this way. If the player does, untap those creatures.
+ // At the beginning of each player's upkeep, that player may choose any number of tapped blue creatures they control and pay {U} for each creature chosen this way. If the player does, untap those creatures.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new ThelonsCurseEffect(), TargetController.ANY, false));
}
@@ -70,7 +70,7 @@ class ThelonsCurseEffect extends OneShotEffect {
ThelonsCurseEffect() {
super(Outcome.Benefit);
- staticText = "that player may choose any number of tapped blue creatures he or she controls and pay {U} for each creature chosen this way. If the player does, untap those creatures.";
+ staticText = "that player may choose any number of tapped blue creatures they control and pay {U} for each creature chosen this way. If the player does, untap those creatures.";
}
ThelonsCurseEffect(ThelonsCurseEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/t/ThermalBlast.java b/Mage.Sets/src/mage/cards/t/ThermalBlast.java
index 3f7b28b7bcc..6ecf16804a2 100644
--- a/Mage.Sets/src/mage/cards/t/ThermalBlast.java
+++ b/Mage.Sets/src/mage/cards/t/ThermalBlast.java
@@ -1,34 +1,33 @@
package mage.cards.t;
-import java.util.UUID;
import mage.abilities.condition.common.CardsInControllerGraveCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author cbt33
*/
public final class ThermalBlast extends CardImpl {
public ThermalBlast(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{4}{R}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}");
// Thermal Blast deals 3 damage to target creature.
// Threshold - Thermal Blast deals 5 damage to that creature instead if seven or more cards are in your graveyard.
- Effect effect = new ConditionalOneShotEffect(new DamageTargetEffect(5),
- new DamageTargetEffect(3),
- new CardsInControllerGraveCondition(7),
- "{this} deals 3 damage to target creature.
Threshold — {this} deals 5 damage to that creature instead if seven or more cards are in your graveyard.");
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new DamageTargetEffect(5), new DamageTargetEffect(3),
+ new CardsInControllerGraveCondition(7),
+ "{this} deals 3 damage to target creature.
Threshold — " +
+ "{this} deals 5 damage instead if seven or more cards are in your graveyard."
+ ));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
- this.getSpellAbility().addEffect(effect);
}
public ThermalBlast(final ThermalBlast card) {
diff --git a/Mage.Sets/src/mage/cards/t/ThicketElemental.java b/Mage.Sets/src/mage/cards/t/ThicketElemental.java
index e5ee92f1eed..314fc6b94e4 100644
--- a/Mage.Sets/src/mage/cards/t/ThicketElemental.java
+++ b/Mage.Sets/src/mage/cards/t/ThicketElemental.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.UUID;
@@ -14,7 +13,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -32,7 +31,7 @@ public final class ThicketElemental extends CardImpl {
this.addAbility(new KickerAbility("{1}{G}"));
// When Thicket Elemental enters the battlefield, if it was kicked, you may reveal cards from the top of your library until you reveal a creature card. If you do, put that card onto the battlefield and shuffle all other cards revealed this way into your library.
- TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new RevealCardsFromLibraryUntilEffect(new FilterCreatureCard(), Zone.BATTLEFIELD, Zone.LIBRARY, true));
+ TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new RevealCardsFromLibraryUntilEffect(StaticFilters.FILTER_CARD_CREATURE, Zone.BATTLEFIELD, Zone.LIBRARY, true));
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, KickedCondition.instance,
"When {this} enters the battlefield, if it was kicked, you may reveal cards from the top of your library until you reveal a creature card. If you do, put that card onto the battlefield and shuffle all other cards revealed this way into your library."));
}
diff --git a/Mage.Sets/src/mage/cards/t/ThiefOfSanity.java b/Mage.Sets/src/mage/cards/t/ThiefOfSanity.java
index 818970680f6..64c5954eebf 100644
--- a/Mage.Sets/src/mage/cards/t/ThiefOfSanity.java
+++ b/Mage.Sets/src/mage/cards/t/ThiefOfSanity.java
@@ -1,8 +1,5 @@
package mage.cards.t;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
@@ -12,18 +9,8 @@ import mage.abilities.effects.AsThoughManaEffect;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlyingAbility;
-import mage.cards.Card;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-import mage.cards.Cards;
-import mage.cards.CardsImpl;
-import mage.constants.AsThoughEffectType;
-import mage.constants.CardType;
-import mage.constants.Duration;
-import mage.constants.ManaType;
-import mage.constants.Outcome;
-import mage.constants.SubType;
-import mage.constants.Zone;
+import mage.cards.*;
+import mage.constants.*;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.ManaPoolItem;
@@ -32,8 +19,11 @@ import mage.target.TargetCard;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class ThiefOfSanity extends CardImpl {
@@ -197,15 +187,11 @@ class ThiefOfSanitySpendAnyManaEffect extends AsThoughEffectImpl implements AsTh
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
- objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget())
&& game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
- if (affectedControllerId.equals(authorizedPlayerId)) {
- // if the card moved from exile to stack the zone change counter is increased by 1
- if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) {
- return true;
- }
- }
+ // if the card moved from exile to spell the zone change counter is increased by 1 (effect must applies before and on stack, use isCheckPlayableMode?)
+ return affectedControllerId.equals(authorizedPlayerId);
} else if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) {
// object has moved zone so effect can be discarted
this.discard();
diff --git a/Mage.Sets/src/mage/cards/t/ThievesAuction.java b/Mage.Sets/src/mage/cards/t/ThievesAuction.java
index b9b27cf7438..ed260a99d58 100644
--- a/Mage.Sets/src/mage/cards/t/ThievesAuction.java
+++ b/Mage.Sets/src/mage/cards/t/ThievesAuction.java
@@ -1,14 +1,8 @@
-
package mage.cards.t;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
-import mage.cards.Card;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-import mage.cards.Cards;
-import mage.cards.CardsImpl;
+import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
@@ -24,14 +18,15 @@ import mage.target.TargetCard;
import mage.target.common.TargetCardInExile;
import mage.util.CardUtil;
+import java.util.UUID;
+
/**
- *
* @author emerald000
*/
public final class ThievesAuction extends CardImpl {
public ThievesAuction(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{R}{R}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}{R}{R}");
// Exile all nontoken permanents. Starting with you, each player chooses one of the exiled cards and puts it onto the battlefield tapped under their control. Repeat this process until all cards exiled this way have been chosen.
this.getSpellAbility().addEffect(new ThievesAuctionEffect());
@@ -98,7 +93,7 @@ class ThievesAuctionEffect extends OneShotEffect {
}
}
// Repeat this process until all cards exiled this way have been chosen.
- player = playerList.getNext(game);
+ player = playerList.getNext(game, false);
}
return true;
}
diff --git a/Mage.Sets/src/mage/cards/t/ThirstForKnowledge.java b/Mage.Sets/src/mage/cards/t/ThirstForKnowledge.java
index 75fae94b4ad..bc4fb767d93 100644
--- a/Mage.Sets/src/mage/cards/t/ThirstForKnowledge.java
+++ b/Mage.Sets/src/mage/cards/t/ThirstForKnowledge.java
@@ -1,38 +1,36 @@
package mage.cards.t;
-import java.util.UUID;
-import mage.abilities.Ability;
-import mage.abilities.costs.Cost;
-import mage.abilities.costs.common.DiscardTargetCost;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.costs.common.DiscardCardCost;
+import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.discard.DiscardControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
import mage.filter.FilterCard;
-import mage.filter.predicate.mageobject.CardTypePredicate;
-import mage.game.Game;
-import mage.players.Player;
-import mage.target.common.TargetCardInHand;
+import mage.filter.common.FilterArtifactCard;
+
+import java.util.UUID;
/**
- *
* @author jeffwadsworth
*/
public final class ThirstForKnowledge extends CardImpl {
- public ThirstForKnowledge(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{U}");
+ private static final FilterCard filter = new FilterArtifactCard();
+ public ThirstForKnowledge(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}");
// Draw three cards. Then discard two cards unless you discard an artifact card.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(3));
- this.getSpellAbility().addEffect(new ThirstforKnowledgeEffect());
+ this.getSpellAbility().addEffect(new DoIfCostPaid(
+ null, new DiscardControllerEffect(2), new DiscardCardCost(filter)
+ ).setText("Then discard two cards unless you discard an artifact card"));
}
- public ThirstForKnowledge(final ThirstForKnowledge card) {
+ private ThirstForKnowledge(final ThirstForKnowledge card) {
super(card);
}
@@ -41,42 +39,3 @@ public final class ThirstForKnowledge extends CardImpl {
return new ThirstForKnowledge(this);
}
}
-
-class ThirstforKnowledgeEffect extends OneShotEffect {
-
- public ThirstforKnowledgeEffect() {
- super(Outcome.Damage);
- staticText = "Then discard two cards unless you discard an artifact card";
- }
-
- public ThirstforKnowledgeEffect(final ThirstforKnowledgeEffect effect) {
- super(effect);
- }
-
- @Override
- public ThirstforKnowledgeEffect copy() {
- return new ThirstforKnowledgeEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player you = game.getPlayer(source.getControllerId());
- FilterCard filter = new FilterCard("artifact to discard");
- filter.add(new CardTypePredicate(CardType.ARTIFACT));
- if (you != null
- && you.getHand().count(filter, game) > 0
- && you.chooseUse(Outcome.Discard, "Do you want to discard an artifact? If you don't, you must discard 2 cards", source, game)) {
- Cost cost = new DiscardTargetCost(new TargetCardInHand(filter));
- if (cost.canPay(source, source.getSourceId(), you.getId(), game)) {
- if (cost.pay(source, game, source.getSourceId(), you.getId(), false, null)) {
- return true;
- }
- }
- }
- if (you != null) {
- you.discard(2, false, source, game);
- return true;
- }
- return false;
- }
-}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/t/ThirstForMeaning.java b/Mage.Sets/src/mage/cards/t/ThirstForMeaning.java
new file mode 100644
index 00000000000..1f8472559c5
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/ThirstForMeaning.java
@@ -0,0 +1,40 @@
+package mage.cards.t;
+
+import mage.abilities.costs.common.DiscardCardCost;
+import mage.abilities.effects.common.DoIfCostPaid;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.discard.DiscardControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.FilterCard;
+import mage.filter.common.FilterEnchantmentCard;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ThirstForMeaning extends CardImpl {
+
+ private static final FilterCard filter = new FilterEnchantmentCard();
+
+ public ThirstForMeaning(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}");
+
+ // Draw three cards. Then discard two cards unless you discard an enchantment card.
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(3));
+ this.getSpellAbility().addEffect(new DoIfCostPaid(
+ null, new DiscardControllerEffect(2), new DiscardCardCost(filter)
+ ).setText("Then discard two cards unless you discard an enchantment card"));
+ }
+
+ private ThirstForMeaning(final ThirstForMeaning card) {
+ super(card);
+ }
+
+ @Override
+ public ThirstForMeaning copy() {
+ return new ThirstForMeaning(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/ThopterSpyNetwork.java b/Mage.Sets/src/mage/cards/t/ThopterSpyNetwork.java
index 8514dc92551..bd4b10cef68 100644
--- a/Mage.Sets/src/mage/cards/t/ThopterSpyNetwork.java
+++ b/Mage.Sets/src/mage/cards/t/ThopterSpyNetwork.java
@@ -1,9 +1,6 @@
package mage.cards.t;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
@@ -18,8 +15,11 @@ import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.ThopterColorlessToken;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
/**
- *
* @author fireshoes
*/
public final class ThopterSpyNetwork extends CardImpl {
@@ -34,7 +34,7 @@ public final class ThopterSpyNetwork extends CardImpl {
this.addAbility(new ThopterSpyNetworkDamageTriggeredAbility());
}
- public ThopterSpyNetwork(final ThopterSpyNetwork card) {
+ private ThopterSpyNetwork(final ThopterSpyNetwork card) {
super(card);
}
@@ -46,11 +46,11 @@ public final class ThopterSpyNetwork extends CardImpl {
class ThopterSpyNetworkUpkeepTriggeredAbility extends TriggeredAbilityImpl {
- public ThopterSpyNetworkUpkeepTriggeredAbility() {
+ ThopterSpyNetworkUpkeepTriggeredAbility() {
super(Zone.BATTLEFIELD, new CreateTokenEffect(new ThopterColorlessToken(), 1), false);
}
- public ThopterSpyNetworkUpkeepTriggeredAbility(final ThopterSpyNetworkUpkeepTriggeredAbility ability) {
+ private ThopterSpyNetworkUpkeepTriggeredAbility(final ThopterSpyNetworkUpkeepTriggeredAbility ability) {
super(ability);
}
@@ -82,13 +82,13 @@ class ThopterSpyNetworkUpkeepTriggeredAbility extends TriggeredAbilityImpl {
class ThopterSpyNetworkDamageTriggeredAbility extends TriggeredAbilityImpl {
- List damagedPlayerIds = new ArrayList<>();
+ private final List damagedPlayerIds = new ArrayList<>();
- public ThopterSpyNetworkDamageTriggeredAbility() {
+ ThopterSpyNetworkDamageTriggeredAbility() {
super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), false);
}
- public ThopterSpyNetworkDamageTriggeredAbility(final ThopterSpyNetworkDamageTriggeredAbility ability) {
+ private ThopterSpyNetworkDamageTriggeredAbility(final ThopterSpyNetworkDamageTriggeredAbility ability) {
super(ability);
}
@@ -100,7 +100,7 @@ class ThopterSpyNetworkDamageTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_PLAYER
- || event.getType() == GameEvent.EventType.END_COMBAT_STEP_POST;
+ || event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_POST;
}
@Override
@@ -115,7 +115,7 @@ class ThopterSpyNetworkDamageTriggeredAbility extends TriggeredAbilityImpl {
}
}
}
- if (event.getType() == GameEvent.EventType.END_COMBAT_STEP_POST) {
+ if (event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_POST) {
damagedPlayerIds.clear();
}
return false;
diff --git a/Mage.Sets/src/mage/cards/t/ThornMammoth.java b/Mage.Sets/src/mage/cards/t/ThornMammoth.java
new file mode 100644
index 00000000000..82b9fca0b1b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/ThornMammoth.java
@@ -0,0 +1,60 @@
+package mage.cards.t;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
+import mage.abilities.effects.common.FightTargetSourceEffect;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+import mage.filter.FilterPermanent;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ThornMammoth extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterCreaturePermanent("creature you don't control");
+
+ static {
+ filter.add(new ControllerPredicate(TargetController.NOT_YOU));
+ }
+
+ public ThornMammoth(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}");
+
+ this.subtype.add(SubType.ELEPHANT);
+ this.power = new MageInt(6);
+ this.toughness = new MageInt(6);
+
+ // Trample
+ this.addAbility(TrampleAbility.getInstance());
+
+ // Whenever Thorn Mammoth or another creature enters the battlefield under your control, Thorn Mammoth fights up to one target creature you don't control.
+ Ability ability = new EntersBattlefieldControlledTriggeredAbility(
+ new FightTargetSourceEffect(), StaticFilters.FILTER_PERMANENT_CREATURE,
+ "Whenever {this} or another creature enters the battlefield under your control, " +
+ "{this} fights up to one target creature you don't control."
+ );
+ ability.addTarget(new TargetPermanent(0, 1, filter, false));
+ this.addAbility(ability);
+ }
+
+ private ThornMammoth(final ThornMammoth card) {
+ super(card);
+ }
+
+ @Override
+ public ThornMammoth copy() {
+ return new ThornMammoth(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/ThoughtCollapse.java b/Mage.Sets/src/mage/cards/t/ThoughtCollapse.java
index e09ad3f0243..ed4faf06f7a 100644
--- a/Mage.Sets/src/mage/cards/t/ThoughtCollapse.java
+++ b/Mage.Sets/src/mage/cards/t/ThoughtCollapse.java
@@ -1,6 +1,7 @@
package mage.cards.t;
import mage.abilities.Ability;
+import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CounterTargetEffect;
import mage.cards.CardImpl;
@@ -39,6 +40,8 @@ public final class ThoughtCollapse extends CardImpl {
class ThoughtCollapseEffect extends OneShotEffect {
+ private static final Effect effect = new CounterTargetEffect();
+
ThoughtCollapseEffect() {
super(Outcome.Benefit);
staticText = "Counter target spell. Its controller puts " +
@@ -61,6 +64,6 @@ class ThoughtCollapseEffect extends OneShotEffect {
return false;
}
player.moveCards(player.getLibrary().getTopCards(game, 3), Zone.GRAVEYARD, source, game);
- return new CounterTargetEffect().apply(game, source);
+ return effect.apply(game, source);
}
}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/t/ThoughtHemorrhage.java b/Mage.Sets/src/mage/cards/t/ThoughtHemorrhage.java
index 04f7a06f21c..17f448a0ee1 100644
--- a/Mage.Sets/src/mage/cards/t/ThoughtHemorrhage.java
+++ b/Mage.Sets/src/mage/cards/t/ThoughtHemorrhage.java
@@ -110,7 +110,7 @@ class ThoughtHemorrhageEffect extends OneShotEffect {
}
// search cards in Library
- // If the player has no nonland cards in their hand, you can still search that player's library and have him or her shuffle it.
+ // If the player has no nonland cards in their hand, you can still search that player's library and have that player shuffle it.
TargetCardInLibrary targetCardsLibrary = new TargetCardInLibrary(0, Integer.MAX_VALUE, filterNamedCards);
controller.searchLibrary(targetCardsLibrary, source, game, targetPlayer.getId());
for (UUID cardId : targetCardsLibrary.getTargets()) {
diff --git a/Mage.Sets/src/mage/cards/t/ThreeDreams.java b/Mage.Sets/src/mage/cards/t/ThreeDreams.java
index 6ca476d0b48..b8543af3f89 100644
--- a/Mage.Sets/src/mage/cards/t/ThreeDreams.java
+++ b/Mage.Sets/src/mage/cards/t/ThreeDreams.java
@@ -1,7 +1,6 @@
-
package mage.cards.t;
-import java.util.UUID;
+import mage.abilities.Ability;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
@@ -14,14 +13,15 @@ import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.target.common.TargetCardInLibrary;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class ThreeDreams extends CardImpl {
public ThreeDreams(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{W}");
// Search your library for up to three Aura cards with different names, reveal them, and put them into your hand. Then shuffle your library.
@@ -41,6 +41,7 @@ public final class ThreeDreams extends CardImpl {
class ThreeDreamsTarget extends TargetCardInLibrary {
private static final FilterCard aurafilter = new FilterCard("Aura cards with different names");
+
static {
aurafilter.add(new SubtypePredicate(SubType.AURA));
}
@@ -59,7 +60,7 @@ class ThreeDreamsTarget extends TargetCardInLibrary {
}
@Override
- public boolean canTarget(UUID id, Cards cards, Game game) {
+ public boolean canTarget(UUID playerId, UUID id, Ability source, Cards cards, Game game) {
Card card = cards.get(id, game);
if (card != null) {
// check if card with that name was selected before
@@ -69,7 +70,7 @@ class ThreeDreamsTarget extends TargetCardInLibrary {
return false;
}
}
- return filter.match(card, game);
+ return filter.match(card, playerId, game);
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/t/ThrillOfPossibility.java b/Mage.Sets/src/mage/cards/t/ThrillOfPossibility.java
new file mode 100644
index 00000000000..93208962308
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/ThrillOfPossibility.java
@@ -0,0 +1,34 @@
+package mage.cards.t;
+
+import mage.abilities.costs.common.DiscardCardCost;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ThrillOfPossibility extends CardImpl {
+
+ public ThrillOfPossibility(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}");
+
+ // As an additional cost to cast this spell, discard a card.
+ this.getSpellAbility().addCost(new DiscardCardCost());
+
+ // Draw two cards.
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2));
+ }
+
+ private ThrillOfPossibility(final ThrillOfPossibility card) {
+ super(card);
+ }
+
+ @Override
+ public ThrillOfPossibility copy() {
+ return new ThrillOfPossibility(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/ThroughTheBreach.java b/Mage.Sets/src/mage/cards/t/ThroughTheBreach.java
index 0afea9c31cd..3929fee7378 100644
--- a/Mage.Sets/src/mage/cards/t/ThroughTheBreach.java
+++ b/Mage.Sets/src/mage/cards/t/ThroughTheBreach.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.UUID;
@@ -16,11 +15,11 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -34,7 +33,7 @@ import mage.target.targetpointer.FixedTarget;
public final class ThroughTheBreach extends CardImpl {
public ThroughTheBreach(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{4}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}");
this.subtype.add(SubType.ARCANE);
// You may put a creature card from your hand onto the battlefield. That creature gains haste. Sacrifice that creature at the beginning of the next end step.
@@ -76,7 +75,7 @@ class ThroughTheBreachEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
if (controller.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) {
- TargetCardInHand target = new TargetCardInHand(new FilterCreatureCard());
+ TargetCardInHand target = new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE);
if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
diff --git a/Mage.Sets/src/mage/cards/t/ThunderbladeCharge.java b/Mage.Sets/src/mage/cards/t/ThunderbladeCharge.java
index c5511630952..96867d1be13 100644
--- a/Mage.Sets/src/mage/cards/t/ThunderbladeCharge.java
+++ b/Mage.Sets/src/mage/cards/t/ThunderbladeCharge.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.UUID;
@@ -32,10 +31,13 @@ public final class ThunderbladeCharge extends CardImpl {
this.getSpellAbility().addEffect(new DamageTargetEffect(3));
this.getSpellAbility().addTarget(new TargetAnyTarget());
- // Whenever one or more creatures you control deal combat damage to a player, if Thunderblade Charge is in your graveyard, you may pay {2}{R}{R}{R}. If you do, you may cast it without paying its mana cost.
+ // Whenever one or more creatures you control deal combat damage to a player,
+ // if Thunderblade Charge is in your graveyard, you may pay {2}{R}{R}{R}.
+ // If you do, you may cast it without paying its mana cost.
this.addAbility(new ControlledCreaturesDealCombatDamagePlayerTriggeredAbility(Zone.GRAVEYARD,
new DoIfCostPaid(new ThunderbladeChargeCastEffect(), new ManaCostsImpl("{2}{R}{R}{R}"))
- .setText("if {this} is in your graveyard, you may pay {2}{R}{R}{R}. If you do, you may cast it without paying its mana cost")));
+ .setText("if {this} is in your graveyard, you may pay {2}{R}{R}{R}. "
+ + "If you do, you may cast it without paying its mana cost")));
}
public ThunderbladeCharge(final ThunderbladeCharge card) {
@@ -71,8 +73,11 @@ class ThunderbladeChargeCastEffect extends OneShotEffect {
if (controller != null
&& sourceCard != null
&& Zone.GRAVEYARD == game.getState().getZone(sourceCard.getId())) {
- controller.cast(sourceCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
- return true;
+ game.getState().setValue("PlayFromNotOwnHandZone" + sourceCard.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(sourceCard, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + sourceCard.getId(), null);
+ return cardWasCast;
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/t/ThunderousMight.java b/Mage.Sets/src/mage/cards/t/ThunderousMight.java
index 08bfbd15b55..bd30f816fce 100644
--- a/Mage.Sets/src/mage/cards/t/ThunderousMight.java
+++ b/Mage.Sets/src/mage/cards/t/ThunderousMight.java
@@ -1,7 +1,5 @@
-
package mage.cards.t;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.AttacksAttachedTriggeredAbility;
import mage.abilities.dynamicvalue.common.DevotionCount;
@@ -11,17 +9,13 @@ import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.AttachmentType;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.ColoredManaSymbol;
-import mage.constants.Duration;
-import mage.constants.Outcome;
+import mage.constants.*;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class ThunderousMight extends CardImpl {
@@ -38,13 +32,14 @@ public final class ThunderousMight extends CardImpl {
this.addAbility(ability);
// Whenever enchanted creature attacks, it gets +X/+0 until end of turn, where X is your devotion to red.
- BoostEnchantedEffect effect = new BoostEnchantedEffect(new DevotionCount(ColoredManaSymbol.R), new StaticValue(0), Duration.EndOfTurn);
+ BoostEnchantedEffect effect = new BoostEnchantedEffect(DevotionCount.R, new StaticValue(0), Duration.EndOfTurn);
effect.setText("it gets +X/+0 until end of turn, where X is your devotion to red");
effect.setLockedIn(true);
- this.addAbility(new AttacksAttachedTriggeredAbility(effect, AttachmentType.AURA, false));
+ this.addAbility(new AttacksAttachedTriggeredAbility(effect, AttachmentType.AURA, false)
+ .addHint(DevotionCount.R.getHint()));
}
- public ThunderousMight(final ThunderousMight card) {
+ private ThunderousMight(final ThunderousMight card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/t/ThunderousSnapper.java b/Mage.Sets/src/mage/cards/t/ThunderousSnapper.java
new file mode 100644
index 00000000000..2a54b4a2950
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/ThunderousSnapper.java
@@ -0,0 +1,49 @@
+package mage.cards.t;
+
+import mage.MageInt;
+import mage.abilities.common.SpellCastControllerTriggeredAbility;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.filter.FilterSpell;
+import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class ThunderousSnapper extends CardImpl {
+
+ private static final FilterSpell filter = new FilterSpell("a spell with converted mana cost 5 or greater");
+
+ static {
+ filter.add(new ConvertedManaCostPredicate(ComparisonType.MORE_THAN, 4));
+ }
+
+ public ThunderousSnapper(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G/U}{G/U}{G/U}{G/U}");
+
+ this.subtype.add(SubType.TURTLE);
+ this.subtype.add(SubType.HYDRA);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(4);
+
+ // Whenever you cast a spell with converted mana cost 5 or greater, draw a card.
+ this.addAbility(new SpellCastControllerTriggeredAbility(
+ new DrawCardSourceControllerEffect(1), filter, false
+ ));
+ }
+
+ private ThunderousSnapper(final ThunderousSnapper card) {
+ super(card);
+ }
+
+ @Override
+ public ThunderousSnapper copy() {
+ return new ThunderousSnapper(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TidalFlats.java b/Mage.Sets/src/mage/cards/t/TidalFlats.java
index bac61115e7b..7bdc8a5767a 100644
--- a/Mage.Sets/src/mage/cards/t/TidalFlats.java
+++ b/Mage.Sets/src/mage/cards/t/TidalFlats.java
@@ -1,10 +1,5 @@
-
package mage.cards.t;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
@@ -29,8 +24,12 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+
/**
- *
* @author L_J
*/
public final class TidalFlats extends CardImpl {
@@ -38,7 +37,7 @@ public final class TidalFlats extends CardImpl {
public TidalFlats(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}");
- // {U}{U}: For each attacking creature without flying, its controller may pay {1}. If he or she doesn't, creatures you control blocking that creature gain first strike until end of turn.
+ // {U}{U}: For each attacking creature without flying, its controller may pay {1}. If they don't, creatures you control blocking that creature gain first strike until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new TidalFlatsEffect(), new ManaCostsImpl("{U}{U}")));
}
@@ -62,7 +61,7 @@ class TidalFlatsEffect extends OneShotEffect {
public TidalFlatsEffect() {
super(Outcome.Benefit);
- this.staticText = "For each attacking creature without flying, its controller may pay {1}. If he or she doesn't, creatures you control blocking that creature gain first strike until end of turn";
+ this.staticText = "For each attacking creature without flying, its controller may pay {1}. If they don't, creatures you control blocking that creature gain first strike until end of turn";
}
public TidalFlatsEffect(final TidalFlatsEffect effect) {
@@ -76,7 +75,6 @@ class TidalFlatsEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- game.getPlayerList();
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
diff --git a/Mage.Sets/src/mage/cards/t/TobiasBeckett.java b/Mage.Sets/src/mage/cards/t/TobiasBeckett.java
index e258e5078d0..749b1eaa4d7 100644
--- a/Mage.Sets/src/mage/cards/t/TobiasBeckett.java
+++ b/Mage.Sets/src/mage/cards/t/TobiasBeckett.java
@@ -1,19 +1,19 @@
package mage.cards.t;
-import java.util.Objects;
-import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.effects.*;
-import mage.abilities.effects.common.ExileCardsFromTopOfLibraryTargetEffect;
+import mage.abilities.effects.AsThoughEffectImpl;
+import mage.abilities.effects.AsThoughManaEffect;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.BountyAbility;
import mage.cards.Card;
-import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
+import mage.constants.*;
import mage.counters.CounterType;
import mage.game.ExileZone;
import mage.game.Game;
@@ -24,15 +24,17 @@ import mage.target.common.TargetOpponentsCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
+import java.util.Objects;
+import java.util.UUID;
+
/**
- *
* @author NinthWorld
*/
public final class TobiasBeckett extends CardImpl {
public TobiasBeckett(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
-
+
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.HUNTER);
@@ -75,7 +77,7 @@ class TobiasBeckettEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Permanent bountyTriggered = game.getPermanent(this.getTargetPointer().getFirst(game, source));
- if(bountyTriggered != null) {
+ if (bountyTriggered != null) {
Player opponent = game.getPlayer(bountyTriggered.getControllerId());
if (opponent != null) {
MageObject sourceObject = game.getObject(source.getSourceId());
@@ -170,12 +172,12 @@ class TobiasBeckettSpendAnyManaEffect extends AsThoughEffectImpl implements AsTh
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
- objectId = game.getCard(objectId).getMainCard().getId(); // for split cards
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
+ FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
return source.isControlledBy(affectedControllerId)
- && Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget())
- && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)
- && (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId))
- && game.getState().getZone(objectId) == Zone.STACK;
+ && Objects.equals(objectId, fixedTarget.getTarget())
+ && game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
+ && (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.EXILED);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/t/TombstoneStairwell.java b/Mage.Sets/src/mage/cards/t/TombstoneStairwell.java
index f492841772e..6442bbcbb4d 100644
--- a/Mage.Sets/src/mage/cards/t/TombstoneStairwell.java
+++ b/Mage.Sets/src/mage/cards/t/TombstoneStairwell.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.HashSet;
@@ -18,15 +17,14 @@ import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.TargetController;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
-import mage.game.permanent.token.TombspawnZombieToken;
-import mage.game.permanent.token.TokenImpl;
import mage.game.permanent.token.Token;
+import mage.game.permanent.token.TombspawnZombieToken;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
@@ -91,11 +89,11 @@ class TombstoneStairwellCreateTokenEffect extends OneShotEffect {
} else {
tokensCreated = new HashSet<>();
}
-
+
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
- int creatureCardsInGraveyard = player.getGraveyard().count(new FilterCreatureCard(), source.getControllerId(), source.getSourceId(), game);
- token.putOntoBattlefield(creatureCardsInGraveyard, game, source.getSourceId(), playerId);
+ int creatureCardsInGraveyard = player.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, source.getControllerId(), source.getSourceId(), game);
+ token.putOntoBattlefield(creatureCardsInGraveyard, game, source.getSourceId(), playerId);
for (UUID tokenId : token.getLastAddedTokenIds()) {
tokensCreated.add(tokenId);
}
@@ -119,7 +117,7 @@ class TombstoneStairwellTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkEventType(GameEvent event, Game game) {
- return event.getType() == EventType.END_TURN_STEP_PRE
+ return event.getType() == EventType.END_TURN_STEP_PRE
|| event.getType() == EventType.ZONE_CHANGE;
}
@@ -138,8 +136,7 @@ class TombstoneStairwellTriggeredAbility extends TriggeredAbilityImpl {
}
return true;
}
- }
- else if (event.getType() == EventType.ZONE_CHANGE) {
+ } else if (event.getType() == EventType.ZONE_CHANGE) {
if (event.getTargetId().equals(this.getSourceId())) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
diff --git a/Mage.Sets/src/mage/cards/t/TomeOfLegends.java b/Mage.Sets/src/mage/cards/t/TomeOfLegends.java
new file mode 100644
index 00000000000..a1cd9cba250
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TomeOfLegends.java
@@ -0,0 +1,65 @@
+package mage.cards.t;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.common.EntersBattlefieldOrAttacksAllTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.RemoveCountersSourceCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.TargetController;
+import mage.counters.CounterType;
+import mage.filter.FilterPermanent;
+import mage.filter.predicate.other.OwnerPredicate;
+import mage.filter.predicate.permanent.CommanderPredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TomeOfLegends extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterPermanent("your commander");
+
+ static {
+ filter.add(CommanderPredicate.instance);
+ filter.add(new OwnerPredicate(TargetController.YOU));
+ }
+
+ public TomeOfLegends(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
+
+ // Tome of Legends enters the battlefield with a page counter on it.
+ this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(
+ CounterType.PAGE.createInstance()
+ ), "with a page counter on it"));
+
+ // Whenever your commander enters the battlefield or attacks, put a page counter on Tome of Legends.
+ this.addAbility(new EntersBattlefieldOrAttacksAllTriggeredAbility(
+ new AddCountersSourceEffect(CounterType.PAGE.createInstance()), filter
+ ));
+
+ // {1}, {T}, Remove a page counter from Tome of Legends: Draw a card.
+ Ability ability = new SimpleActivatedAbility(
+ new DrawCardSourceControllerEffect(1), new GenericManaCost(1)
+ );
+ ability.addCost(new TapSourceCost());
+ ability.addCost(new RemoveCountersSourceCost(CounterType.PAGE.createInstance()));
+ this.addAbility(ability);
+ }
+
+ private TomeOfLegends(final TomeOfLegends card) {
+ super(card);
+ }
+
+ @Override
+ public TomeOfLegends copy() {
+ return new TomeOfLegends(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TomeRaider.java b/Mage.Sets/src/mage/cards/t/TomeRaider.java
new file mode 100644
index 00000000000..2661a4c17fd
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TomeRaider.java
@@ -0,0 +1,41 @@
+package mage.cards.t;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TomeRaider extends CardImpl {
+
+ public TomeRaider(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
+
+ this.subtype.add(SubType.FAERIE);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // When Tome Raider enters the battlefield, draw a card.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)));
+ }
+
+ private TomeRaider(final TomeRaider card) {
+ super(card);
+ }
+
+ @Override
+ public TomeRaider copy() {
+ return new TomeRaider(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/ToothAndNail.java b/Mage.Sets/src/mage/cards/t/ToothAndNail.java
index 9059f778c38..2b2bd35a10a 100644
--- a/Mage.Sets/src/mage/cards/t/ToothAndNail.java
+++ b/Mage.Sets/src/mage/cards/t/ToothAndNail.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.UUID;
@@ -13,6 +12,7 @@ import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.players.Player;
@@ -26,11 +26,11 @@ import mage.target.common.TargetCardInLibrary;
public final class ToothAndNail extends CardImpl {
public ToothAndNail(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{G}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{G}{G}");
// Choose one -
// Search your library for up to two creature cards, reveal them, put them into your hand, then shuffle your library;
- this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 2, new FilterCreatureCard()), true));
+ this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_CREATURE), true));
// or put up to two creature cards from your hand onto the battlefield.
Mode mode = new Mode();
mode.addEffect(new ToothAndNailPutCreatureOnBattlefieldEffect());
diff --git a/Mage.Sets/src/mage/cards/t/TorbranThaneOfRedFell.java b/Mage.Sets/src/mage/cards/t/TorbranThaneOfRedFell.java
new file mode 100644
index 00000000000..659c6588b94
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TorbranThaneOfRedFell.java
@@ -0,0 +1,106 @@
+package mage.cards.t;
+
+import mage.MageInt;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ReplacementEffectImpl;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TorbranThaneOfRedFell extends CardImpl {
+
+ public TorbranThaneOfRedFell(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{R}{R}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.DWARF);
+ this.subtype.add(SubType.NOBLE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(4);
+
+ // If a red source you control would deal damage to an opponent or a permanent an opponent controls, it deals that much damage plus 2 instead.
+ this.addAbility(new SimpleStaticAbility(new TorbranThaneOfRedFellEffect()));
+ }
+
+ private TorbranThaneOfRedFell(final TorbranThaneOfRedFell card) {
+ super(card);
+ }
+
+ @Override
+ public TorbranThaneOfRedFell copy() {
+ return new TorbranThaneOfRedFell(this);
+ }
+}
+
+class TorbranThaneOfRedFellEffect extends ReplacementEffectImpl {
+
+ TorbranThaneOfRedFellEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.Damage);
+ this.staticText = "If a red source you control would deal damage to an opponent " +
+ "or a permanent an opponent controls, it deals that much damage plus 2 instead.";
+ }
+
+ private TorbranThaneOfRedFellEffect(final TorbranThaneOfRedFellEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean replaceEvent(GameEvent event, Ability source, Game game) {
+ event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), 2));
+ return false;
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ switch (event.getType()) {
+ case DAMAGE_CREATURE:
+ case DAMAGE_PLANESWALKER:
+ case DAMAGE_PLAYER:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null
+ || !player.hasOpponent(getControllerOrSelf(event.getTargetId(), game), game)
+ || !source.isControlledBy(game.getControllerId(event.getSourceId()))) {
+ return false;
+ }
+ MageObject sourceObject;
+ Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
+ if (sourcePermanent == null) {
+ sourceObject = game.getObject(event.getSourceId());
+ } else {
+ sourceObject = sourcePermanent;
+ }
+ return sourceObject != null
+ && sourceObject.getColor(game).isRed();
+ }
+
+ private static UUID getControllerOrSelf(UUID id, Game game) {
+ UUID outId = game.getControllerId(id);
+ return outId == null ? id : outId;
+ }
+
+ @Override
+ public TorbranThaneOfRedFellEffect copy() {
+ return new TorbranThaneOfRedFellEffect(this);
+ }
+
+}
diff --git a/Mage.Sets/src/mage/cards/t/TormentOfHailfire.java b/Mage.Sets/src/mage/cards/t/TormentOfHailfire.java
index 244ba827947..c6d51fdf532 100644
--- a/Mage.Sets/src/mage/cards/t/TormentOfHailfire.java
+++ b/Mage.Sets/src/mage/cards/t/TormentOfHailfire.java
@@ -23,7 +23,7 @@ public final class TormentOfHailfire extends CardImpl {
public TormentOfHailfire(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}{B}");
- // Repeat the following process X times. Each opponent loses 3 life unless he or she sacrifices a nonland permanent or discards a card.
+ // Repeat the following process X times. Each opponent loses 3 life unless they sacrifice a nonland permanent or discards a card.
this.getSpellAbility().addEffect(new TormentOfHailfireEffect());
}
@@ -42,7 +42,7 @@ class TormentOfHailfireEffect extends OneShotEffect {
public TormentOfHailfireEffect() {
super(Outcome.LoseLife);
- this.staticText = "Repeat the following process X times. Each opponent loses 3 life unless he or she sacrifices a nonland permanent or discards a card";
+ this.staticText = "Repeat the following process X times. Each opponent loses 3 life unless they sacrifice a nonland permanent or discards a card";
}
public TormentOfHailfireEffect(final TormentOfHailfireEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/t/TormentOfScarabs.java b/Mage.Sets/src/mage/cards/t/TormentOfScarabs.java
index bda573aa8b2..7d9eeec3b13 100644
--- a/Mage.Sets/src/mage/cards/t/TormentOfScarabs.java
+++ b/Mage.Sets/src/mage/cards/t/TormentOfScarabs.java
@@ -42,7 +42,7 @@ public final class TormentOfScarabs extends CardImpl {
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
- // At the beginning of enchanted player's upkeep, that player loses 3 life unless he or she sacrifices a nonland permanent or discards a card.
+ // At the beginning of enchanted player's upkeep, that player loses 3 life unless they sacrifice a nonland permanent or discards a card.
this.addAbility(new TormentOfScarabsAbility());
}
@@ -89,7 +89,7 @@ class TormentOfScarabsAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
- return "At the beginning of enchanted player's upkeep, that player loses 3 life unless he or she sacrifices a nonland permanent or discards a card.";
+ return "At the beginning of enchanted player's upkeep, that player loses 3 life unless they sacrifice a nonland permanent or discards a card.";
}
}
@@ -98,7 +98,7 @@ class TormentOfScarabsEffect extends OneShotEffect {
public TormentOfScarabsEffect() {
super(Outcome.LoseLife);
- this.staticText = "that player loses 3 life unless he or she sacrifices a nonland permanent or discards a card";
+ this.staticText = "that player loses 3 life unless they sacrifice a nonland permanent or discards a card";
}
public TormentOfScarabsEffect(final TormentOfScarabsEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/t/TormentOfVenom.java b/Mage.Sets/src/mage/cards/t/TormentOfVenom.java
index dd0b5739e85..b3c23ae5f19 100644
--- a/Mage.Sets/src/mage/cards/t/TormentOfVenom.java
+++ b/Mage.Sets/src/mage/cards/t/TormentOfVenom.java
@@ -32,7 +32,7 @@ public final class TormentOfVenom extends CardImpl {
public TormentOfVenom(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}{B}");
- // Put three -1/-1 counters on target creature. Its controller loses 3 life unless he or she sacrifices another nonland permanent or discards a card.
+ // Put three -1/-1 counters on target creature. Its controller loses 3 life unless they sacrifice another nonland permanent or discards a card.
this.getSpellAbility().addEffect(new TormentOfVenomEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
@@ -51,7 +51,7 @@ class TormentOfVenomEffect extends OneShotEffect {
public TormentOfVenomEffect() {
super(Outcome.LoseLife);
- this.staticText = "Put three -1/-1 counters on target creature. Its controller loses 3 life unless he or she sacrifices another nonland permanent or discards a card";
+ this.staticText = "Put three -1/-1 counters on target creature. Its controller loses 3 life unless they sacrifice another nonland permanent or discards a card";
}
public TormentOfVenomEffect(final TormentOfVenomEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/t/TormentingVoice.java b/Mage.Sets/src/mage/cards/t/TormentingVoice.java
index f50ec685624..d5cbbadc408 100644
--- a/Mage.Sets/src/mage/cards/t/TormentingVoice.java
+++ b/Mage.Sets/src/mage/cards/t/TormentingVoice.java
@@ -1,31 +1,28 @@
-
package mage.cards.t;
-import java.util.UUID;
-import mage.abilities.costs.common.DiscardTargetCost;
+import mage.abilities.costs.common.DiscardCardCost;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.target.common.TargetCardInHand;
+
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class TormentingVoice extends CardImpl {
public TormentingVoice(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{R}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}");
// As an additional cost to cast Tormenting Voice, discard a card.
- this.getSpellAbility().addCost(new DiscardTargetCost(new TargetCardInHand()));
+ this.getSpellAbility().addCost(new DiscardCardCost());
// Draw two cards.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2));
}
- public TormentingVoice(final TormentingVoice card) {
+ private TormentingVoice(final TormentingVoice card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/t/TorrentOfSouls.java b/Mage.Sets/src/mage/cards/t/TorrentOfSouls.java
index 7a694c00b7c..9b503932b28 100644
--- a/Mage.Sets/src/mage/cards/t/TorrentOfSouls.java
+++ b/Mage.Sets/src/mage/cards/t/TorrentOfSouls.java
@@ -42,10 +42,10 @@ public final class TorrentOfSouls extends CardImpl {
Target targetPlayer = new TargetPlayer();
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new ReturnToBattlefieldUnderYourControlTargetEffect(),
- new ManaWasSpentCondition(ColoredManaSymbol.B), "Return up to one target creature card from your graveyard to the battlefield if {B} was spent to cast {this}"));
+ new ManaWasSpentCondition(ColoredManaSymbol.B), "Return up to one target creature card from your graveyard to the battlefield if {B} was spent to cast this spell"));
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new TorrentOfSoulsEffect(),
- new ManaWasSpentCondition(ColoredManaSymbol.R), " Creatures target player controls get +2/+0 and gain haste until end of turn if {R} was spent to cast {this}"));
+ new ManaWasSpentCondition(ColoredManaSymbol.R), " Creatures target player controls get +2/+0 and gain haste until end of turn if {R} was spent to cast this spell"));
this.getSpellAbility().addTarget(targetCreature);
this.getSpellAbility().addTarget(targetPlayer);
diff --git a/Mage.Sets/src/mage/cards/t/TorrentialGearhulk.java b/Mage.Sets/src/mage/cards/t/TorrentialGearhulk.java
index 399ee393157..8763da84e07 100644
--- a/Mage.Sets/src/mage/cards/t/TorrentialGearhulk.java
+++ b/Mage.Sets/src/mage/cards/t/TorrentialGearhulk.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.UUID;
@@ -49,7 +48,8 @@ public final class TorrentialGearhulk extends CardImpl {
// Flash
this.addAbility(FlashAbility.getInstance());
- // When Torrential Gearhulk enters the battlefield, you may cast target instant card from your graveyard without paying its mana cost.
+ // When Torrential Gearhulk enters the battlefield, you may cast target
+ // instant card from your graveyard without paying its mana cost.
// If that card would be put into your graveyard this turn, exile it instead.
Ability ability = new EntersBattlefieldTriggeredAbility(new TorrentialGearhulkEffect());
ability.addTarget(new TargetCardInYourGraveyard(filter));
@@ -69,7 +69,7 @@ public final class TorrentialGearhulk extends CardImpl {
class TorrentialGearhulkEffect extends OneShotEffect {
TorrentialGearhulkEffect() {
- super(Outcome.Benefit);
+ super(Outcome.PlayForFree);
this.staticText = "you may cast target instant card from your graveyard without paying its mana cost. "
+ "If that card would be put into your graveyard this turn, exile it instead";
}
@@ -88,9 +88,13 @@ class TorrentialGearhulkEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Card card = game.getCard(this.getTargetPointer().getFirst(game, source));
- if (card != null && card.getSpellAbility() != null) {
+ if (card != null) {
if (controller.chooseUse(outcome, "Cast " + card.getLogName() + '?', source, game)) {
- if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (cardWasCast) {
ContinuousEffect effect = new TorrentialGearhulkReplacementEffect(card.getId());
effect.setTargetPointer(new FixedTarget(card.getId(), game.getState().getZoneChangeCounter(card.getId())));
game.addEffect(effect, source);
diff --git a/Mage.Sets/src/mage/cards/t/TorturedExistence.java b/Mage.Sets/src/mage/cards/t/TorturedExistence.java
index a77823150c7..8ff13eb53e3 100644
--- a/Mage.Sets/src/mage/cards/t/TorturedExistence.java
+++ b/Mage.Sets/src/mage/cards/t/TorturedExistence.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.UUID;
@@ -12,7 +11,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
-import mage.filter.common.FilterCreatureCard;
import mage.target.common.TargetCardInYourGraveyard;
/**
@@ -26,7 +24,7 @@ public final class TorturedExistence extends CardImpl {
// {B}, Discard a creature card: Return target creature card from your graveyard to your hand.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnFromGraveyardToHandTargetEffect(), new ManaCostsImpl("{B}"));
- ability.addCost(new DiscardCardCost(new FilterCreatureCard()));
+ ability.addCost(new DiscardCardCost(StaticFilters.FILTER_CARD_CREATURE));
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/t/ToshiroUmezawa.java b/Mage.Sets/src/mage/cards/t/ToshiroUmezawa.java
index 3dff8037208..68a6decc051 100644
--- a/Mage.Sets/src/mage/cards/t/ToshiroUmezawa.java
+++ b/Mage.Sets/src/mage/cards/t/ToshiroUmezawa.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.UUID;
@@ -31,37 +30,40 @@ import mage.target.common.TargetCardInYourGraveyard;
* @author LevelX2
*/
public final class ToshiroUmezawa extends CardImpl {
-
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature an opponent controls");
+
+ private static final FilterCreaturePermanent filter
+ = new FilterCreaturePermanent("a creature an opponent controls");
private static final FilterCard filterInstant = new FilterCard("instant card from your graveyard");
-
+
static {
filter.add(new ControllerPredicate(TargetController.OPPONENT));
filterInstant.add(new CardTypePredicate(CardType.INSTANT));
}
-
+
public ToshiroUmezawa(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SAMURAI);
-
+
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Bushido 1
this.addAbility(new BushidoAbility(1));
- // Whenever a creature an opponent controls dies, you may cast target instant card from your graveyard. If that card would be put into a graveyard this turn, exile it instead.
+ // Whenever a creature an opponent controls dies, you may cast target
+ // instant card from your graveyard. If that card would be put into a
+ // graveyard this turn, exile it instead.
Ability ability = new DiesCreatureTriggeredAbility(new ToshiroUmezawaEffect(), true, filter);
ability.addTarget(new TargetCardInYourGraveyard(1, 1, filterInstant));
this.addAbility(ability);
-
+
}
-
+
public ToshiroUmezawa(final ToshiroUmezawa card) {
super(card);
}
-
+
@Override
public ToshiroUmezawa copy() {
return new ToshiroUmezawa(this);
@@ -69,28 +71,33 @@ public final class ToshiroUmezawa extends CardImpl {
}
class ToshiroUmezawaEffect extends OneShotEffect {
-
+
public ToshiroUmezawaEffect() {
super(Outcome.Benefit);
- this.staticText = "cast target instant card from your graveyard. If that card would be put into a graveyard this turn, exile it instead";
+ this.staticText = "cast target instant card from your graveyard. "
+ + "If that card would be put into a graveyard this turn, exile it instead";
}
-
+
public ToshiroUmezawaEffect(final ToshiroUmezawaEffect effect) {
super(effect);
}
-
+
@Override
public ToshiroUmezawaEffect copy() {
return new ToshiroUmezawaEffect(this);
}
-
+
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Card card = game.getCard(getTargetPointer().getFirst(game, source));
- if (card != null) {
- controller.cast(card.getSpellAbility(), game, false, new MageObjectReference(source.getSourceObject(game), game));
+ if (card != null
+ && controller.getGraveyard().contains(card.getId())) { // must be in graveyard
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(card, game, false),
+ game, false, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
game.addEffect(new ToshiroUmezawaReplacementEffect(card.getId()), source);
}
}
@@ -99,24 +106,24 @@ class ToshiroUmezawaEffect extends OneShotEffect {
}
class ToshiroUmezawaReplacementEffect extends ReplacementEffectImpl {
-
+
private final UUID cardId;
-
+
public ToshiroUmezawaReplacementEffect(UUID cardId) {
super(Duration.EndOfTurn, Outcome.Exile);
this.cardId = cardId;
}
-
+
public ToshiroUmezawaReplacementEffect(final ToshiroUmezawaReplacementEffect effect) {
super(effect);
this.cardId = effect.cardId;
}
-
+
@Override
public ToshiroUmezawaReplacementEffect copy() {
return new ToshiroUmezawaReplacementEffect(this);
}
-
+
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
UUID eventObject = event.getTargetId();
@@ -132,12 +139,12 @@ class ToshiroUmezawaReplacementEffect extends ReplacementEffectImpl {
}
return false;
}
-
+
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == EventType.ZONE_CHANGE;
}
-
+
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
diff --git a/Mage.Sets/src/mage/cards/t/TourachsChant.java b/Mage.Sets/src/mage/cards/t/TourachsChant.java
index 5799e75b3f3..d16c1125545 100644
--- a/Mage.Sets/src/mage/cards/t/TourachsChant.java
+++ b/Mage.Sets/src/mage/cards/t/TourachsChant.java
@@ -43,9 +43,9 @@ public final class TourachsChant extends CardImpl {
// At the beginning of your upkeep, sacrifice Tourach's Chant unless you pay {B}.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl("{B}")), TargetController.YOU, false));
- // Whenever a player puts a Forest onto the battlefield, Tourach's Chant deals 3 damage to that player unless he or she puts a -1/-1 counter on a creature he or she controls.
+ // Whenever a player puts a Forest onto the battlefield, Tourach's Chant deals 3 damage to that player unless they put a -1/-1 counter on a creature they control.
this.addAbility(new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new TourachsChantEffect(), filter, false, SetTargetPointer.PLAYER,
- "Whenever a player puts a Forest onto the battlefield, {this} deals 3 damage to that player unless he or she puts a -1/-1 counter on a creature he or she controls."));
+ "Whenever a player puts a Forest onto the battlefield, {this} deals 3 damage to that player unless they put a -1/-1 counter on a creature they control."));
}
public TourachsChant(final TourachsChant card) {
@@ -62,7 +62,7 @@ class TourachsChantEffect extends OneShotEffect {
public TourachsChantEffect() {
super(Outcome.Damage);
- staticText = "{this} deals 3 damage to that player unless he or she puts a -1/-1 counter on a creature he or she controls";
+ staticText = "{this} deals 3 damage to that player unless they put a -1/-1 counter on a creature they control";
}
public TourachsChantEffect(final TourachsChantEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/t/TournamentGrounds.java b/Mage.Sets/src/mage/cards/t/TournamentGrounds.java
new file mode 100644
index 00000000000..bc357fbe083
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TournamentGrounds.java
@@ -0,0 +1,51 @@
+package mage.cards.t;
+
+import mage.Mana;
+import mage.abilities.mana.ColorlessManaAbility;
+import mage.abilities.mana.ConditionalColoredManaAbility;
+import mage.abilities.mana.conditional.ConditionalSpellManaBuilder;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterSpell;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TournamentGrounds extends CardImpl {
+
+ private static final FilterSpell filter = new FilterSpell("a Knight or Equipment spell");
+
+ static {
+ filter.add(Predicates.or(
+ new SubtypePredicate(SubType.KNIGHT),
+ new SubtypePredicate(SubType.EQUIPMENT)
+ ));
+ }
+
+ public TournamentGrounds(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ // {T}: Add {C}.
+ this.addAbility(new ColorlessManaAbility());
+
+ // {T}: Add {R}, {W}, or {B}. Spend this mana only to cast a Knight or Equipment spell.
+ this.addAbility(new ConditionalColoredManaAbility(Mana.RedMana(1), new ConditionalSpellManaBuilder(filter)));
+ this.addAbility(new ConditionalColoredManaAbility(Mana.WhiteMana(1), new ConditionalSpellManaBuilder(filter)));
+ this.addAbility(new ConditionalColoredManaAbility(Mana.BlackMana(1), new ConditionalSpellManaBuilder(filter)));
+ }
+
+ private TournamentGrounds(final TournamentGrounds card) {
+ super(card);
+ }
+
+ @Override
+ public TournamentGrounds copy() {
+ return new TournamentGrounds(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TradeSecrets.java b/Mage.Sets/src/mage/cards/t/TradeSecrets.java
index 57ed77040ee..e5037e551e2 100644
--- a/Mage.Sets/src/mage/cards/t/TradeSecrets.java
+++ b/Mage.Sets/src/mage/cards/t/TradeSecrets.java
@@ -23,7 +23,7 @@ public final class TradeSecrets extends CardImpl {
public TradeSecrets(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}{U}");
- // Target opponent draws two cards, then you draw up to four cards. That opponent may repeat this process as many times as he or she chooses.
+ // Target opponent draws two cards, then you draw up to four cards. That opponent may repeat this process as many times as they choose.
this.getSpellAbility().addTarget(new TargetOpponent());
this.getSpellAbility().addEffect(new TradeSecretsEffect());
@@ -43,7 +43,7 @@ class TradeSecretsEffect extends OneShotEffect {
public TradeSecretsEffect() {
super(Outcome.DrawCard);
- this.staticText = "Target opponent draws two cards, then you draw up to four cards. That opponent may repeat this process as many times as he or she chooses";
+ this.staticText = "Target opponent draws two cards, then you draw up to four cards. That opponent may repeat this process as many times as they choose";
}
public TradeSecretsEffect(final TradeSecretsEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/t/TragicArrogance.java b/Mage.Sets/src/mage/cards/t/TragicArrogance.java
index f68c0e7561f..9e8f0dc4c7e 100644
--- a/Mage.Sets/src/mage/cards/t/TragicArrogance.java
+++ b/Mage.Sets/src/mage/cards/t/TragicArrogance.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.HashSet;
@@ -10,10 +9,10 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterArtifactPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.common.FilterEnchantmentPermanent;
-import mage.filter.common.FilterNonlandPermanent;
import mage.filter.common.FilterPlaneswalkerPermanent;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game;
@@ -32,7 +31,7 @@ public final class TragicArrogance extends CardImpl {
public TragicArrogance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{W}{W}");
- // For each player, you choose from among the permanents that player controls an artifact, a creature, an enchantment, and a planeswalker. Then each player sacrifices all other nonland permanents he or she controls.
+ // For each player, you choose from among the permanents that player controls an artifact, a creature, an enchantment, and a planeswalker. Then each player sacrifices all other nonland permanents they control.
this.getSpellAbility().addEffect(new TragicArroganceffect());
}
@@ -50,7 +49,7 @@ class TragicArroganceffect extends OneShotEffect {
public TragicArroganceffect() {
super(Outcome.Benefit);
- this.staticText = "For each player, you choose from among the permanents that player controls an artifact, a creature, an enchantment, and a planeswalker. Then each player sacrifices all other nonland permanents he or she controls";
+ this.staticText = "For each player, you choose from among the permanents that player controls an artifact, a creature, an enchantment, and a planeswalker. Then each player sacrifices all other nonland permanents they control";
}
public TragicArroganceffect(final TragicArroganceffect effect) {
@@ -123,11 +122,11 @@ class TragicArroganceffect extends OneShotEffect {
}
}
}
- // Then each player sacrifices all other nonland permanents he or she controls
+ // Then each player sacrifices all other nonland permanents they control
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
- for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterNonlandPermanent(), game)) {
+ for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENTS_NON_LAND, playerId, game)) {
if (!choosenPermanent.contains(permanent)) {
permanent.sacrifice(playerId, game);
}
diff --git a/Mage.Sets/src/mage/cards/t/TrailOfCrumbs.java b/Mage.Sets/src/mage/cards/t/TrailOfCrumbs.java
new file mode 100644
index 00000000000..707eaa50630
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TrailOfCrumbs.java
@@ -0,0 +1,86 @@
+package mage.cards.t;
+
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DoIfCostPaid;
+import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.FilterCard;
+import mage.filter.common.FilterPermanentCard;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.token.FoodToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TrailOfCrumbs extends CardImpl {
+
+ public TrailOfCrumbs(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
+
+ // When Trail of Crumbs enters the battlefield, create a Food token.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new FoodToken())));
+
+ // Whenever you sacrifice a Food, you may pay {1}. If you do, look at the top two cards of your library. You may reveal a permanent card from among them and put it into your hand. Put the rest on the bottom of your library in any order.
+ this.addAbility(new TrailOfCrumbsTriggeredAbility());
+ }
+
+ private TrailOfCrumbs(final TrailOfCrumbs card) {
+ super(card);
+ }
+
+ @Override
+ public TrailOfCrumbs copy() {
+ return new TrailOfCrumbs(this);
+ }
+}
+
+class TrailOfCrumbsTriggeredAbility extends TriggeredAbilityImpl {
+
+ private static final FilterCard filter = new FilterPermanentCard();
+
+ TrailOfCrumbsTriggeredAbility() {
+ super(Zone.BATTLEFIELD, new DoIfCostPaid(new LookLibraryAndPickControllerEffect(
+ 2, 1, filter, true, true, Zone.HAND, true
+ ), new GenericManaCost(1)));
+ }
+
+ private TrailOfCrumbsTriggeredAbility(final TrailOfCrumbsTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public TrailOfCrumbsTriggeredAbility copy() {
+ return new TrailOfCrumbsTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId());
+ return permanent != null
+ && event.getPlayerId().equals(this.getControllerId())
+ && permanent.hasSubtype(SubType.FOOD, game);
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever you sacrifice a Food, you may pay {1}. If you do, " +
+ "look at the top two cards of your library. You may reveal a permanent card from among them " +
+ "and put it into your hand. Put the rest on the bottom of your library in any order.";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TrainingGrounds.java b/Mage.Sets/src/mage/cards/t/TrainingGrounds.java
index 663138e691c..354f42c0bde 100644
--- a/Mage.Sets/src/mage/cards/t/TrainingGrounds.java
+++ b/Mage.Sets/src/mage/cards/t/TrainingGrounds.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import mage.Mana;
@@ -28,10 +27,10 @@ public final class TrainingGrounds extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}");
// Activated abilities of creatures you control cost up to {2} less to activate. This effect can't reduce the amount of mana an ability costs to activate to less than one mana.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TrainingGroundsEffect()));
+ this.addAbility(new SimpleStaticAbility(new TrainingGroundsEffect()));
}
- public TrainingGrounds(final TrainingGrounds card) {
+ private TrainingGrounds(final TrainingGrounds card) {
super(card);
}
@@ -58,47 +57,48 @@ class TrainingGroundsEffect extends CostModificationEffectImpl {
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
Player controller = game.getPlayer(abilityToModify.getControllerId());
- if (controller != null) {
- Mana mana = abilityToModify.getManaCostsToPay().getMana();
- int reduceMax = mana.getGeneric();
- if (reduceMax > 0 && mana.count() == mana.getGeneric()) {
- reduceMax--;
- }
- if (reduceMax > 2) {
- reduceMax = 2;
- }
- if (reduceMax > 0) {
- ChoiceImpl choice = new ChoiceImpl(true);
- Set set = new LinkedHashSet<>();
-
- for (int i = 0; i <= reduceMax; i++) {
- set.add(String.valueOf(i));
- }
- choice.setChoices(set);
- choice.setMessage("Reduce ability cost");
- if (!controller.choose(Outcome.Benefit, choice, game)) {
- return false;
- }
- int reduce = Integer.parseInt(choice.getChoice());
- CardUtil.reduceCost(abilityToModify, reduce);
- }
+ if (controller == null) {
+ return false;
+ }
+ Mana mana = abilityToModify.getManaCostsToPay().getMana();
+ int reduceMax = mana.getGeneric();
+ if (reduceMax > 0 && mana.count() == mana.getGeneric()) {
+ reduceMax--;
+ }
+ if (reduceMax > 2) {
+ reduceMax = 2;
+ }
+ if (reduceMax <= 0) {
return true;
}
+ ChoiceImpl choice = new ChoiceImpl(true);
+ Set set = new LinkedHashSet<>();
+
+ for (int i = 0; i <= reduceMax; i++) {
+ set.add(String.valueOf(i));
+ }
+ choice.setChoices(set);
+ choice.setMessage("Reduce ability cost");
+ if (!controller.choose(Outcome.Benefit, choice, game)) {
+ return false;
+ }
+ int reduce = Integer.parseInt(choice.getChoice());
+ CardUtil.reduceCost(abilityToModify, reduce);
+ return true;
- return false;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
- if (abilityToModify.getAbilityType() == AbilityType.ACTIVATED
- || (abilityToModify.getAbilityType() == AbilityType.MANA && (abilityToModify instanceof ActivatedAbility))) {
- //Activated abilities of creatures you control
- Permanent permanent = game.getPermanent(abilityToModify.getSourceId());
- if (permanent != null && permanent.isControlledBy(source.getControllerId())) {
- return true;
- }
+ if (abilityToModify.getAbilityType() != AbilityType.ACTIVATED
+ && (abilityToModify.getAbilityType() != AbilityType.MANA
+ || !(abilityToModify instanceof ActivatedAbility))) {
+ return false;
}
- return false;
+ //Activated abilities of creatures you control
+ Permanent permanent = game.getPermanent(abilityToModify.getSourceId());
+ return permanent != null && permanent.isCreature()
+ && permanent.isControlledBy(source.getControllerId());
}
@Override
diff --git a/Mage.Sets/src/mage/cards/t/TrappedInTheTower.java b/Mage.Sets/src/mage/cards/t/TrappedInTheTower.java
new file mode 100644
index 00000000000..407eb71cfe6
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TrappedInTheTower.java
@@ -0,0 +1,56 @@
+package mage.cards.t;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.combat.CantBlockAttackActivateAttachedEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.AbilityPredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TrappedInTheTower extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature without flying");
+
+ static {
+ filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
+ }
+
+ public TrappedInTheTower(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
+
+ this.subtype.add(SubType.AURA);
+
+ // Enchant creature without flying
+ TargetPermanent auraTarget = new TargetPermanent(filter);
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.LoseAbility));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // Enchanted creature can't attack or block, and its activated abilities can't be activated.
+ this.addAbility(new SimpleStaticAbility(new CantBlockAttackActivateAttachedEffect()));
+ }
+
+ private TrappedInTheTower(final TrappedInTheTower card) {
+ super(card);
+ }
+
+ @Override
+ public TrappedInTheTower copy() {
+ return new TrappedInTheTower(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TreacherousUrge.java b/Mage.Sets/src/mage/cards/t/TreacherousUrge.java
index 21fc9a93c45..412ae5bf62f 100644
--- a/Mage.Sets/src/mage/cards/t/TreacherousUrge.java
+++ b/Mage.Sets/src/mage/cards/t/TreacherousUrge.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.UUID;
@@ -18,7 +17,7 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -33,7 +32,7 @@ import mage.target.targetpointer.FixedTarget;
public final class TreacherousUrge extends CardImpl {
public TreacherousUrge(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{4}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{B}");
// Target opponent reveals their hand. You may put a creature card from it onto the battlefield under your control. That creature gains haste. Sacrifice it at the beginning of the next end step.
this.getSpellAbility().addEffect(new TreacherousUrgeEffect());
@@ -52,8 +51,6 @@ public final class TreacherousUrge extends CardImpl {
class TreacherousUrgeEffect extends OneShotEffect {
- private static final FilterCreatureCard filter = new FilterCreatureCard();
-
public TreacherousUrgeEffect() {
super(Outcome.Benefit);
this.staticText = "Target opponent reveals their hand. You may put a creature card from it onto the battlefield under your control. That creature gains haste. Sacrifice it at the beginning of the next end step";
@@ -76,10 +73,10 @@ class TreacherousUrgeEffect extends OneShotEffect {
opponent.revealCards(sourceObject.getName(), opponent.getHand(), game);
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- int cardsHand = opponent.getHand().count(filter, game);
+ int cardsHand = opponent.getHand().count(StaticFilters.FILTER_CARD_CREATURE, game);
Card card = null;
if (cardsHand > 0) {
- TargetCard target = new TargetCard(Zone.HAND, filter);
+ TargetCard target = new TargetCard(Zone.HAND, StaticFilters.FILTER_CARD_CREATURE);
if (controller.choose(Outcome.Benefit, opponent.getHand(), target, game)) {
card = opponent.getHand().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/cards/t/TreasureKeeper.java b/Mage.Sets/src/mage/cards/t/TreasureKeeper.java
index 640272be9af..1bd30575c36 100644
--- a/Mage.Sets/src/mage/cards/t/TreasureKeeper.java
+++ b/Mage.Sets/src/mage/cards/t/TreasureKeeper.java
@@ -1,7 +1,5 @@
-
package mage.cards.t;
-import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
@@ -17,8 +15,10 @@ import mage.constants.SubType;
import mage.game.Game;
import mage.players.Player;
+import java.util.UUID;
+import mage.MageObject;
+
/**
- *
* @author fireshoes
*/
public final class TreasureKeeper extends CardImpl {
@@ -49,8 +49,10 @@ class TreasureKeeperEffect extends OneShotEffect {
public TreasureKeeperEffect() {
super(Outcome.PlayForFree);
- this.staticText = "reveal cards from the top of your library until you reveal a nonland card with converted mana cost 3 or less. "
- + "You may cast that card without paying its mana cost. Put all revealed cards not cast this way on the bottom of your library in a random order";
+ this.staticText = "reveal cards from the top of your library until you reveal a "
+ + "nonland card with converted mana cost 3 or less. "
+ + "You may cast that card without paying its mana cost. Put all revealed "
+ + "cards not cast this way on the bottom of your library in a random order";
}
public TreasureKeeperEffect(TreasureKeeperEffect effect) {
@@ -59,8 +61,10 @@ class TreasureKeeperEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
+ Boolean cardWasCast = false;
Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
+ if (controller != null
+ && !controller.getLibrary().isEmptyDraw()) {
CardsImpl toReveal = new CardsImpl();
Card nonLandCard = null;
for (Card card : controller.getLibrary().getCards(game)) {
@@ -71,14 +75,19 @@ class TreasureKeeperEffect extends OneShotEffect {
}
}
controller.revealCards(source, toReveal, game);
- if (nonLandCard != null && controller.chooseUse(outcome, "Cast " + nonLandCard.getLogName() + "without paying its mana cost?", source, game)) {
- controller.cast(nonLandCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
- toReveal.remove(nonLandCard);
+ if (nonLandCard != null
+ && controller.chooseUse(Outcome.PlayForFree, "Cast " + nonLandCard.getLogName() + " without paying its mana cost?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + nonLandCard.getId(), Boolean.TRUE);
+ cardWasCast = controller.cast(controller.chooseAbilityForCast(nonLandCard, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + nonLandCard.getId(), null);
+ if (cardWasCast) {
+ toReveal.remove(nonLandCard);
+ }
}
controller.putCardsOnBottomOfLibrary(toReveal, game, source, false);
- return true;
}
- return false;
+ return cardWasCast;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/t/TreeshakerChimera.java b/Mage.Sets/src/mage/cards/t/TreeshakerChimera.java
new file mode 100644
index 00000000000..d9f9476d45b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TreeshakerChimera.java
@@ -0,0 +1,42 @@
+package mage.cards.t;
+
+import mage.MageInt;
+import mage.abilities.common.DiesTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.combat.MustBeBlockedByAllSourceEffect;
+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 TreeshakerChimera extends CardImpl {
+
+ public TreeshakerChimera(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}");
+
+ this.subtype.add(SubType.CHIMERA);
+ this.power = new MageInt(8);
+ this.toughness = new MageInt(5);
+
+ // All creatures able to block Treeshaker Chimera do so.
+ this.addAbility(new SimpleStaticAbility(new MustBeBlockedByAllSourceEffect()));
+
+ // When Treeshaker Chimera dies, draw three cards.
+ this.addAbility(new DiesTriggeredAbility(new DrawCardSourceControllerEffect(3)));
+ }
+
+ private TreeshakerChimera(final TreeshakerChimera card) {
+ super(card);
+ }
+
+ @Override
+ public TreeshakerChimera copy() {
+ return new TreeshakerChimera(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TrepanationBlade.java b/Mage.Sets/src/mage/cards/t/TrepanationBlade.java
index d0e89515c72..b5d83710066 100644
--- a/Mage.Sets/src/mage/cards/t/TrepanationBlade.java
+++ b/Mage.Sets/src/mage/cards/t/TrepanationBlade.java
@@ -33,7 +33,7 @@ public final class TrepanationBlade extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
this.subtype.add(SubType.EQUIPMENT);
- // Whenever equipped creature attacks, defending player reveals cards from the top of their library until he or she reveals a land card.
+ // Whenever equipped creature attacks, defending player reveals cards from the top of their library until they reveal a land card.
// The creature gets +1/+0 until end of turn for each card revealed this way. That player puts the revealed cards into their graveyard.
this.addAbility(new AttacksAttachedTriggeredAbility(new TrepanationBladeDiscardEffect()));
@@ -55,7 +55,7 @@ class TrepanationBladeDiscardEffect extends OneShotEffect {
public TrepanationBladeDiscardEffect() {
super(Outcome.Discard);
- this.staticText = "defending player reveals cards from the top of their library until he or she reveals a land card. The creature gets +1/+0 until end of turn for each card revealed this way. That player puts the revealed cards into their graveyard";
+ this.staticText = "defending player reveals cards from the top of their library until they reveal a land card. The creature gets +1/+0 until end of turn for each card revealed this way. That player puts the revealed cards into their graveyard";
}
public TrepanationBladeDiscardEffect(final TrepanationBladeDiscardEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/t/TrueLovesKiss.java b/Mage.Sets/src/mage/cards/t/TrueLovesKiss.java
new file mode 100644
index 00000000000..98d92a92ab6
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TrueLovesKiss.java
@@ -0,0 +1,37 @@
+package mage.cards.t;
+
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.ExileTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.StaticFilters;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TrueLovesKiss extends CardImpl {
+
+ public TrueLovesKiss(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}{W}");
+
+ // Exile target artifact or enchantment.
+ this.getSpellAbility().addEffect(new ExileTargetEffect());
+ this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT));
+
+ // Draw a card
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
+ }
+
+ private TrueLovesKiss(final TrueLovesKiss card) {
+ super(card);
+ }
+
+ @Override
+ public TrueLovesKiss copy() {
+ return new TrueLovesKiss(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TrueNameNemesis.java b/Mage.Sets/src/mage/cards/t/TrueNameNemesis.java
index bc5fefd8179..4ce75bb2121 100644
--- a/Mage.Sets/src/mage/cards/t/TrueNameNemesis.java
+++ b/Mage.Sets/src/mage/cards/t/TrueNameNemesis.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.UUID;
@@ -36,7 +35,7 @@ import mage.game.stack.StackObject;
public final class TrueNameNemesis extends CardImpl {
public TrueNameNemesis(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}");
this.subtype.add(SubType.MERFOLK);
this.subtype.add(SubType.ROGUE);
@@ -44,9 +43,11 @@ public final class TrueNameNemesis extends CardImpl {
this.toughness = new MageInt(1);
// As True-Name Nemesis enters the battlefield, choose a player.
- this.addAbility(new AsEntersBattlefieldAbility(new ChoosePlayerEffect(Outcome.Protect)));
+ this.addAbility(new AsEntersBattlefieldAbility(new ChoosePlayerEffect(Outcome.Detriment)));
+
// True-Name Nemesis has protection from the chosen player.
this.addAbility(new ProtectionFromPlayerAbility());
+
}
public TrueNameNemesis(final TrueNameNemesis card) {
diff --git a/Mage.Sets/src/mage/cards/t/TuinvaleTreefolk.java b/Mage.Sets/src/mage/cards/t/TuinvaleTreefolk.java
new file mode 100644
index 00000000000..ba0d79dc7be
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TuinvaleTreefolk.java
@@ -0,0 +1,41 @@
+package mage.cards.t;
+
+import mage.MageInt;
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.cards.AdventureCard;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TuinvaleTreefolk extends AdventureCard {
+
+ public TuinvaleTreefolk(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.SORCERY}, "{5}{G}", "Oaken Boon", "{3}{G}");
+
+ this.subtype.add(SubType.TREEFOLK);
+ this.subtype.add(SubType.DRUID);
+ this.power = new MageInt(6);
+ this.toughness = new MageInt(5);
+
+ // Oaken Boon
+ // Put two +1/+1 counters on target creature.
+ this.getSpellCard().getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)));
+ this.getSpellCard().getSpellAbility().addTarget(new TargetCreaturePermanent());
+ }
+
+ private TuinvaleTreefolk(final TuinvaleTreefolk card) {
+ super(card);
+ }
+
+ @Override
+ public TuinvaleTreefolk copy() {
+ return new TuinvaleTreefolk(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TurnIntoAPumpkin.java b/Mage.Sets/src/mage/cards/t/TurnIntoAPumpkin.java
new file mode 100644
index 00000000000..93246265811
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TurnIntoAPumpkin.java
@@ -0,0 +1,47 @@
+package mage.cards.t;
+
+import mage.abilities.condition.common.AdamantCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.game.permanent.token.FoodToken;
+import mage.target.common.TargetNonlandPermanent;
+import mage.watchers.common.ManaSpentToCastWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TurnIntoAPumpkin extends CardImpl {
+
+ public TurnIntoAPumpkin(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}");
+
+ // Return target nonland permanent to its owner's hand. Draw a card.
+ this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("Draw a card."));
+ this.getSpellAbility().addTarget(new TargetNonlandPermanent());
+
+ // Adamant — If at least three blue mana was spent to cast this spell, create a Food token.
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new CreateTokenEffect(new FoodToken()), AdamantCondition.BLUE,
+ "
Adamant — If at least three blue mana " +
+ "was spent to cast this spell, create a Food token."
+ ));
+ this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher());
+ }
+
+ private TurnIntoAPumpkin(final TurnIntoAPumpkin card) {
+ super(card);
+ }
+
+ @Override
+ public TurnIntoAPumpkin copy() {
+ return new TurnIntoAPumpkin(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TwinningGlass.java b/Mage.Sets/src/mage/cards/t/TwinningGlass.java
index 71646c16ace..b082420dd55 100644
--- a/Mage.Sets/src/mage/cards/t/TwinningGlass.java
+++ b/Mage.Sets/src/mage/cards/t/TwinningGlass.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.List;
@@ -35,8 +34,10 @@ public final class TwinningGlass extends CardImpl {
public TwinningGlass(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
- // {1}, {tap}: You may cast a nonland card from your hand without paying its mana cost if it has the same name as a spell that was cast this turn.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TwinningGlassEffect(), new ManaCostsImpl("{1}"));
+ // {1}, {tap}: You may cast a nonland card from your hand without paying
+ // its mana cost if it has the same name as a spell that was cast this turn.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
+ new TwinningGlassEffect(), new ManaCostsImpl("{1}"));
ability.addWatcher(new SpellsCastWatcher());
ability.addCost(new TapSourceCost());
this.addAbility(ability);
@@ -56,8 +57,10 @@ public final class TwinningGlass extends CardImpl {
class TwinningGlassEffect extends OneShotEffect {
public TwinningGlassEffect() {
- super(Outcome.PutCardInPlay);
- this.staticText = "You may cast a nonland card from your hand without paying its mana cost if it has the same name as a spell that was cast this turn";
+ super(Outcome.PlayForFree);
+ this.staticText = "You may cast a nonland card from your hand "
+ + "without paying its mana cost if it has the same name "
+ + "as a spell that was cast this turn";
}
public TwinningGlassEffect(final TwinningGlassEffect effect) {
@@ -92,11 +95,15 @@ class TwinningGlassEffect extends OneShotEffect {
}
}
TargetCardInHand target = new TargetCardInHand(0, 1, filterCard);
- if (controller.choose(Outcome.Benefit, controller.getHand(), target, game)) {
+ if (controller.choose(Outcome.PlayForFree, controller.getHand(), target, game)) {
Card chosenCard = game.getCard(target.getFirstTarget());
if (chosenCard != null) {
- if (controller.chooseUse(outcome, "Cast the card without paying mana cost?", source, game)) {
- return controller.cast(chosenCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ if (controller.chooseUse(Outcome.PlayForFree, "Cast the card without paying mana cost?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + chosenCard.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(chosenCard, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + chosenCard.getId(), null);
+ return cardWasCast;
}
}
}
diff --git a/Mage.Sets/src/mage/cards/t/TymaretCallsTheDead.java b/Mage.Sets/src/mage/cards/t/TymaretCallsTheDead.java
new file mode 100644
index 00000000000..abdd56dfade
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TymaretCallsTheDead.java
@@ -0,0 +1,142 @@
+package mage.cards.t;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SagaAbility;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveControllerEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.FilterCard;
+import mage.filter.FilterPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.game.Game;
+import mage.game.permanent.token.ZombieToken;
+import mage.players.Player;
+import mage.target.TargetCard;
+import mage.target.common.TargetCardInYourGraveyard;
+
+import java.util.UUID;
+
+import static mage.constants.Outcome.Benefit;
+
+/**
+ * @author TheElk801
+ */
+public final class TymaretCallsTheDead extends CardImpl {
+
+ public TymaretCallsTheDead(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}");
+
+ this.subtype.add(SubType.SAGA);
+
+ // (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)
+ SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_III);
+
+ // I, II — Put the top three cards of your library into your graveyard. Then you may exile a creature or enchantment card from your graveyard. If you do, create a 2/2 black Zombie creature token.
+ sagaAbility.addChapterEffect(
+ this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, new TymaretCallsTheDeadFirstEffect()
+ );
+
+ // III — You gain X life and scry X, where X is the number of Zombies you control.
+ sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new TymaretCallsTheDeadLastEffect());
+
+ this.addAbility(sagaAbility);
+ }
+
+ private TymaretCallsTheDead(final TymaretCallsTheDead card) {
+ super(card);
+ }
+
+ @Override
+ public TymaretCallsTheDead copy() {
+ return new TymaretCallsTheDead(this);
+ }
+}
+
+class TymaretCallsTheDeadFirstEffect extends OneShotEffect {
+
+ private static final Effect millEffect = new PutTopCardOfLibraryIntoGraveControllerEffect(3);
+ private static final Effect tokenEffect = new CreateTokenEffect(new ZombieToken());
+ private static final FilterCard filter = new FilterCard("creature or enchantment card from your graveyard");
+
+ static {
+ filter.add(Predicates.or(
+ new CardTypePredicate(CardType.CREATURE),
+ new CardTypePredicate(CardType.ENCHANTMENT)
+ ));
+ }
+
+ TymaretCallsTheDeadFirstEffect() {
+ super(Benefit);
+ staticText = "put the top three cards of your library into your graveyard. " +
+ "Then you may exile a creature or enchantment card from your graveyard. " +
+ "If you do, create a 2/2 black Zombie creature token";
+ }
+
+ private TymaretCallsTheDeadFirstEffect(final TymaretCallsTheDeadFirstEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public TymaretCallsTheDeadFirstEffect copy() {
+ return new TymaretCallsTheDeadFirstEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ millEffect.apply(game, source);
+ if (player.getGraveyard().count(filter, game) == 0
+ || !player.chooseUse(Outcome.Exile, "Exile a creature or enchantment card from your graveyard?", source, game)) {
+ return true;
+ }
+ TargetCard target = new TargetCardInYourGraveyard(filter);
+ target.setNotTarget(true);
+ if (!player.choose(outcome, player.getGraveyard(), target, game)) {
+ return true;
+ }
+ return player.moveCards(game.getCard(target.getFirstTarget()), Zone.EXILED, source, game)
+ && tokenEffect.apply(game, source);
+ }
+}
+
+class TymaretCallsTheDeadLastEffect extends OneShotEffect {
+
+ private static final FilterPermanent filter = new FilterPermanent(SubType.ZOMBIE, "");
+
+ TymaretCallsTheDeadLastEffect() {
+ super(Benefit);
+ staticText = "You gain X life and scry X, where X is the number of Zombies you control.";
+ }
+
+ private TymaretCallsTheDeadLastEffect(final TymaretCallsTheDeadLastEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public TymaretCallsTheDeadLastEffect copy() {
+ return new TymaretCallsTheDeadLastEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ int zombieCount = game.getBattlefield().countAll(filter, source.getControllerId(), game);
+ if (zombieCount <= 0) {
+ return true;
+ }
+ player.gainLife(zombieCount, game, source);
+ player.scry(zombieCount, source, game);
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/Tyrannize.java b/Mage.Sets/src/mage/cards/t/Tyrannize.java
index ba8b1b9db54..c7055ae97ab 100644
--- a/Mage.Sets/src/mage/cards/t/Tyrannize.java
+++ b/Mage.Sets/src/mage/cards/t/Tyrannize.java
@@ -26,7 +26,7 @@ public final class Tyrannize extends CardImpl {
public Tyrannize(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B/R}{B/R}");
- // Target player discards their hand unless he or she pays 7 life.
+ // Target player discards their hand unless they pay 7 life.
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new TyrannizeEffect());
@@ -46,7 +46,7 @@ class TyrannizeEffect extends OneShotEffect {
TyrannizeEffect() {
super(Outcome.Discard);
- this.staticText = "Target player discards their hand unless he or she pays 7 life";
+ this.staticText = "Target player discards their hand unless they pay 7 life";
}
TyrannizeEffect(final TyrannizeEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/t/TyrantOfDiscord.java b/Mage.Sets/src/mage/cards/t/TyrantOfDiscord.java
index cfec1ac8cee..6f1c1072247 100644
--- a/Mage.Sets/src/mage/cards/t/TyrantOfDiscord.java
+++ b/Mage.Sets/src/mage/cards/t/TyrantOfDiscord.java
@@ -29,7 +29,7 @@ public final class TyrantOfDiscord extends CardImpl {
this.power = new MageInt(7);
this.toughness = new MageInt(7);
- // When Tyrant of Discord enters the battlefield, target opponent chooses a permanent he or she controls at random and sacrifices it. If a nonland permanent is sacrificed this way, repeat this process.
+ // When Tyrant of Discord enters the battlefield, target opponent chooses a permanent they control at random and sacrifices it. If a nonland permanent is sacrificed this way, repeat this process.
Ability ability = new EntersBattlefieldTriggeredAbility(new TyrantOfDiscordEffect());
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
@@ -49,7 +49,7 @@ class TyrantOfDiscordEffect extends OneShotEffect {
public TyrantOfDiscordEffect() {
super(Outcome.Benefit);
- this.staticText = "target opponent chooses a permanent he or she controls at random and sacrifices it. If a nonland permanent is sacrificed this way, repeat this process";
+ this.staticText = "target opponent chooses a permanent they control at random and sacrifices it. If a nonland permanent is sacrificed this way, repeat this process";
}
public TyrantOfDiscordEffect(final TyrantOfDiscordEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/u/UbaMask.java b/Mage.Sets/src/mage/cards/u/UbaMask.java
index 9f56aea2efb..90521396c5a 100644
--- a/Mage.Sets/src/mage/cards/u/UbaMask.java
+++ b/Mage.Sets/src/mage/cards/u/UbaMask.java
@@ -30,7 +30,7 @@ public final class UbaMask extends CardImpl {
// If a player would draw a card, that player exiles that card face up instead.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new UbaMaskReplacementEffect()));
- // Each player may play cards he or she exiled with Uba Mask this turn.
+ // Each player may play cards they exiled with Uba Mask this turn.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new UbaMaskPlayEffect()), new UbaMaskExiledCardsWatcher());
}
@@ -93,7 +93,7 @@ class UbaMaskPlayEffect extends AsThoughEffectImpl {
public UbaMaskPlayEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfGame, Outcome.Benefit);
- staticText = "Each player may play cards he or she exiled with {this} this turn";
+ staticText = "Each player may play cards they exiled with {this} this turn";
}
public UbaMaskPlayEffect(final UbaMaskPlayEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/u/UginsConjurant.java b/Mage.Sets/src/mage/cards/u/UginsConjurant.java
index a633fbff275..cf2582e1318 100644
--- a/Mage.Sets/src/mage/cards/u/UginsConjurant.java
+++ b/Mage.Sets/src/mage/cards/u/UginsConjurant.java
@@ -31,7 +31,7 @@ public final class UginsConjurant extends CardImpl {
// Ugin’s Conjurant enters the battlefield with X +1/+1 counters on it.
this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldWithXCountersEffect(CounterType.P1P1.createInstance())));
// If damage would be dealt to Ugin’s Conjurant while it has a +1/+1 counter on it, prevent that damage and remove that many +1/+1 counters from Ugin’s Conjurant.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventDamageAndRemoveCountersEffect()));
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventDamageAndRemoveCountersEffect(true)));
}
private UginsConjurant(final UginsConjurant card) {
diff --git a/Mage.Sets/src/mage/cards/u/Umbilicus.java b/Mage.Sets/src/mage/cards/u/Umbilicus.java
index c6b87b82423..037f63953b0 100644
--- a/Mage.Sets/src/mage/cards/u/Umbilicus.java
+++ b/Mage.Sets/src/mage/cards/u/Umbilicus.java
@@ -26,7 +26,7 @@ public final class Umbilicus extends CardImpl {
public Umbilicus(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
- // At the beginning of each player's upkeep, that player returns a permanent he or she controls to its owner's hand unless he or she pays 2 life.
+ // At the beginning of each player's upkeep, that player returns a permanent they control to its owner's hand unless they pay 2 life.
Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new BloodClockEffect(), TargetController.ANY, false, true);
this.addAbility(ability);
}
@@ -45,7 +45,7 @@ class BloodClockEffect extends OneShotEffect {
public BloodClockEffect() {
super(Outcome.ReturnToHand);
- this.staticText = "that player returns a permanent he or she controls to its owner's hand unless he or she pays 2 life";
+ this.staticText = "that player returns a permanent they control to its owner's hand unless they pay 2 life";
}
public BloodClockEffect(final BloodClockEffect effect) {
@@ -65,7 +65,7 @@ class BloodClockEffect extends OneShotEffect {
}
if (player.getLife() > 2 && player.chooseUse(Outcome.Neutral, "Pay 2 life? If you don't, return a permanent you control to its owner's hand.", source, game)) {
player.loseLife(2, game, false);
- game.informPlayers(player.getLogName() + " pays 2 life. He will not return a permanent he or she controls.");
+ game.informPlayers(player.getLogName() + " pays 2 life. They will not return a permanent they control.");
return true;
} else {
Target target = new TargetControlledPermanent();
diff --git a/Mage.Sets/src/mage/cards/u/UnbreathingHorde.java b/Mage.Sets/src/mage/cards/u/UnbreathingHorde.java
index 5e3bbe7f5d8..bbf8ba08093 100644
--- a/Mage.Sets/src/mage/cards/u/UnbreathingHorde.java
+++ b/Mage.Sets/src/mage/cards/u/UnbreathingHorde.java
@@ -1,7 +1,5 @@
-
package mage.cards.u;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
@@ -16,18 +14,21 @@ import mage.filter.common.FilterCreatureCard;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
+import java.util.UUID;
+
/**
- *
* @author BetaSteward
*/
public final class UnbreathingHorde extends CardImpl {
public UnbreathingHorde(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.subtype.add(SubType.ZOMBIE);
this.power = new MageInt(0);
@@ -115,7 +116,7 @@ class UnbreathingHordeEffect2 extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
boolean retValue = false;
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
int damage = event.getAmount();
if (!game.replaceEvent(preventEvent)) {
event.setAmount(0);
@@ -132,9 +133,7 @@ class UnbreathingHordeEffect2 extends PreventionEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
- if (event.getTargetId().equals(source.getSourceId())) {
- return true;
- }
+ return event.getTargetId().equals(source.getSourceId());
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/u/UncageTheMenagerie.java b/Mage.Sets/src/mage/cards/u/UncageTheMenagerie.java
index 840fbbe22ef..e45a6432a57 100644
--- a/Mage.Sets/src/mage/cards/u/UncageTheMenagerie.java
+++ b/Mage.Sets/src/mage/cards/u/UncageTheMenagerie.java
@@ -1,14 +1,8 @@
-
package mage.cards.u;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
-import mage.cards.Card;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-import mage.cards.Cards;
-import mage.cards.CardsImpl;
+import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
@@ -19,8 +13,9 @@ import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
+import java.util.UUID;
+
/**
- *
* @author spjspj
*/
public final class UncageTheMenagerie extends CardImpl {
@@ -115,7 +110,7 @@ class UncageTheMenagerieTarget extends TargetCardInLibrary {
}
@Override
- public boolean canTarget(UUID id, Cards cards, Game game) {
+ public boolean canTarget(UUID playerId, UUID id, Ability source, Cards cards, Game game) {
Card card = cards.get(id, game);
if (card != null) {
for (UUID targetId : this.getTargets()) {
@@ -124,11 +119,12 @@ class UncageTheMenagerieTarget extends TargetCardInLibrary {
return false;
}
}
+
if (!(card.isCreature() && card.getConvertedManaCost() == xValue)) {
return false;
}
- return filter.match(card, game);
+ return filter.match(card, playerId, game);
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/u/UnconventionalTactics.java b/Mage.Sets/src/mage/cards/u/UnconventionalTactics.java
index 81b45ca9078..49c18999add 100644
--- a/Mage.Sets/src/mage/cards/u/UnconventionalTactics.java
+++ b/Mage.Sets/src/mage/cards/u/UnconventionalTactics.java
@@ -1,7 +1,5 @@
-
package mage.cards.u;
-import java.util.UUID;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
@@ -24,8 +22,9 @@ import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author spjspj
*/
public final class UnconventionalTactics extends CardImpl {
@@ -91,12 +90,10 @@ class UnconventionalTacticsTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
- if (permanent.isCreature()
+ return permanent != null
+ && permanent.isCreature()
&& permanent.isControlledBy(this.controllerId)
- && filter.match(permanent, game)) {
- return true;
- }
- return false;
+ && filter.match(permanent, game);
}
@Override
diff --git a/Mage.Sets/src/mage/cards/u/UndercityInformer.java b/Mage.Sets/src/mage/cards/u/UndercityInformer.java
index b763a9b4df9..512d191e844 100644
--- a/Mage.Sets/src/mage/cards/u/UndercityInformer.java
+++ b/Mage.Sets/src/mage/cards/u/UndercityInformer.java
@@ -37,7 +37,7 @@ public final class UndercityInformer extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(3);
- //{1}, Sacrifice a creature: Target player reveals the top card of their library until he or she reveals a land card, then puts those cards into their graveyard.
+ //{1}, Sacrifice a creature: Target player reveals the top card of their library until they reveal a land card, then puts those cards into their graveyard.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new UndercityInformerEffect(), new ManaCostsImpl("{1}"));
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
ability.addTarget(new TargetPlayer());
@@ -58,7 +58,7 @@ class UndercityInformerEffect extends OneShotEffect {
public UndercityInformerEffect() {
super(Outcome.PutCardInPlay);
- this.staticText = "Target player reveals the top card of their library until he or she reveals a land card, then puts those cards into their graveyard";
+ this.staticText = "Target player reveals the top card of their library until they reveal a land card, then puts those cards into their graveyard";
}
public UndercityInformerEffect(final UndercityInformerEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/u/UndergrowthScavenger.java b/Mage.Sets/src/mage/cards/u/UndergrowthScavenger.java
index 09d5708e19d..8907d900df2 100644
--- a/Mage.Sets/src/mage/cards/u/UndergrowthScavenger.java
+++ b/Mage.Sets/src/mage/cards/u/UndergrowthScavenger.java
@@ -1,4 +1,3 @@
-
package mage.cards.u;
import java.util.UUID;
@@ -12,7 +11,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -21,7 +20,7 @@ import mage.filter.common.FilterCreatureCard;
public final class UndergrowthScavenger extends CardImpl {
public UndergrowthScavenger(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.subtype.add(SubType.FUNGUS);
this.subtype.add(SubType.HORROR);
@@ -29,9 +28,9 @@ public final class UndergrowthScavenger extends CardImpl {
this.toughness = new MageInt(0);
// Undergrowth Scavenger enters the battlefield with a number of +1/+1 counters on it equal to the number of creature cards in all graveyards.
- Effect effect = new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), new CardsInAllGraveyardsCount(new FilterCreatureCard()), true);
+ Effect effect = new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), new CardsInAllGraveyardsCount(StaticFilters.FILTER_CARD_CREATURE), true);
effect.setText("with a number of +1/+1 counters on it equal to the number of creature cards in all graveyards");
- this.addAbility(new EntersBattlefieldAbility(effect));
+ this.addAbility(new EntersBattlefieldAbility(effect));
}
public UndergrowthScavenger(final UndergrowthScavenger card) {
diff --git a/Mage.Sets/src/mage/cards/u/UnderworldBreach.java b/Mage.Sets/src/mage/cards/u/UnderworldBreach.java
new file mode 100644
index 00000000000..ac4fe71f5ad
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/u/UnderworldBreach.java
@@ -0,0 +1,82 @@
+package mage.cards.u;
+
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ContinuousEffectImpl;
+import mage.abilities.effects.common.SacrificeSourceEffect;
+import mage.abilities.keyword.EscapeAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.players.Player;
+
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class UnderworldBreach extends CardImpl {
+
+ public UnderworldBreach(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}");
+
+ // Each nonland card in your graveyard has escape. The escape cost is equal to the card's mana cost plus exile three other cards from your graveyard.
+ this.addAbility(new SimpleStaticAbility(new UnderworldBreachEffect()));
+
+ // At the beginning of the end step, sacrifice Underworld Breach.
+ this.addAbility(new BeginningOfEndStepTriggeredAbility(
+ new SacrificeSourceEffect(), TargetController.NEXT, false
+ ));
+ }
+
+ private UnderworldBreach(final UnderworldBreach card) {
+ super(card);
+ }
+
+ @Override
+ public UnderworldBreach copy() {
+ return new UnderworldBreach(this);
+ }
+}
+
+class UnderworldBreachEffect extends ContinuousEffectImpl {
+
+ UnderworldBreachEffect() {
+ super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
+ staticText = "Each nonland card in your graveyard has escape. " +
+ "The escape cost is equal to the card's mana cost plus exile three other cards from your graveyard.";
+ }
+
+ private UnderworldBreachEffect(final UnderworldBreachEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) {
+ return false;
+ }
+ controller
+ .getGraveyard()
+ .getCards(game)
+ .stream()
+ .filter(Objects::nonNull)
+ .filter(card -> !card.isLand())
+ .forEach(card -> {
+ Ability ability = new EscapeAbility(card, card.getManaCost().getText(), 3);
+ ability.setSourceId(card.getId());
+ ability.setControllerId(card.getOwnerId());
+ game.getState().addOtherAbility(card, ability);
+ });
+ return true;
+ }
+
+ @Override
+ public UnderworldBreachEffect copy() {
+ return new UnderworldBreachEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/u/UnderworldDreams.java b/Mage.Sets/src/mage/cards/u/UnderworldDreams.java
index 17500870e0a..981427708cb 100644
--- a/Mage.Sets/src/mage/cards/u/UnderworldDreams.java
+++ b/Mage.Sets/src/mage/cards/u/UnderworldDreams.java
@@ -17,7 +17,7 @@ public final class UnderworldDreams extends CardImpl {
public UnderworldDreams(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{B}{B}{B}");
- // Whenever an opponent draws a card, Underworld Dreams deals 1 damage to him or her.
+ // Whenever an opponent draws a card, Underworld Dreams deals 1 damage to that player.
this.addAbility(new DrawCardOpponentTriggeredAbility(new DamageTargetEffect(1, true, "that player"), false, true));
}
diff --git a/Mage.Sets/src/mage/cards/u/UnderworldRageHound.java b/Mage.Sets/src/mage/cards/u/UnderworldRageHound.java
new file mode 100644
index 00000000000..ee3ee87feb5
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/u/UnderworldRageHound.java
@@ -0,0 +1,45 @@
+package mage.cards.u;
+
+import mage.MageInt;
+import mage.abilities.common.AttacksEachCombatStaticAbility;
+import mage.abilities.common.EscapesWithAbility;
+import mage.abilities.keyword.EscapeAbility;
+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 UnderworldRageHound extends CardImpl {
+
+ public UnderworldRageHound(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
+
+ this.subtype.add(SubType.ELEMENTAL);
+ this.subtype.add(SubType.HOUND);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(1);
+
+ // Underworld Rage-Hound attacks each combat if able.
+ this.addAbility(new AttacksEachCombatStaticAbility());
+
+ // Escape—{3}{R}, Exile three other cards from your graveyard.
+ this.addAbility(new EscapeAbility(this, "{3}{R}", 3));
+
+ // Underworld Rage-Hound escapes with a +1/+1 counter on it.
+ this.addAbility(new EscapesWithAbility(1));
+ }
+
+ private UnderworldRageHound(final UnderworldRageHound card) {
+ super(card);
+ }
+
+ @Override
+ public UnderworldRageHound copy() {
+ return new UnderworldRageHound(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/u/UnderworldSentinel.java b/Mage.Sets/src/mage/cards/u/UnderworldSentinel.java
new file mode 100644
index 00000000000..1ad813bb1a1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/u/UnderworldSentinel.java
@@ -0,0 +1,83 @@
+package mage.cards.u;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.common.DiesTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.ExileTargetForSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.StaticFilters;
+import mage.game.ExileZone;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.common.TargetCardInYourGraveyard;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class UnderworldSentinel extends CardImpl {
+
+ public UnderworldSentinel(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
+
+ this.subtype.add(SubType.SKELETON);
+ this.subtype.add(SubType.SOLDIER);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(5);
+
+ // Whenever Underworld Sentinel attacks, exile target creature card from your graveyard.
+ Ability ability = new AttacksTriggeredAbility(new ExileTargetForSourceEffect(), false);
+ ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
+ this.addAbility(ability);
+
+ // When Underworld Sentinel dies, put all cards exiled with it onto the battlefield.
+ this.addAbility(new DiesTriggeredAbility(new UnderworldSentinelEffect()));
+ }
+
+ private UnderworldSentinel(final UnderworldSentinel card) {
+ super(card);
+ }
+
+ @Override
+ public UnderworldSentinel copy() {
+ return new UnderworldSentinel(this);
+ }
+}
+
+class UnderworldSentinelEffect extends OneShotEffect {
+
+ UnderworldSentinelEffect() {
+ super(Outcome.PutCardInPlay);
+ this.staticText = "put all cards exiled with it onto the battlefield";
+ }
+
+ private UnderworldSentinelEffect(final UnderworldSentinelEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public UnderworldSentinelEffect copy() {
+ return new UnderworldSentinelEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) {
+ return false;
+ }
+ ExileZone exileZone = game.getExile().getExileZone(
+ CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter())
+ );
+ return exileZone != null && controller.moveCards(exileZone, Zone.BATTLEFIELD, source, game);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/u/UnexpectedResults.java b/Mage.Sets/src/mage/cards/u/UnexpectedResults.java
index 6a879dbdfd1..4b8fe86e52f 100644
--- a/Mage.Sets/src/mage/cards/u/UnexpectedResults.java
+++ b/Mage.Sets/src/mage/cards/u/UnexpectedResults.java
@@ -1,4 +1,3 @@
-
package mage.cards.u;
import java.util.UUID;
@@ -18,7 +17,7 @@ import mage.players.Player;
/**
* Gatecrash FAQ 01/2013
*
- * If you reveal a nonland card, you may cast it during the resolution of
+ * If you reveal a non-land card, you may cast it during the resolution of
* Unexpected Results. Ignore timing restrictions based on the card's type.
* Other timing restrictions, such as "Cast [this card] only during combat,"
* must be followed.
@@ -47,7 +46,9 @@ public final class UnexpectedResults extends CardImpl {
public UnexpectedResults(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}{U}");
- // Shuffle your library, then reveal the top card. If it's a nonland card, you may cast it without paying its mana cost. If it's a land card, you may put it onto the battlefield and return Unexpected Results to its owner's hand.
+ // Shuffle your library, then reveal the top card. If it's a nonland card,
+ // you may cast it without paying its mana cost. If it's a land card, you may
+ // put it onto the battlefield and return Unexpected Results to its owner's hand.
this.getSpellAbility().addEffect(new UnexpectedResultEffect());
}
@@ -66,7 +67,10 @@ class UnexpectedResultEffect extends OneShotEffect {
public UnexpectedResultEffect() {
super(Outcome.PlayForFree);
- this.staticText = "Shuffle your library, then reveal the top card. If it's a nonland card, you may cast it without paying its mana cost. If it's a land card, you may put it onto the battlefield and return {this} to its owner's hand";
+ this.staticText = "Shuffle your library, then reveal the top card. "
+ + "If it's a nonland card, you may cast it without paying its mana "
+ + "cost. If it's a land card, you may put it onto the battlefield "
+ + "and return {this} to its owner's hand";
}
public UnexpectedResultEffect(final UnexpectedResultEffect effect) {
@@ -82,7 +86,8 @@ class UnexpectedResultEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Card sourceCard = game.getCard(source.getSourceId());
- if (controller == null || sourceCard == null) {
+ if (controller == null
+ || sourceCard == null) {
return false;
}
if (controller.getLibrary().hasCards()) {
@@ -100,8 +105,13 @@ class UnexpectedResultEffect extends OneShotEffect {
return true;
}
} else {
- if (controller.chooseUse(outcome, "Cast " + card.getName() + " without paying its mana cost?", source, game)) {
- return controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ if (controller.chooseUse(outcome, "Cast " + card.getName()
+ + " without paying its mana cost?", source, game)) {
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ return cardWasCast;
}
}
return true;
diff --git a/Mage.Sets/src/mage/cards/u/UnexplainedVision.java b/Mage.Sets/src/mage/cards/u/UnexplainedVision.java
new file mode 100644
index 00000000000..3fb0d06e51c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/u/UnexplainedVision.java
@@ -0,0 +1,41 @@
+package mage.cards.u;
+
+import mage.abilities.condition.common.AdamantCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.keyword.ScryEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.watchers.common.ManaSpentToCastWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class UnexplainedVision extends CardImpl {
+
+ public UnexplainedVision(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}");
+
+ // Draw three cards.
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(3));
+
+ // Adamant — If at least three blue mana was spent to cast this spell, scry 3.
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new ScryEffect(3), AdamantCondition.BLUE, "
Adamant — " +
+ "If at least three blue mana was spent to cast this spell, scry 3."
+ ));
+ this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher());
+ }
+
+ private UnexplainedVision(final UnexplainedVision card) {
+ super(card);
+ }
+
+ @Override
+ public UnexplainedVision copy() {
+ return new UnexplainedVision(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/u/UnifyingTheory.java b/Mage.Sets/src/mage/cards/u/UnifyingTheory.java
index e512fb528be..365f47ad428 100644
--- a/Mage.Sets/src/mage/cards/u/UnifyingTheory.java
+++ b/Mage.Sets/src/mage/cards/u/UnifyingTheory.java
@@ -27,7 +27,7 @@ public final class UnifyingTheory extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{U}");
- // Whenever a player casts a spell, that player may pay {2}. If the player does, he or she draws a card.
+ // Whenever a player casts a spell, that player may pay {2}. If the player does, they draw a card.
this.addAbility(new SpellCastAllTriggeredAbility(new UnifyingTheoryEffect() , new FilterSpell("a spell"), false, SetTargetPointer.PLAYER));
}
@@ -45,7 +45,7 @@ class UnifyingTheoryEffect extends OneShotEffect {
public UnifyingTheoryEffect() {
super(Outcome.Detriment);
- this.staticText = "that player may pay {2}. If the player does, he or she draws a card";
+ this.staticText = "that player may pay {2}. If the player does, they draw a card";
}
public UnifyingTheoryEffect(final UnifyingTheoryEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/u/UnnervingAssault.java b/Mage.Sets/src/mage/cards/u/UnnervingAssault.java
index 5b38d3a21fa..d3ab5d6af2b 100644
--- a/Mage.Sets/src/mage/cards/u/UnnervingAssault.java
+++ b/Mage.Sets/src/mage/cards/u/UnnervingAssault.java
@@ -37,7 +37,7 @@ public final class UnnervingAssault extends CardImpl {
// Creatures your opponents control get -1/-0 until end of turn if {U} was spent to cast Unnerving Assault, and creatures you control get +1/+0 until end of turn if {R} was spent to cast it.
this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
new BoostAllEffect(-1, 0, Duration.EndOfTurn, filter, false),
- new ManaWasSpentCondition(ColoredManaSymbol.U), "Creatures your opponents control get -1/-0 until end of turn if {U} was spent to cast {this},"));
+ new ManaWasSpentCondition(ColoredManaSymbol.U), "Creatures your opponents control get -1/-0 until end of turn if {U} was spent to cast this spell,"));
this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
new BoostAllEffect(1, 0, Duration.EndOfTurn, filter2, false),
new ManaWasSpentCondition(ColoredManaSymbol.R), " and creatures you control get +1/+0 until end of turn if {R} was spent to cast it"));
diff --git a/Mage.Sets/src/mage/cards/u/UrzaAcademyHeadmaster.java b/Mage.Sets/src/mage/cards/u/UrzaAcademyHeadmaster.java
index fca36bf6e5a..66e4c3b6eed 100644
--- a/Mage.Sets/src/mage/cards/u/UrzaAcademyHeadmaster.java
+++ b/Mage.Sets/src/mage/cards/u/UrzaAcademyHeadmaster.java
@@ -1,5 +1,6 @@
package mage.cards.u;
+import java.util.*;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
@@ -45,8 +46,6 @@ import mage.target.TargetPlayer;
import mage.target.common.*;
import mage.util.RandomUtil;
-import java.util.*;
-
/**
* @author L_J
*/
@@ -187,7 +186,7 @@ class UrzaAcademyHeadmasterRandomEffect extends OneShotEffect {
effects.add(new mage.cards.j.JaceArchitectOfThought(controller.getId(), setInfo).getAbilities().get(2).getEffects().get(0));
break;
case 11: // KARN LIBERATED 1
- sb.append("Target player exiles a card from his or her hand.");
+ sb.append("Target player exiles a card from their hand.");
effects.add(new ExileFromZoneTargetEffect(Zone.HAND, null, "", new FilterCard()));
target = new TargetPlayer();
break;
@@ -263,14 +262,14 @@ class UrzaAcademyHeadmasterRandomEffect extends OneShotEffect {
break;
case 6: // (altered) GARRUK CALLER OF BEASTS 2
sb.append("You may put a creature card from your hand onto the battlefield.");
- effects.add(new PutCardFromHandOntoBattlefieldEffect(new FilterCreatureCard()));
+ effects.add(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_CREATURE));
break;
case 7: // (altered) JACE THE MIND SCULPTOR 2
sb.append("Draw three cards, then put a card from your hand on top of your library.");
effects.add(new UrzaAcademyHeadmasterBrainstormEffect());
break;
case 8: // JACE MEMORY ADEPT 2
- sb.append("Target player puts the top ten cards of his or her library into his or her graveyard.");
+ sb.append("Target player puts the top ten cards of their library into their graveyard.");
effects.add(new PutLibraryIntoGraveTargetEffect(10));
target = new TargetPlayer();
break;
@@ -360,7 +359,7 @@ class UrzaAcademyHeadmasterRandomEffect extends OneShotEffect {
effects.add(new GainLifeEffect(100));
break;
case 6: // CHANDRA NALAAR 3
- sb.append("Urza deals 10 damage to target player and each creature he or she controls.");
+ sb.append("Urza deals 10 damage to target player and each creature they control.");
effects.add(new DamageTargetEffect(10));
effects.add(new DamageAllControlledTargetEffect(10, new FilterCreaturePermanent()));
target = new TargetPlayerOrPlaneswalker();
@@ -378,7 +377,7 @@ class UrzaAcademyHeadmasterRandomEffect extends OneShotEffect {
effects.add(new CreateTokenEffect(new WurmToken(), new PermanentsOnBattlefieldCount(new FilterControlledLandPermanent())));
break;
case 10: // JACE THE LIVING GUILDPACT 3
- sb.append("Each player shuffles his or her hand and graveyard into his or her library. You draw seven cards.");
+ sb.append("Each player shuffles their hand and graveyard into their library. You draw seven cards.");
effects.add(new ShuffleHandGraveyardAllEffect());
effects.add(new DrawCardSourceControllerEffect(7));
break;
@@ -402,7 +401,7 @@ class UrzaAcademyHeadmasterRandomEffect extends OneShotEffect {
target = new TargetPlayer();
break;
case 15: // JACE THE MIND SCULPTOR 4
- sb.append("Exile all cards from target player’s library, then that player shuffles his or her hand into his or her library.");
+ sb.append("Exile all cards from target player’s library, then that player shuffles their hand into their library.");
effects.add(new mage.cards.j.JaceTheMindSculptor(controller.getId(), setInfo).getAbilities().get(5).getEffects().get(0));
target = new TargetPlayer();
break;
diff --git a/Mage.Sets/src/mage/cards/v/VampireAristocrat.java b/Mage.Sets/src/mage/cards/v/VampireAristocrat.java
index 0c20539e792..aeb08d03d0e 100644
--- a/Mage.Sets/src/mage/cards/v/VampireAristocrat.java
+++ b/Mage.Sets/src/mage/cards/v/VampireAristocrat.java
@@ -1,7 +1,5 @@
-
package mage.cards.v;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -11,22 +9,22 @@ import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
+import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.target.common.TargetControlledCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author Loki
*/
public final class VampireAristocrat extends CardImpl {
public VampireAristocrat(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}");
- this.subtype.add(SubType.VAMPIRE);
- this.subtype.add(SubType.ROGUE);
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
+ this.subtype.add(SubType.VAMPIRE, SubType.NOBLE, SubType.ROGUE);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
diff --git a/Mage.Sets/src/mage/cards/v/VampireHounds.java b/Mage.Sets/src/mage/cards/v/VampireHounds.java
index 6f00309cf0f..f231c28a653 100644
--- a/Mage.Sets/src/mage/cards/v/VampireHounds.java
+++ b/Mage.Sets/src/mage/cards/v/VampireHounds.java
@@ -1,4 +1,3 @@
-
package mage.cards.v;
import java.util.UUID;
@@ -9,10 +8,10 @@ import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
+import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCardInHand;
/**
@@ -22,7 +21,7 @@ import mage.target.common.TargetCardInHand;
public final class VampireHounds extends CardImpl {
public VampireHounds(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.subtype.add(SubType.VAMPIRE);
this.subtype.add(SubType.HOUND);
this.power = new MageInt(2);
@@ -30,9 +29,9 @@ public final class VampireHounds extends CardImpl {
// Discard a creature card: Vampire Hounds gets +2/+2 until end of turn.
this.addAbility(new SimpleActivatedAbility(
- Zone.BATTLEFIELD,
- new BoostSourceEffect(2, 2, Duration.EndOfTurn),
- new DiscardTargetCost(new TargetCardInHand(new FilterCreatureCard()))));
+ Zone.BATTLEFIELD,
+ new BoostSourceEffect(2, 2, Duration.EndOfTurn),
+ new DiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE))));
}
public VampireHounds(final VampireHounds card) {
diff --git a/Mage.Sets/src/mage/cards/v/VampireNoble.java b/Mage.Sets/src/mage/cards/v/VampireNoble.java
index 88099f000db..67189ec9c63 100644
--- a/Mage.Sets/src/mage/cards/v/VampireNoble.java
+++ b/Mage.Sets/src/mage/cards/v/VampireNoble.java
@@ -1,22 +1,21 @@
-
package mage.cards.v;
-import java.util.UUID;
import mage.MageInt;
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 VampireNoble extends CardImpl {
public VampireNoble(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}");
- this.subtype.add(SubType.VAMPIRE);
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
+ this.subtype.add(SubType.VAMPIRE, SubType.NOBLE);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
}
diff --git a/Mage.Sets/src/mage/cards/v/VampireSovereign.java b/Mage.Sets/src/mage/cards/v/VampireSovereign.java
index 1cfbfe42b60..66b5549d08c 100644
--- a/Mage.Sets/src/mage/cards/v/VampireSovereign.java
+++ b/Mage.Sets/src/mage/cards/v/VampireSovereign.java
@@ -1,20 +1,20 @@
package mage.cards.v;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LoseLifeTargetEffect;
-import mage.constants.SubType;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
+import mage.constants.SubType;
import mage.target.common.TargetOpponent;
+import java.util.UUID;
+
/**
- *
* @author TheElk801
*/
public final class VampireSovereign extends CardImpl {
@@ -22,7 +22,7 @@ public final class VampireSovereign extends CardImpl {
public VampireSovereign(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
- this.subtype.add(SubType.VAMPIRE);
+ this.subtype.add(SubType.VAMPIRE, SubType.NOBLE);
this.power = new MageInt(3);
this.toughness = new MageInt(4);
diff --git a/Mage.Sets/src/mage/cards/v/VantressGargoyle.java b/Mage.Sets/src/mage/cards/v/VantressGargoyle.java
new file mode 100644
index 00000000000..0639373464c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/v/VantressGargoyle.java
@@ -0,0 +1,116 @@
+package mage.cards.v;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.RestrictionEffect;
+import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveEachPlayerEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class VantressGargoyle extends CardImpl {
+
+ public VantressGargoyle(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{U}");
+
+ this.subtype.add(SubType.GARGOYLE);
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(4);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Vantress Gargoyle can't attack unless defending player has seven or more cards in their graveyard.
+ this.addAbility(new SimpleStaticAbility(new VantressGargoyleAttackEffect()));
+
+ // Vantress Gargoyle can't block unless you have four or more cards in hand.
+ this.addAbility(new SimpleStaticAbility(new VantressGargoyleBlockEffect()));
+
+ // {T}: Each player puts the top card of their library into their graveyard.
+ this.addAbility(new SimpleActivatedAbility(
+ new PutTopCardOfLibraryIntoGraveEachPlayerEffect(1, TargetController.ANY), new TapSourceCost()
+ ));
+ }
+
+ private VantressGargoyle(final VantressGargoyle card) {
+ super(card);
+ }
+
+ @Override
+ public VantressGargoyle copy() {
+ return new VantressGargoyle(this);
+ }
+}
+
+class VantressGargoyleAttackEffect extends RestrictionEffect {
+
+ VantressGargoyleAttackEffect() {
+ super(Duration.WhileOnBattlefield);
+ staticText = "{this} can't attack unless defending player has seven or more cards in their graveyard";
+ }
+
+ private VantressGargoyleAttackEffect(final VantressGargoyleAttackEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean applies(Permanent permanent, Ability source, Game game) {
+ return permanent.getId().equals(source.getSourceId());
+ }
+
+ @Override
+ public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game, boolean canUseChooseDialogs) {
+ Player player = game.getPlayerOrPlaneswalkerController(defenderId);
+ return player != null && player.getGraveyard().size() > 6;
+ }
+
+ @Override
+ public VantressGargoyleAttackEffect copy() {
+ return new VantressGargoyleAttackEffect(this);
+ }
+}
+
+class VantressGargoyleBlockEffect extends RestrictionEffect {
+
+ VantressGargoyleBlockEffect() {
+ super(Duration.WhileOnBattlefield);
+ staticText = "{this} can't block unless you have four or more cards in hand";
+ }
+
+ private VantressGargoyleBlockEffect(final VantressGargoyleBlockEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public VantressGargoyleBlockEffect copy() {
+ return new VantressGargoyleBlockEffect(this);
+ }
+
+ @Override
+ public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game, boolean canUseChooseDialogs) {
+ return false;
+ }
+
+ @Override
+ public boolean applies(Permanent permanent, Ability source, Game game) {
+ Player player = game.getPlayer(source.getControllerId());
+ return player != null
+ && player.getHand().size() < 4
+ && permanent.getId().equals(source.getSourceId());
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/v/VantressPaladin.java b/Mage.Sets/src/mage/cards/v/VantressPaladin.java
new file mode 100644
index 00000000000..2c1ef9dfef1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/v/VantressPaladin.java
@@ -0,0 +1,50 @@
+package mage.cards.v;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.condition.common.AdamantCondition;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.watchers.common.ManaSpentToCastWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class VantressPaladin extends CardImpl {
+
+ public VantressPaladin(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Adamant — If at least three blue mana was spent to cast this spell, Vantress Paladin enters the battlefield with an additional +1/+1 counter on it.
+ this.addAbility(new EntersBattlefieldAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
+ AdamantCondition.BLUE, "
Adamant — " +
+ "If at least three blue mana was spent to cast this spell, " +
+ "{this} enters the battlefield with a +1/+1 counter on it.", ""
+ ), new ManaSpentToCastWatcher());
+ }
+
+ private VantressPaladin(final VantressPaladin card) {
+ super(card);
+ }
+
+ @Override
+ public VantressPaladin copy() {
+ return new VantressPaladin(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/v/VenerableKnight.java b/Mage.Sets/src/mage/cards/v/VenerableKnight.java
new file mode 100644
index 00000000000..dc14f248f35
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/v/VenerableKnight.java
@@ -0,0 +1,47 @@
+package mage.cards.v;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.DiesTriggeredAbility;
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class VenerableKnight extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledPermanent(SubType.KNIGHT);
+
+ public VenerableKnight(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(1);
+
+ // When Venerable Knight dies, put a +1/+1 counter on target Knight you control.
+ Ability ability = new DiesTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
+ ability.addTarget(new TargetPermanent(filter));
+ this.addAbility(ability);
+ }
+
+ private VenerableKnight(final VenerableKnight card) {
+ super(card);
+ }
+
+ @Override
+ public VenerableKnight copy() {
+ return new VenerableKnight(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/v/VerdantSuccession.java b/Mage.Sets/src/mage/cards/v/VerdantSuccession.java
index cd0e14e0e45..b537ac5aeb3 100644
--- a/Mage.Sets/src/mage/cards/v/VerdantSuccession.java
+++ b/Mage.Sets/src/mage/cards/v/VerdantSuccession.java
@@ -35,7 +35,7 @@ public final class VerdantSuccession extends CardImpl {
public VerdantSuccession(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}");
- // Whenever a green nontoken creature dies, that creature's controller may search their library for a card with the same name as that creature and put it onto the battlefield. If that player does, he or she shuffles their library.
+ // Whenever a green nontoken creature dies, that creature's controller may search their library for a card with the same name as that creature and put it onto the battlefield. If that player does, they shuffle their library.
this.addAbility(new VerdantSuccessionTriggeredAbility());
}
@@ -95,7 +95,7 @@ class VerdantSuccessionTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
- return "Whenever a green nontoken creature dies, that creature's controller may search their library for a card with the same name as that creature and put it onto the battlefield. If that player does, he or she shuffles their library.";
+ return "Whenever a green nontoken creature dies, that creature's controller may search their library for a card with the same name as that creature and put it onto the battlefield. If that player does, they shuffle their library.";
}
}
diff --git a/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java b/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java
index e7723d4f9ff..234266a6fa7 100644
--- a/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java
+++ b/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java
@@ -1,4 +1,3 @@
-
package mage.cards.v;
import mage.MageInt;
@@ -77,8 +76,6 @@ class VesuvanShapeShifterFaceUpApplier extends ApplyToPermanent {
Effect effect = new VesuvanShapeshifterFaceDownEffect();
Ability ability = new BeginningOfUpkeepTriggeredAbility(effect, TargetController.YOU, true);
permanent.getAbilities().add(ability);
- // Why is this needed?
- permanent.addAbility(new MorphAbility(permanent, new ManaCostsImpl("{1}{U}")), permanent.getId(), game);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/v/VexingArcanix.java b/Mage.Sets/src/mage/cards/v/VexingArcanix.java
index 61ec7710087..91e1525a0d7 100644
--- a/Mage.Sets/src/mage/cards/v/VexingArcanix.java
+++ b/Mage.Sets/src/mage/cards/v/VexingArcanix.java
@@ -28,7 +28,7 @@ public final class VexingArcanix extends CardImpl {
public VexingArcanix(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
- // {3}, {tap}: Target player chooses a card name, then reveals the top card of their library. If that card has the chosen name, the player puts it into their hand. Otherwise, the player puts it into their graveyard and Vexing Arcanix deals 2 damage to him or her.
+ // {3}, {tap}: Target player chooses a card name, then reveals the top card of their library. If that card has the chosen name, the player puts it into their hand. Otherwise, the player puts it into their graveyard and Vexing Arcanix deals 2 damage to them.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new VexingArcanixEffect(), new GenericManaCost(3));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetPlayer());
@@ -50,7 +50,7 @@ class VexingArcanixEffect extends OneShotEffect {
public VexingArcanixEffect() {
super(Outcome.DrawCard);
- staticText = "Target player chooses a card name, then reveals the top card of their library. If that card has the chosen name, the player puts it into their hand. Otherwise, the player puts it into their graveyard and {this} deals 2 damage to him or her";
+ staticText = "Target player chooses a card name, then reveals the top card of their library. If that card has the chosen name, the player puts it into their hand. Otherwise, the player puts it into their graveyard and {this} deals 2 damage to them";
}
public VexingArcanixEffect(final VexingArcanixEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/v/VexingDevil.java b/Mage.Sets/src/mage/cards/v/VexingDevil.java
index 28bfa4863b4..2c783d130d9 100644
--- a/Mage.Sets/src/mage/cards/v/VexingDevil.java
+++ b/Mage.Sets/src/mage/cards/v/VexingDevil.java
@@ -29,7 +29,7 @@ public final class VexingDevil extends CardImpl {
this.power = new MageInt(4);
this.toughness = new MageInt(3);
- // When Vexing Devil enters the battlefield, any opponent may have it deal 4 damage to him or her. If a player does, sacrifice Vexing Devil.
+ // When Vexing Devil enters the battlefield, any opponent may have it deal 4 damage to them. If a player does, sacrifice Vexing Devil.
this.addAbility(new EntersBattlefieldTriggeredAbility(new VexingDevilEffect(), false));
}
@@ -47,7 +47,7 @@ class VexingDevilEffect extends OneShotEffect {
public VexingDevilEffect() {
super(Outcome.Neutral);
- staticText = "any opponent may have it deal 4 damage to him or her. If a player does, sacrifice {this}";
+ staticText = "any opponent may have it deal 4 damage to them. If a player does, sacrifice {this}";
}
VexingDevilEffect(final VexingDevilEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/v/VictorysEnvoy.java b/Mage.Sets/src/mage/cards/v/VictorysEnvoy.java
new file mode 100644
index 00000000000..e7ef5946adb
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/v/VictorysEnvoy.java
@@ -0,0 +1,53 @@
+package mage.cards.v;
+
+import mage.MageInt;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.effects.common.counter.AddCountersAllEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+import mage.counters.CounterType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.permanent.AnotherPredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class VictorysEnvoy extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterControlledCreaturePermanent("other creature you control");
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ }
+
+ public VictorysEnvoy(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.CLERIC);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // At the beginning of your upkeep, put a +1/1 counter on each other creature you control.
+ this.addAbility(new BeginningOfUpkeepTriggeredAbility(
+ new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter),
+ TargetController.YOU, false
+ ));
+ }
+
+ private VictorysEnvoy(final VictorysEnvoy card) {
+ super(card);
+ }
+
+ @Override
+ public VictorysEnvoy copy() {
+ return new VictorysEnvoy(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/v/Vigor.java b/Mage.Sets/src/mage/cards/v/Vigor.java
index cf1b6292eb4..10296ede3b1 100644
--- a/Mage.Sets/src/mage/cards/v/Vigor.java
+++ b/Mage.Sets/src/mage/cards/v/Vigor.java
@@ -1,7 +1,5 @@
-
package mage.cards.v;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.PutIntoGraveFromAnywhereSourceTriggeredAbility;
@@ -11,24 +9,23 @@ import mage.abilities.effects.common.ShuffleIntoLibrarySourceEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Duration;
-import mage.constants.Outcome;
-import mage.constants.Zone;
+import mage.constants.*;
import mage.counters.CounterType;
import mage.game.Game;
+import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
+import mage.game.events.PreventDamageEvent;
import mage.game.permanent.Permanent;
+import java.util.UUID;
+
/**
- *
* @author emerald000
*/
public final class Vigor extends CardImpl {
public Vigor(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}{G}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}{G}");
this.subtype.add(SubType.ELEMENTAL);
this.subtype.add(SubType.INCARNATION);
@@ -37,10 +34,10 @@ public final class Vigor extends CardImpl {
// Trample
this.addAbility(TrampleAbility.getInstance());
-
+
// If damage would be dealt to a creature you control other than Vigor, prevent that damage. Put a +1/+1 counter on that creature for each 1 damage prevented this way.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new VigorReplacementEffect()));
-
+
// When Vigor is put into a graveyard from anywhere, shuffle it into its owner's library.
this.addAbility(new PutIntoGraveFromAnywhereSourceTriggeredAbility(new ShuffleIntoLibrarySourceEffect()));
}
@@ -68,7 +65,7 @@ class VigorReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
+ GameEvent preventEvent = new PreventDamageEvent(source.getFirstTarget(), source.getSourceId(), source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int preventedDamage = event.getAmount();
event.setAmount(0);
@@ -81,15 +78,15 @@ class VigorReplacementEffect extends ReplacementEffectImpl {
}
return false;
}
-
+
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGE_CREATURE;
}
-
+
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
- return event.getPlayerId().equals(source.getControllerId())
+ return event.getPlayerId().equals(source.getControllerId())
&& !event.getTargetId().equals(source.getSourceId());
}
diff --git a/Mage.Sets/src/mage/cards/v/VigorMortis.java b/Mage.Sets/src/mage/cards/v/VigorMortis.java
index f783c1815eb..20b1e2bb5b6 100644
--- a/Mage.Sets/src/mage/cards/v/VigorMortis.java
+++ b/Mage.Sets/src/mage/cards/v/VigorMortis.java
@@ -1,4 +1,3 @@
-
package mage.cards.v;
import java.util.UUID;
@@ -14,7 +13,7 @@ import mage.constants.ColoredManaSymbol;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.counters.CounterType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.EntersTheBattlefieldEvent;
import mage.game.events.GameEvent;
@@ -33,8 +32,8 @@ public final class VigorMortis extends CardImpl {
// Return target creature card from your graveyard to the battlefield. If {G} was spent to cast Vigor Mortis, that creature enters the battlefield with an additional +1/+1 counter on it.
this.getSpellAbility().addEffect(new VigorMortisReplacementEffect()); // has to be added before the moving effect
this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect());
- this.getSpellAbility().addEffect(new InfoEffect("If {G} was spent to cast {this}, that creature enters the battlefield with an additional +1/+1 counter on it"));
- this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard()));
+ this.getSpellAbility().addEffect(new InfoEffect("If {G} was spent to cast this spell, that creature enters the battlefield with an additional +1/+1 counter on it"));
+ this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE));
}
diff --git a/Mage.Sets/src/mage/cards/v/VillainousWealth.java b/Mage.Sets/src/mage/cards/v/VillainousWealth.java
index e45e4eded9f..15fc7509744 100644
--- a/Mage.Sets/src/mage/cards/v/VillainousWealth.java
+++ b/Mage.Sets/src/mage/cards/v/VillainousWealth.java
@@ -1,4 +1,3 @@
-
package mage.cards.v;
import java.util.UUID;
@@ -29,7 +28,8 @@ public final class VillainousWealth extends CardImpl {
public VillainousWealth(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}{G}{U}");
- // Target opponent exiles the top X cards of their library. You may cast any number of nonland cards with converted mana cost X or less from among them without paying their mana cost.
+ // Target opponent exiles the top X cards of their library. You may cast any number of nonland cards
+ // with converted mana cost X or less from among them without paying their mana cost.
this.getSpellAbility().addTarget(new TargetOpponent());
this.getSpellAbility().addEffect(new VillainousWealthEffect());
@@ -49,7 +49,9 @@ class VillainousWealthEffect extends OneShotEffect {
public VillainousWealthEffect() {
super(Outcome.PlayForFree);
- this.staticText = "Target opponent exiles the top X cards of their library. You may cast any number of nonland cards with converted mana cost X or less from among them without paying their mana cost";
+ this.staticText = "Target opponent exiles the top X cards of their library. "
+ + "You may cast any number of nonland cards with converted mana cost X "
+ + "or less from among them without paying their mana cost";
}
public VillainousWealthEffect(final VillainousWealthEffect effect) {
@@ -74,7 +76,8 @@ class VillainousWealthEffect extends OneShotEffect {
Cards cardsToExile = new CardsImpl();
cardsToExile.addAll(player.getLibrary().getTopCards(game, source.getManaCostsToPay().getX()));
controller.moveCards(cardsToExile, Zone.EXILED, source, game);
- if (controller.chooseUse(Outcome.PlayForFree, "Cast cards exiled with " + mageObject.getLogName() + " without paying its mana cost?", source, game)) {
+ if (controller.chooseUse(Outcome.PlayForFree, "Cast cards exiled with " + mageObject.getLogName()
+ + " without paying its mana cost?", source, game)) {
OuterLoop:
while (cardsToExile.count(filter, game) > 0) {
if (!controller.canRespond()) {
@@ -82,11 +85,17 @@ class VillainousWealthEffect extends OneShotEffect {
}
TargetCardInExile target = new TargetCardInExile(0, 1, filter, exileId, false);
target.setNotTarget(true);
- while (cardsToExile.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, cardsToExile, target, game)) {
+ while (cardsToExile.count(filter, game) > 0
+ && controller.choose(Outcome.PlayForFree, cardsToExile, target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
- cardsToExile.remove(card);
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
+ if (cardWasCast) {
+ cardsToExile.remove(card);
+ }
} else {
break OuterLoop;
}
diff --git a/Mage.Sets/src/mage/cards/v/ViridianClaw.java b/Mage.Sets/src/mage/cards/v/ViridianClaw.java
index a704198b649..45ec4186338 100644
--- a/Mage.Sets/src/mage/cards/v/ViridianClaw.java
+++ b/Mage.Sets/src/mage/cards/v/ViridianClaw.java
@@ -3,6 +3,8 @@
package mage.cards.v;
import java.util.UUID;
+
+import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
@@ -26,9 +28,16 @@ public final class ViridianClaw extends CardImpl {
public ViridianClaw (UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
this.subtype.add(SubType.EQUIPMENT);
+
+ // Equipped creature gets +1/+0 and has first strike.
+ Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(1, 0));
+ ability.addEffect(new GainAbilityAttachedEffect(
+ FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT).setText("and has first strike")
+ );
+ this.addAbility(ability);
+
+ // Equip {1}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(1)));
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 0)));
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT)));
}
public ViridianClaw (final ViridianClaw card) {
diff --git a/Mage.Sets/src/mage/cards/v/VivienArkbowRanger.java b/Mage.Sets/src/mage/cards/v/VivienArkbowRanger.java
index 29d488866d8..b6f7107c145 100644
--- a/Mage.Sets/src/mage/cards/v/VivienArkbowRanger.java
+++ b/Mage.Sets/src/mage/cards/v/VivienArkbowRanger.java
@@ -21,6 +21,10 @@ import mage.target.common.TargetCreatureOrPlaneswalker;
import mage.target.common.TargetCreaturePermanentAmount;
import java.util.UUID;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.game.Game;
+import mage.target.common.TargetCreaturePermanent;
+import mage.target.targetadjustment.TargetAdjuster;
/**
* @author TheElk801
@@ -36,19 +40,19 @@ public final class VivienArkbowRanger extends CardImpl {
// +1: Distribute two +1/+1 counters among up to two target creatures. They gain trample until end of turn.
Ability ability = new LoyaltyAbility(new DistributeCountersEffect(
- CounterType.P1P1, 2, false, "up to two target creatures"
- ), 1);
+ CounterType.P1P1, 2, false, "up to two target creatures"), 1);
ability.addEffect(new GainAbilityTargetEffect(
TrampleAbility.getInstance(), Duration.EndOfTurn,
"They gain trample until end of turn"
));
- ability.addTarget(new TargetCreaturePermanentAmount(2));
+ ability.addTarget(new TargetCreaturePermanent(0, 2, new FilterCreaturePermanent(), false));
+ ability.setTargetAdjuster(VivienArkbowRangerAdjuster.instance);
this.addAbility(ability);
// −3: Target creature you control deals damage equal to its power to target creature or planeswalker.
ability = new LoyaltyAbility(
- new DamageWithPowerTargetEffect().setText("Target creature you control deals damage " +
- "equal to its power to target creature or planeswalker."), -3
+ new DamageWithPowerTargetEffect().setText("Target creature you control deals damage "
+ + "equal to its power to target creature or planeswalker."), -3
);
ability.addTarget(new TargetControlledCreaturePermanent());
ability.addTarget(new TargetCreatureOrPlaneswalker());
@@ -66,4 +70,17 @@ public final class VivienArkbowRanger extends CardImpl {
public VivienArkbowRanger copy() {
return new VivienArkbowRanger(this);
}
+
+ enum VivienArkbowRangerAdjuster implements TargetAdjuster {
+ instance;
+
+ @Override
+ public void adjustTargets(Ability ability, Game game) {
+ // if targets are available, switch over to a working target method
+ if (game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), game).size() > 0) {
+ ability.getTargets().clear();
+ ability.addTarget(new TargetCreaturePermanentAmount(2));
+ }
+ }
+ }
}
diff --git a/Mage.Sets/src/mage/cards/v/ViviensArkbow.java b/Mage.Sets/src/mage/cards/v/ViviensArkbow.java
index 0db7847a761..82b58143471 100644
--- a/Mage.Sets/src/mage/cards/v/ViviensArkbow.java
+++ b/Mage.Sets/src/mage/cards/v/ViviensArkbow.java
@@ -50,7 +50,7 @@ public final class ViviensArkbow extends CardImpl {
class ViviensArkbowEffect extends OneShotEffect {
ViviensArkbowEffect() {
- super(Outcome.Benefit);
+ super(Outcome.PutCardInPlay);
staticText = "Look at the top X cards of your library. " +
"You may put a creature card with converted mana cost X or less " +
"from among them onto the battlefield. Put the rest on the bottom of your library in a random order.";
diff --git a/Mage.Sets/src/mage/cards/v/ViviensInvocation.java b/Mage.Sets/src/mage/cards/v/ViviensInvocation.java
index 7eacc7e747e..23d46f0a18d 100644
--- a/Mage.Sets/src/mage/cards/v/ViviensInvocation.java
+++ b/Mage.Sets/src/mage/cards/v/ViviensInvocation.java
@@ -73,6 +73,7 @@ class ViviensInvocationEffect extends OneShotEffect {
Zone.LIBRARY,
new FilterCreatureCard("creature card to put on the battlefield")
);
+ target.setNotTarget(true);
if (controller.choose(Outcome.PutCreatureInPlay, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java b/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java
index a51a1e68b5b..8583afb86c3 100644
--- a/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java
+++ b/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java
@@ -1,4 +1,3 @@
-
package mage.cards.v;
import mage.MageInt;
@@ -15,6 +14,7 @@ import mage.constants.*;
import mage.game.Game;
import mage.players.ManaPoolItem;
import mage.players.Player;
+import mage.util.CardUtil;
import java.util.UUID;
@@ -83,12 +83,10 @@ class VizierOfTheMenagerieTopCardCastEffect extends AsThoughEffectImpl {
MageObject vizierOfTheMenagerie = game.getObject(source.getSourceId());
if (vizierOfTheMenagerie != null
&& topCard != null) {
- if (topCard == card
+ return topCard == card
&& topCard.isCreature()
&& topCard.getSpellAbility() != null
- && topCard.getSpellAbility().spellCanBeActivatedRegularlyNow(controller.getId(), game)) {
- return true;
- }
+ && topCard.getSpellAbility().spellCanBeActivatedRegularlyNow(controller.getId(), game);
}
}
}
@@ -120,10 +118,10 @@ class VizierOfTheMenagerieManaEffect extends AsThoughEffectImpl implements AsTho
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
+ objectId = CardUtil.getMainCardId(game, objectId); // for split cards
if (source.isControlledBy(affectedControllerId)) {
MageObject mageObject = game.getObject(objectId);
- return mageObject != null
- && mageObject.isCreature();
+ return mageObject != null && mageObject.isCreature();
}
return false;
}
diff --git a/Mage.Sets/src/mage/cards/v/VolrathTheFallen.java b/Mage.Sets/src/mage/cards/v/VolrathTheFallen.java
index d7344404e4a..38281873064 100644
--- a/Mage.Sets/src/mage/cards/v/VolrathTheFallen.java
+++ b/Mage.Sets/src/mage/cards/v/VolrathTheFallen.java
@@ -1,4 +1,3 @@
-
package mage.cards.v;
import java.util.UUID;
@@ -13,11 +12,11 @@ import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Duration;
+import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -26,22 +25,22 @@ import mage.filter.common.FilterCreatureCard;
public final class VolrathTheFallen extends CardImpl {
public VolrathTheFallen(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}{B}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.SHAPESHIFTER);
this.power = new MageInt(6);
this.toughness = new MageInt(4);
- // {1}{B}, Discard a creature card:
+ // {1}{B}, Discard a creature card:
// Volrath the Fallen gets +X/+X until end of turn, where X is the discarded card's converted mana cost.
- Effect effect = new BoostSourceEffect(DiscardCostCardConvertedMana.instance,DiscardCostCardConvertedMana.instance,Duration.EndOfTurn);
+ Effect effect = new BoostSourceEffect(DiscardCostCardConvertedMana.instance, DiscardCostCardConvertedMana.instance, Duration.EndOfTurn);
effect.setText("{this} gets +X/+X until end of turn, where X is the discarded card's converted mana cost");
-
+
Ability ability = new SimpleActivatedAbility(
- Zone.BATTLEFIELD,
+ Zone.BATTLEFIELD,
effect,
new ManaCostsImpl("{1}{B}"));
- ability.addCost(new DiscardCardCost(new FilterCreatureCard()));
+ ability.addCost(new DiscardCardCost(StaticFilters.FILTER_CARD_CREATURE));
this.addAbility(ability);
}
@@ -53,4 +52,4 @@ public final class VolrathTheFallen extends CardImpl {
public VolrathTheFallen copy() {
return new VolrathTheFallen(this);
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/v/VolrathTheShapestealer.java b/Mage.Sets/src/mage/cards/v/VolrathTheShapestealer.java
index 736144713de..880e9a64bc5 100644
--- a/Mage.Sets/src/mage/cards/v/VolrathTheShapestealer.java
+++ b/Mage.Sets/src/mage/cards/v/VolrathTheShapestealer.java
@@ -48,7 +48,7 @@ public final class VolrathTheShapestealer extends CardImpl {
// At the beginning of combat on your turn, put a -1/-1 counter on up to one target creature.
Ability ability = new BeginningOfCombatTriggeredAbility(
- new AddCountersTargetEffect(CounterType.M1M1.createInstance()), TargetController.YOU, false
+ new AddCountersTargetEffect(CounterType.M1M1.createInstance(), Outcome.Detriment), TargetController.YOU, false
);
ability.addTarget(new TargetCreaturePermanent(0, 1));
this.addAbility(ability);
@@ -73,8 +73,8 @@ class VolrathTheShapestealerEffect extends OneShotEffect {
VolrathTheShapestealerEffect() {
super(Outcome.Copy);
- staticText = "Until your next turn, {this} becomes a copy of target creature with a counter on it, " +
- "except it's 7/5 and it has this ability.";
+ staticText = "Until your next turn, {this} becomes a copy of target creature with a counter on it, "
+ + "except it's 7/5 and it has this ability.";
}
private VolrathTheShapestealerEffect(final VolrathTheShapestealerEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/v/VonasHunger.java b/Mage.Sets/src/mage/cards/v/VonasHunger.java
index ce015602733..b9044e81006 100644
--- a/Mage.Sets/src/mage/cards/v/VonasHunger.java
+++ b/Mage.Sets/src/mage/cards/v/VonasHunger.java
@@ -41,11 +41,11 @@ public final class VonasHunger extends CardImpl {
new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT_A_CREATURE),
new InvertCondition(CitysBlessingCondition.instance),
"Each opponent sacrifices a creature"));
- // If you have the city's blessing, instead each opponent sacrifices half the creatures he or she controls rounded up.
+ // If you have the city's blessing, instead each opponent sacrifices half the creatures they control rounded up.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new VonasHungerEffect(),
CitysBlessingCondition.instance,
- "If you have the city's blessing, instead each opponent sacrifices half the creatures he or she controls rounded up"));
+ "If you have the city's blessing, instead each opponent sacrifices half the creatures they control rounded up"));
}
public VonasHunger(final VonasHunger card) {
diff --git a/Mage.Sets/src/mage/cards/w/WaitingInTheWeeds.java b/Mage.Sets/src/mage/cards/w/WaitingInTheWeeds.java
index fe4bc242943..ed0ee62fc1e 100644
--- a/Mage.Sets/src/mage/cards/w/WaitingInTheWeeds.java
+++ b/Mage.Sets/src/mage/cards/w/WaitingInTheWeeds.java
@@ -28,7 +28,7 @@ public final class WaitingInTheWeeds extends CardImpl {
public WaitingInTheWeeds(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}{G}");
- // Each player creates a 1/1 green Cat creature token for each untapped Forest he or she controls.
+ // Each player creates a 1/1 green Cat creature token for each untapped Forest they control.
this.getSpellAbility().addEffect(new WaitingInTheWeedsEffect());
}
@@ -44,7 +44,7 @@ public final class WaitingInTheWeeds extends CardImpl {
class WaitingInTheWeedsEffect extends OneShotEffect {
- private static final FilterPermanent filter = new FilterPermanent("untapped Forest he or she controls");
+ private static final FilterPermanent filter = new FilterPermanent("untapped Forest they control");
static {
filter.add(new SubtypePredicate(SubType.FOREST));
@@ -53,7 +53,7 @@ class WaitingInTheWeedsEffect extends OneShotEffect {
public WaitingInTheWeedsEffect() {
super(Outcome.PutCreatureInPlay);
- staticText = "Each player creates a 1/1 green Cat creature token for each untapped Forest he or she controls";
+ staticText = "Each player creates a 1/1 green Cat creature token for each untapped Forest they control";
}
public WaitingInTheWeedsEffect(final WaitingInTheWeedsEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/w/WallOfResistance.java b/Mage.Sets/src/mage/cards/w/WallOfResistance.java
new file mode 100644
index 00000000000..06099d7b1d9
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WallOfResistance.java
@@ -0,0 +1,59 @@
+package mage.cards.w;
+
+import mage.MageInt;
+import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.SourceDealtDamageCondition;
+import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.keyword.DefenderAbility;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+import mage.counters.CounterType;
+import mage.watchers.common.DamageDoneWatcher;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WallOfResistance extends CardImpl {
+
+ private static final Condition condition = new SourceDealtDamageCondition(1);
+
+ public WallOfResistance(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
+
+ this.subtype.add(SubType.WALL);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(3);
+
+ // Defender
+ this.addAbility(DefenderAbility.getInstance());
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // At the beginning of each end step, if Wall of Resistance was dealt damage this turn, put a +0/+1 counter on it.
+ this.addAbility(new ConditionalInterveningIfTriggeredAbility(
+ new BeginningOfEndStepTriggeredAbility(
+ new AddCountersSourceEffect(CounterType.P0P1.createInstance()),
+ TargetController.ANY, false
+ ), condition, "At the beginning of each end step, " +
+ "if {this} was dealt damage this turn, put a +0/+1 counter on it."
+ ), new DamageDoneWatcher());
+ }
+
+ private WallOfResistance(final WallOfResistance card) {
+ super(card);
+ }
+
+ @Override
+ public WallOfResistance copy() {
+ return new WallOfResistance(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WallOfStolenIdentity.java b/Mage.Sets/src/mage/cards/w/WallOfStolenIdentity.java
new file mode 100644
index 00000000000..842336238cf
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WallOfStolenIdentity.java
@@ -0,0 +1,166 @@
+package mage.cards.w;
+
+import mage.MageInt;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.keyword.DefenderAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.TargetPermanent;
+import mage.util.functions.ApplyToPermanent;
+import java.util.UUID;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.decorator.ConditionalContinuousEffect;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.ContinuousRuleModifyingEffect;
+import mage.abilities.effects.EntersBattlefieldEffect;
+import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.target.Target;
+import mage.target.targetpointer.FixedTarget;
+
+/**
+ * @author TheElk801
+ */
+public final class WallOfStolenIdentity extends CardImpl {
+
+ final static private String rule = "You may have Wall of Stolen Identity enter the battlefield as a copy of any "
+ + "creature on the battlefield, except it's a wall in addition to its other types and it has defender. "
+ + "When you do, tap the copied creature and it doesn't untap during its "
+ + "controller's untap step for as long as you control {this}";
+
+ public WallOfStolenIdentity(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
+
+ this.subtype.add(SubType.SHAPESHIFTER);
+ this.subtype.add(SubType.WALL);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(0);
+
+ // You may have Wall of Stolen Identity enter the battlefield as a copy of any creature on the battlefield, except it's a wall in addition to its other types and it has defender. When you do, tap the copied creature and it doesn't untap during its controller's untap step for as long as you control Wall of Stolen Identity.
+ Ability ability = new SimpleStaticAbility(
+ Zone.BATTLEFIELD,
+ new EntersBattlefieldEffect(
+ new WallOfStolenIdentityCopyEffect(),
+ rule,
+ true));
+ this.addAbility(ability);
+ }
+
+ private WallOfStolenIdentity(final WallOfStolenIdentity card) {
+ super(card);
+ }
+
+ @Override
+ public WallOfStolenIdentity copy() {
+ return new WallOfStolenIdentity(this);
+ }
+}
+
+class WallOfStolenIdentityCopyEffect extends OneShotEffect {
+
+ private static final String rule2 = "When you do, tap the copied creature and it doesn't untap during its "
+ + "controller's untap step for as long as you control {this}.";
+
+ public WallOfStolenIdentityCopyEffect() {
+ super(Outcome.Copy);
+ staticText = rule2;
+ }
+
+ public WallOfStolenIdentityCopyEffect(final WallOfStolenIdentityCopyEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Permanent permanent = game.getPermanent(source.getSourceId());
+ if (permanent == null) {
+ permanent = game.getPermanentEntering(source.getSourceId());
+ }
+ final Permanent sourcePermanent = permanent;
+ if (controller != null
+ && sourcePermanent != null) {
+ Target target = new TargetPermanent(new FilterCreaturePermanent("target creature (you copy from)"));
+ target.setRequired(true);
+ if (source instanceof SimpleStaticAbility) {
+ target = new TargetPermanent(new FilterCreaturePermanent("creature (you copy from)"));
+ target.setRequired(false);
+ target.setNotTarget(true);
+ }
+ if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
+ controller.choose(Outcome.Copy, target, source.getSourceId(), game);
+ Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget());
+ if (copyFromPermanent != null) {
+ game.copyPermanent(copyFromPermanent, sourcePermanent.getId(), source, new ApplyToPermanent() {
+ @Override
+ public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) {
+ permanent.getSubtype(game).add(SubType.WALL);
+ permanent.getAbilities().add(DefenderAbility.getInstance());
+ return true;
+ }
+
+ @Override
+ public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
+ mageObject.getSubtype(game).add(SubType.WALL);
+ mageObject.getAbilities().add(DefenderAbility.getInstance());
+ return true;
+ }
+
+ });
+
+ copyFromPermanent.tap(game);
+ // Incredibly, you can't just add a fixed target to a continuousrulemodifyingeffect, thus the workaround.
+ ContinuousRuleModifyingEffect effect = new DontUntapInControllersUntapStepSourceEffect();
+ Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
+ ContinuousEffect effect2 = new GainAbilityTargetEffect(ability, Duration.Custom);
+ ConditionalContinuousEffect conditionalEffect = new ConditionalContinuousEffect(
+ effect2, new WallOfStolenIdentityCondition(
+ source,
+ source.getControllerId(),
+ sourcePermanent.getZoneChangeCounter(game)), "");
+ conditionalEffect.setTargetPointer(new FixedTarget(target.getFirstTarget()));
+ game.addEffect(conditionalEffect, source);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public WallOfStolenIdentityCopyEffect copy() {
+ return new WallOfStolenIdentityCopyEffect(this);
+ }
+}
+
+class WallOfStolenIdentityCondition implements Condition {
+
+ // Checks for when it leaves play or changes control
+ private final Ability ability;
+ private final UUID controllerId;
+ private final int zcc;
+
+ public WallOfStolenIdentityCondition(Ability ability, UUID controllerId, int zcc) {
+ this.ability = ability;
+ this.controllerId = controllerId;
+ this.zcc = zcc;
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanentSource = game.getPermanent(ability.getSourceId());
+ if (permanentSource != null) {
+ return permanentSource.getZoneChangeCounter(game) == zcc + 1
+ && permanentSource.getControllerId() == controllerId;
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WandOfIth.java b/Mage.Sets/src/mage/cards/w/WandOfIth.java
index e4f953ed0bb..bbd4a2d1195 100644
--- a/Mage.Sets/src/mage/cards/w/WandOfIth.java
+++ b/Mage.Sets/src/mage/cards/w/WandOfIth.java
@@ -31,7 +31,7 @@ public final class WandOfIth extends CardImpl {
public WandOfIth(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
- // {3}, {T}: Target player reveals a card at random from their hand. If it's a land card, that player discards it unless he or she pays 1 life. If it isn't a land card, the player discards it unless he or she pays life equal to its converted mana cost. Activate this ability only during your turn.
+ // {3}, {T}: Target player reveals a card at random from their hand. If it's a land card, that player discards it unless they pay 1 life. If it isn't a land card, the player discards it unless they pay life equal to its converted mana cost. Activate this ability only during your turn.
Ability ability = new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, new WandOfIthEffect(), new GenericManaCost(3), MyTurnCondition.instance);
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetPlayer());
@@ -52,7 +52,7 @@ class WandOfIthEffect extends OneShotEffect {
public WandOfIthEffect() {
super(Outcome.Discard);
- staticText = "Target player reveals a card at random from their hand. If it's a land card, that player discards it unless he or she pays 1 life. If it isn't a land card, the player discards it unless he or she pays life equal to its converted mana cost";
+ staticText = "Target player reveals a card at random from their hand. If it's a land card, that player discards it unless they pay 1 life. If it isn't a land card, the player discards it unless they pay life equal to its converted mana cost";
}
public WandOfIthEffect(final WandOfIthEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/w/Wandermare.java b/Mage.Sets/src/mage/cards/w/Wandermare.java
new file mode 100644
index 00000000000..1b6e77b3173
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/Wandermare.java
@@ -0,0 +1,50 @@
+package mage.cards.w;
+
+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.FilterSpell;
+import mage.filter.common.FilterCreatureSpell;
+import mage.filter.predicate.mageobject.AdventurePredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class Wandermare extends CardImpl {
+
+ private static final FilterSpell filter
+ = new FilterCreatureSpell("a creature spell that has an Adventure");
+
+ static {
+ filter.add(AdventurePredicate.instance);
+ }
+
+ public Wandermare(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{W}");
+
+ this.subtype.add(SubType.HORSE);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Whenever you cast a creature spell that has an Adventure, put a +1/+1 counter on Wandermare.
+ this.addAbility(new SpellCastControllerTriggeredAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance()), filter, false
+ ));
+ }
+
+ private Wandermare(final Wandermare card) {
+ super(card);
+ }
+
+ @Override
+ public Wandermare copy() {
+ return new Wandermare(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WarCadence.java b/Mage.Sets/src/mage/cards/w/WarCadence.java
index a3864feb41b..703925733f5 100644
--- a/Mage.Sets/src/mage/cards/w/WarCadence.java
+++ b/Mage.Sets/src/mage/cards/w/WarCadence.java
@@ -27,7 +27,7 @@ public final class WarCadence extends CardImpl {
public WarCadence(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
- // {X}{R}: This turn, creatures can't block unless their controller pays {X} for each blocking creature he or she controls.
+ // {X}{R}: This turn, creatures can't block unless their controller pays {X} for each blocking creature they control.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new WarCadenceReplacementEffect(), new ManaCostsImpl("{X}{R}")));
}
@@ -48,7 +48,7 @@ class WarCadenceReplacementEffect extends ReplacementEffectImpl {
WarCadenceReplacementEffect() {
super(Duration.EndOfTurn, Outcome.Neutral);
- staticText = "This turn, creatures can't block unless their controller pays {X} for each blocking creature he or she controls";
+ staticText = "This turn, creatures can't block unless their controller pays {X} for each blocking creature they control";
}
WarCadenceReplacementEffect(WarCadenceReplacementEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/w/WarTax.java b/Mage.Sets/src/mage/cards/w/WarTax.java
index e9d14ff8221..f7d53672af1 100644
--- a/Mage.Sets/src/mage/cards/w/WarTax.java
+++ b/Mage.Sets/src/mage/cards/w/WarTax.java
@@ -29,7 +29,7 @@ public final class WarTax extends CardImpl {
public WarTax(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
- // {X}{U}: This turn, creatures can't attack unless their controller pays {X} for each attacking creature he or she controls.
+ // {X}{U}: This turn, creatures can't attack unless their controller pays {X} for each attacking creature they control.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new WarTaxCantAttackUnlessPaysEffect(), new ManaCostsImpl("{X}{U}")));
}
@@ -49,7 +49,7 @@ class WarTaxCantAttackUnlessPaysEffect extends PayCostToAttackBlockEffectImpl {
WarTaxCantAttackUnlessPaysEffect() {
super(Duration.EndOfTurn, Outcome.Neutral, RestrictType.ATTACK);
- staticText = "This turn, creatures can't attack unless their controller pays {X} for each attacking creature he or she controls";
+ staticText = "This turn, creatures can't attack unless their controller pays {X} for each attacking creature they control";
}
WarTaxCantAttackUnlessPaysEffect(WarTaxCantAttackUnlessPaysEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/w/WarpWorld.java b/Mage.Sets/src/mage/cards/w/WarpWorld.java
index 221caf4d12b..08be3d71863 100644
--- a/Mage.Sets/src/mage/cards/w/WarpWorld.java
+++ b/Mage.Sets/src/mage/cards/w/WarpWorld.java
@@ -31,7 +31,7 @@ public final class WarpWorld extends CardImpl {
public WarpWorld(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{R}{R}{R}");
- // Each player shuffles all permanents he or she owns into their library, then reveals that many cards from the top of their library. Each player puts all artifact, creature, and land cards revealed this way onto the battlefield, then does the same for enchantment cards, then puts all cards revealed this way that weren't put onto the battlefield on the bottom of their library.
+ // Each player shuffles all permanents they own into their library, then reveals that many cards from the top of their library. Each player puts all artifact, creature, and land cards revealed this way onto the battlefield, then does the same for enchantment cards, then puts all cards revealed this way that weren't put onto the battlefield on the bottom of their library.
this.getSpellAbility().addEffect(new WarpWorldEffect());
}
@@ -49,7 +49,7 @@ class WarpWorldEffect extends OneShotEffect {
public WarpWorldEffect() {
super(Outcome.Neutral);
- this.staticText = "Each player shuffles all permanents he or she owns into their library, then reveals that many cards from the top of their library. Each player puts all artifact, creature, and land cards revealed this way onto the battlefield, then does the same for enchantment cards, then puts all cards revealed this way that weren't put onto the battlefield on the bottom of their library";
+ this.staticText = "Each player shuffles all permanents they own into their library, then reveals that many cards from the top of their library. Each player puts all artifact, creature, and land cards revealed this way onto the battlefield, then does the same for enchantment cards, then puts all cards revealed this way that weren't put onto the battlefield on the bottom of their library";
}
public WarpWorldEffect(final WarpWorldEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/w/WarstormSurge.java b/Mage.Sets/src/mage/cards/w/WarstormSurge.java
index 71475721b2d..747e7ea93bf 100644
--- a/Mage.Sets/src/mage/cards/w/WarstormSurge.java
+++ b/Mage.Sets/src/mage/cards/w/WarstormSurge.java
@@ -1,7 +1,5 @@
-
package mage.cards.w;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
@@ -18,14 +16,15 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetAnyTarget;
+import java.util.UUID;
+
/**
- *
* @author North
*/
public final class WarstormSurge extends CardImpl {
public WarstormSurge(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{5}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{5}{R}");
// Whenever a creature enters the battlefield under your control, it deals damage equal to its power to any target.
Ability ability = new WarstormSurgeTriggeredAbility();
@@ -61,7 +60,8 @@ class WarstormSurgeTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
- if (permanent.isCreature()
+ if (permanent != null
+ && permanent.isCreature()
&& permanent.isControlledBy(this.controllerId)) {
Effect effect = this.getEffects().get(0);
effect.setValue("damageSource", event.getTargetId());
diff --git a/Mage.Sets/src/mage/cards/w/WatcherForTomorrow.java b/Mage.Sets/src/mage/cards/w/WatcherForTomorrow.java
index fed14663f50..a6751c12d3e 100644
--- a/Mage.Sets/src/mage/cards/w/WatcherForTomorrow.java
+++ b/Mage.Sets/src/mage/cards/w/WatcherForTomorrow.java
@@ -19,6 +19,7 @@ import mage.players.Player;
import mage.util.CardUtil;
import java.util.UUID;
+import mage.game.permanent.Permanent;
/**
* @author TheElk801
@@ -72,11 +73,15 @@ class WatcherForTomorrowEffect extends OneShotEffect {
if (player == null) {
return false;
}
- ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source.getSourceId(), true));
+ Permanent permanentLeftBattlefield = (Permanent) getValue("permanentLeftBattlefield");
+ if (permanentLeftBattlefield == null) {
+ return false;
+ }
+ ExileZone zone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), permanentLeftBattlefield.getZoneChangeCounter(game)));
if (zone == null) {
return false;
}
Cards cards = new CardsImpl(zone.getCards(game));
return player.moveCards(cards, Zone.HAND, source, game);
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/w/WaveOfVitriol.java b/Mage.Sets/src/mage/cards/w/WaveOfVitriol.java
index 5b223ec8627..1a566c49e1a 100644
--- a/Mage.Sets/src/mage/cards/w/WaveOfVitriol.java
+++ b/Mage.Sets/src/mage/cards/w/WaveOfVitriol.java
@@ -31,7 +31,7 @@ public final class WaveOfVitriol extends CardImpl {
public WaveOfVitriol(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{G}{G}");
- // Each player sacrifices all artifacts, enchantments, and nonbasic lands he or she controls. For each land sacrificed this way, its controller may search their library for a basic land card and put it onto the battlefield tapped. Then each player who searched their library this way shuffles it.
+ // Each player sacrifices all artifacts, enchantments, and nonbasic lands they control. For each land sacrificed this way, its controller may search their library for a basic land card and put it onto the battlefield tapped. Then each player who searched their library this way shuffles it.
this.getSpellAbility().addEffect(new WaveOfVitriolEffect());
}
@@ -63,7 +63,7 @@ class WaveOfVitriolEffect extends OneShotEffect {
public WaveOfVitriolEffect() {
super(Outcome.Benefit);
- this.staticText = "Each player sacrifices all artifacts, enchantments, and nonbasic lands he or she controls. For each land sacrificed this way, its controller may search their library for a basic land card and put it onto the battlefield tapped. Then each player who searched their library this way shuffles it";
+ this.staticText = "Each player sacrifices all artifacts, enchantments, and nonbasic lands they control. For each land sacrificed this way, its controller may search their library for a basic land card and put it onto the battlefield tapped. Then each player who searched their library this way shuffles it";
}
public WaveOfVitriolEffect(final WaveOfVitriolEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/w/WeaponRack.java b/Mage.Sets/src/mage/cards/w/WeaponRack.java
new file mode 100644
index 00000000000..70066e25511
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WeaponRack.java
@@ -0,0 +1,82 @@
+package mage.cards.w;
+
+import mage.abilities.Ability;
+import mage.abilities.common.ActivateAsSorceryActivatedAbility;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WeaponRack extends CardImpl {
+
+ public WeaponRack(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
+
+ // Weapon Rack enters the battlefield with three +1/+1 counters on it.
+ this.addAbility(new EntersBattlefieldAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)),
+ "{this} enters the battlefield with three +1/+1 counters on it"
+ ));
+
+ // {T}: Move a +1/+1 counter from Weapon Rack onto target creature. Activate this ability only any time you could cast a sorcery.
+ Ability ability = new ActivateAsSorceryActivatedAbility(
+ Zone.BATTLEFIELD, new WeaponRackEffect(), new TapSourceCost()
+ );
+ ability.addTarget(new TargetCreaturePermanent());
+ this.addAbility(ability);
+ }
+
+ private WeaponRack(final WeaponRack card) {
+ super(card);
+ }
+
+ @Override
+ public WeaponRack copy() {
+ return new WeaponRack(this);
+ }
+}
+
+class WeaponRackEffect extends OneShotEffect {
+
+ WeaponRackEffect() {
+ super(Outcome.Benefit);
+ staticText = "move a +1/+1 counter from {this} onto target creature";
+ }
+
+ private WeaponRackEffect(final WeaponRackEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public WeaponRackEffect copy() {
+ return new WeaponRackEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent sourcePermanent = game.getPermanent(source.getSourceId());
+ if (sourcePermanent == null || !sourcePermanent.getCounters(game).containsKey(CounterType.P1P1)) {
+ return false;
+ }
+ Permanent permanent = game.getPermanent(source.getFirstTarget());
+ if (permanent == null || !permanent.addCounters(CounterType.P1P1.createInstance(), source, game)) {
+ return false;
+ }
+ sourcePermanent.removeCounters(CounterType.P1P1.createInstance(), game);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/w/WeaselbackRedcap.java b/Mage.Sets/src/mage/cards/w/WeaselbackRedcap.java
new file mode 100644
index 00000000000..3526c274525
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WeaselbackRedcap.java
@@ -0,0 +1,42 @@
+package mage.cards.w;
+
+import mage.MageInt;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WeaselbackRedcap extends CardImpl {
+
+ public WeaselbackRedcap(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}");
+
+ this.subtype.add(SubType.GOBLIN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // {1}{R}: Weaselback Redcap gets +2/+0 until end of turn.
+ this.addAbility(new SimpleActivatedAbility(
+ new BoostSourceEffect(2, 0, Duration.EndOfTurn), new ManaCostsImpl("{1}{R}")
+ ));
+ }
+
+ private WeaselbackRedcap(final WeaselbackRedcap card) {
+ super(card);
+ }
+
+ @Override
+ public WeaselbackRedcap copy() {
+ return new WeaselbackRedcap(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WebOfInertia.java b/Mage.Sets/src/mage/cards/w/WebOfInertia.java
index edaf46afe00..b8a396e607b 100644
--- a/Mage.Sets/src/mage/cards/w/WebOfInertia.java
+++ b/Mage.Sets/src/mage/cards/w/WebOfInertia.java
@@ -26,7 +26,7 @@ public final class WebOfInertia extends CardImpl {
public WebOfInertia(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
- // At the beginning of combat on each opponent's turn, that player may exile a card from their graveyard. If the player doesn't, creatures he or she controls can't attack you this turn.
+ // At the beginning of combat on each opponent's turn, that player may exile a card from their graveyard. If the player doesn't, creatures they control can't attack you this turn.
this.addAbility(new BeginningOfCombatTriggeredAbility(Zone.BATTLEFIELD, new WebOfInertiaEffect(), TargetController.OPPONENT, false, true));
}
@@ -44,7 +44,7 @@ class WebOfInertiaEffect extends OneShotEffect {
public WebOfInertiaEffect() {
super(Outcome.Detriment);
- staticText = "that player may exile a card from their graveyard. If the player doesn't, creatures he or she controls can't attack you this turn";
+ staticText = "that player may exile a card from their graveyard. If the player doesn't, creatures they control can't attack you this turn";
}
public WebOfInertiaEffect(final WebOfInertiaEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/w/WeiAssassins.java b/Mage.Sets/src/mage/cards/w/WeiAssassins.java
index 48d149aabeb..44f05e4f82f 100644
--- a/Mage.Sets/src/mage/cards/w/WeiAssassins.java
+++ b/Mage.Sets/src/mage/cards/w/WeiAssassins.java
@@ -35,7 +35,7 @@ public final class WeiAssassins extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(2);
- // When Wei Assassins enters the battlefield, target opponent chooses a creature he or she controls. Destroy it.
+ // When Wei Assassins enters the battlefield, target opponent chooses a creature they control. Destroy it.
Ability ability = new EntersBattlefieldTriggeredAbility(new WeiAssassinsEffect(), false);
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
@@ -55,7 +55,7 @@ class WeiAssassinsEffect extends OneShotEffect {
WeiAssassinsEffect() {
super(Outcome.Benefit);
- this.staticText = "target opponent chooses a creature he or she controls. Destroy it.";
+ this.staticText = "target opponent chooses a creature they control. Destroy it.";
}
WeiAssassinsEffect(final WeiAssassinsEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/w/WeirdHarvest.java b/Mage.Sets/src/mage/cards/w/WeirdHarvest.java
index ca1fa3a86f3..3bd2728d72f 100644
--- a/Mage.Sets/src/mage/cards/w/WeirdHarvest.java
+++ b/Mage.Sets/src/mage/cards/w/WeirdHarvest.java
@@ -1,4 +1,3 @@
-
package mage.cards.w;
import java.util.ArrayList;
@@ -14,7 +13,7 @@ import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
@@ -26,7 +25,7 @@ import mage.target.common.TargetCardInLibrary;
public final class WeirdHarvest extends CardImpl {
public WeirdHarvest(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{G}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{G}{G}");
// Each player may search their library for up to X creature cards, reveal those cards, and put them into their hand. Then each player who searched their library this way shuffles it.
getSpellAbility().addEffect(new WeirdHarvestEffect());
@@ -87,7 +86,7 @@ class WeirdHarvestEffect extends OneShotEffect {
private void chooseAndSearchLibrary(List usingPlayers, Player player, int xValue, Ability source, MageObject sourceObject, Game game) {
if (player.chooseUse(Outcome.PutCardInPlay, "Search your library for up " + xValue + " creature cards and put them into your hand?", source, game)) {
usingPlayers.add(player);
- TargetCardInLibrary target = new TargetCardInLibrary(0, xValue, new FilterCreatureCard());
+ TargetCardInLibrary target = new TargetCardInLibrary(0, xValue, StaticFilters.FILTER_CARD_CREATURE);
if (player.searchLibrary(target, source, game)) {
if (!target.getTargets().isEmpty()) {
Cards cards = new CardsImpl(target.getTargets());
diff --git a/Mage.Sets/src/mage/cards/w/Wellspring.java b/Mage.Sets/src/mage/cards/w/Wellspring.java
new file mode 100644
index 00000000000..56173302cc8
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/Wellspring.java
@@ -0,0 +1,90 @@
+package mage.cards.w;
+
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.UntapEnchantedEffect;
+import mage.abilities.effects.common.continuous.GainControlTargetEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetLandPermanent;
+import mage.target.targetpointer.FixedTarget;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class Wellspring extends CardImpl {
+
+ public Wellspring(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}{W}");
+
+ this.subtype.add(SubType.AURA);
+
+ // Enchant land
+ TargetPermanent auraTarget = new TargetLandPermanent();
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // When Wellspring enters the battlefield, gain control of enchanted land until end of turn.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(
+ new WellspringEffect("gain control of enchanted land until end of turn")
+ ));
+
+ // At the beginning of your upkeep, untap enchanted land. You gain control of that land until end of turn.
+ ability = new BeginningOfUpkeepTriggeredAbility(
+ new UntapEnchantedEffect().setText("untap enchanted land."), TargetController.YOU, false
+ );
+ ability.addEffect(new WellspringEffect("You gain control of that land until end of turn"));
+ this.addAbility(ability);
+ }
+
+ private Wellspring(final Wellspring card) {
+ super(card);
+ }
+
+ @Override
+ public Wellspring copy() {
+ return new Wellspring(this);
+ }
+}
+
+class WellspringEffect extends OneShotEffect {
+
+ WellspringEffect(String text) {
+ super(Outcome.Benefit);
+ staticText = text;
+ }
+
+ private WellspringEffect(final WellspringEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public WellspringEffect copy() {
+ return new WellspringEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
+ if (permanent == null) {
+ return false;
+ }
+ ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfTurn);
+ effect.setTargetPointer(new FixedTarget(permanent.getAttachedTo(), game));
+ game.addEffect(effect, source);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/w/WhimsOfTheFates.java b/Mage.Sets/src/mage/cards/w/WhimsOfTheFates.java
index 3f1006ece9d..07ebe8f4516 100644
--- a/Mage.Sets/src/mage/cards/w/WhimsOfTheFates.java
+++ b/Mage.Sets/src/mage/cards/w/WhimsOfTheFates.java
@@ -28,7 +28,7 @@ public final class WhimsOfTheFates extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{R}");
- // Starting with you, each player separates all permanents he or she controls into three piles. Then each player chooses one of their piles at random and sacrifices those permanents.
+ // Starting with you, each player separates all permanents they control into three piles. Then each player chooses one of their piles at random and sacrifices those permanents.
this.getSpellAbility().addEffect(new WhimsOfTheFateEffect());
}
@@ -47,7 +47,7 @@ class WhimsOfTheFateEffect extends OneShotEffect {
public WhimsOfTheFateEffect() {
super(Outcome.Detriment);
- this.staticText = "Starting with you, each player separates all permanents he or she controls into three piles. Then each player chooses one of their piles at random and sacrifices those permanents.";
+ this.staticText = "Starting with you, each player separates all permanents they control into three piles. Then each player chooses one of their piles at random and sacrifices those permanents.";
}
public WhimsOfTheFateEffect(final WhimsOfTheFateEffect effect) {
@@ -86,7 +86,7 @@ class WhimsOfTheFateEffect extends OneShotEffect {
if (!nextPlayer.canRespond()) {
continue;
}
- // if player is in range of controller he chooses 3 piles with all its permanents
+ // if player is in range of controller they choose 3 piles with all their permanents
if (currentPlayer != null && game.getState().getPlayersInRange(controller.getId(), game).contains(currentPlayer.getId())) {
Map> playerPiles = new HashMap<>();
for (int i = 1; i < 4; i++) {
diff --git a/Mage.Sets/src/mage/cards/w/WhisperingSpecter.java b/Mage.Sets/src/mage/cards/w/WhisperingSpecter.java
index 3c4bd09ed9d..732322083b0 100644
--- a/Mage.Sets/src/mage/cards/w/WhisperingSpecter.java
+++ b/Mage.Sets/src/mage/cards/w/WhisperingSpecter.java
@@ -51,7 +51,7 @@ public final class WhisperingSpecter extends CardImpl {
class WhisperingSpecterEffect extends OneShotEffect {
WhisperingSpecterEffect() {
super(Outcome.Discard);
- staticText = "If you do, that player discards a card for each poison counter he or she has";
+ staticText = "If you do, that player discards a card for each poison counter they have";
}
WhisperingSpecterEffect(final WhisperingSpecterEffect effect) {
@@ -64,7 +64,7 @@ class WhisperingSpecterEffect extends OneShotEffect {
if (player != null) {
int value = player.getCounters().getCount(CounterType.POISON);
if (value > 0) {
- player.discard(value, source, game);
+ player.discard(value, false, source, game);
return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/w/WickedGuardian.java b/Mage.Sets/src/mage/cards/w/WickedGuardian.java
new file mode 100644
index 00000000000..23136034fbc
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WickedGuardian.java
@@ -0,0 +1,92 @@
+package mage.cards.w;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+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.filter.FilterPermanent;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WickedGuardian extends CardImpl {
+
+ public WickedGuardian(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.NOBLE);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(2);
+
+ // When Wicked Guardian enters the battlefield, you may have it deal 2 damage to another creature you control. If you do, draw a card.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new WickedGuardianEffect(), true));
+ }
+
+ private WickedGuardian(final WickedGuardian card) {
+ super(card);
+ }
+
+ @Override
+ public WickedGuardian copy() {
+ return new WickedGuardian(this);
+ }
+}
+
+class WickedGuardianEffect extends OneShotEffect {
+
+ private static final FilterPermanent filter
+ = new FilterControlledCreaturePermanent("another creature you control");
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ }
+
+ WickedGuardianEffect() {
+ super(Outcome.Benefit);
+ staticText = "have it deal 2 damage to another creature you control. If you do, draw a card";
+ }
+
+ private WickedGuardianEffect(final WickedGuardianEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public WickedGuardianEffect copy() {
+ return new WickedGuardianEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ if (game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) == 0) {
+ return false;
+ }
+ TargetPermanent target = new TargetPermanent(0, 1, filter, true);
+ if (!player.choose(outcome, target, source.getSourceId(), game)) {
+ return false;
+ }
+ Permanent permanent = game.getPermanent(target.getFirstTarget());
+ if (permanent == null) {
+ return false;
+ }
+ permanent.damage(2, source.getSourceId(), game);
+ return player.drawCards(1, game) > 0;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/w/WickedWolf.java b/Mage.Sets/src/mage/cards/w/WickedWolf.java
new file mode 100644
index 00000000000..3888da8973c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WickedWolf.java
@@ -0,0 +1,77 @@
+package mage.cards.w;
+
+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.effects.common.FightTargetSourceEffect;
+import mage.abilities.effects.common.TapSourceEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.keyword.IndestructibleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+import mage.counters.CounterType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WickedWolf extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterCreaturePermanent("creature you don't control");
+ private static final FilterControlledPermanent filter2
+ = new FilterControlledPermanent(SubType.FOOD, "a Food");
+
+ static {
+ filter.add(new ControllerPredicate(TargetController.NOT_YOU));
+ }
+
+ public WickedWolf(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}");
+
+ this.subtype.add(SubType.WOLF);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // When Wicked Wolf enters the battlefield, it fights up to one target creature you don't control.
+ Ability ability = new EntersBattlefieldTriggeredAbility(
+ new FightTargetSourceEffect().setText("it fights up to one target creature you don't control")
+ );
+ ability.addTarget(new TargetPermanent(0, 1, filter, false));
+ this.addAbility(ability);
+
+ // Sacrifice a Food: Put a +1/+1 counter on Wicked Wolf. It gains indestructible until end of turn. Tap it.
+ ability = new SimpleActivatedAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
+ new SacrificeTargetCost(new TargetControlledPermanent(filter2))
+ );
+ ability.addEffect(new GainAbilitySourceEffect(
+ IndestructibleAbility.getInstance(), Duration.EndOfTurn
+ ).setText("it gains indestructible until end of turn."));
+ ability.addEffect(new TapSourceEffect().setText("Tap it"));
+ this.addAbility(ability);
+ }
+
+ private WickedWolf(final WickedWolf card) {
+ super(card);
+ }
+
+ @Override
+ public WickedWolf copy() {
+ return new WickedWolf(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WildGuess.java b/Mage.Sets/src/mage/cards/w/WildGuess.java
index bd0a53e3922..d70767cd396 100644
--- a/Mage.Sets/src/mage/cards/w/WildGuess.java
+++ b/Mage.Sets/src/mage/cards/w/WildGuess.java
@@ -1,31 +1,28 @@
-
package mage.cards.w;
-import java.util.UUID;
-import mage.abilities.costs.common.DiscardTargetCost;
+import mage.abilities.costs.common.DiscardCardCost;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.target.common.TargetCardInHand;
+
+import java.util.UUID;
/**
- *
* @author North
*/
public final class WildGuess extends CardImpl {
public WildGuess(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{R}{R}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}{R}");
// As an additional cost to cast Wild Guess, discard a card.
- this.getSpellAbility().addCost(new DiscardTargetCost(new TargetCardInHand()));
+ this.getSpellAbility().addCost(new DiscardCardCost());
// Draw two cards.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2));
}
- public WildGuess(final WildGuess card) {
+ private WildGuess(final WildGuess card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/w/WildbornPreserver.java b/Mage.Sets/src/mage/cards/w/WildbornPreserver.java
new file mode 100644
index 00000000000..b6429ccdda5
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WildbornPreserver.java
@@ -0,0 +1,141 @@
+package mage.cards.w;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.DelayedTriggeredAbility;
+import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.costs.mana.ManaCosts;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.keyword.FlashAbility;
+import mage.abilities.keyword.ReachAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.counters.CounterType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WildbornPreserver extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterCreaturePermanent("another non-Human creature");
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ filter.add(Predicates.not(new SubtypePredicate(SubType.HUMAN)));
+ }
+
+ public WildbornPreserver(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
+
+ this.subtype.add(SubType.ELF);
+ this.subtype.add(SubType.ARCHER);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Flash
+ this.addAbility(FlashAbility.getInstance());
+
+ // Reach
+ this.addAbility(ReachAbility.getInstance());
+
+ // Whenever another non-Human creature enters the battlefield under your control, you may pay {X}. When you do, put X +1/+1 counters on Wildborn Preserver.
+ this.addAbility(new EntersBattlefieldControlledTriggeredAbility(
+ new WildbornPreserverCreateReflexiveTriggerEffect(), filter
+ ));
+ }
+
+ private WildbornPreserver(final WildbornPreserver card) {
+ super(card);
+ }
+
+ @Override
+ public WildbornPreserver copy() {
+ return new WildbornPreserver(this);
+ }
+}
+
+class WildbornPreserverCreateReflexiveTriggerEffect extends OneShotEffect {
+
+ WildbornPreserverCreateReflexiveTriggerEffect() {
+ super(Outcome.Benefit);
+ }
+
+ private WildbornPreserverCreateReflexiveTriggerEffect(final WildbornPreserverCreateReflexiveTriggerEffect effect) {
+ super(effect);
+ staticText = "you may pay {X}. When you do, put X +1/+1 counters on {this}";
+ }
+
+ @Override
+ public WildbornPreserverCreateReflexiveTriggerEffect copy() {
+ return new WildbornPreserverCreateReflexiveTriggerEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ ManaCosts cost = new ManaCostsImpl("{X}");
+ if (player == null) {
+ return false;
+ }
+ if (!player.chooseUse(outcome, "Pay " + cost.getText() + "?", source, game)) {
+ return false;
+ }
+ int costX = player.announceXMana(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source);
+ cost.add(new GenericManaCost(costX));
+ if (!cost.pay(source, game, source.getSourceId(), source.getControllerId(), false, null)) {
+ return false;
+ }
+ game.addDelayedTriggeredAbility(new WildbornPreserverReflexiveTriggeredAbility(costX), source);
+ game.fireEvent(GameEvent.getEvent(GameEvent.EventType.OPTION_USED, source.getOriginalId(), source.getSourceId(), source.getControllerId(), 0));
+ return true;
+ }
+}
+
+class WildbornPreserverReflexiveTriggeredAbility extends DelayedTriggeredAbility {
+
+ WildbornPreserverReflexiveTriggeredAbility(int counters) {
+ super(new AddCountersSourceEffect(CounterType.P1P1.createInstance(counters)), Duration.OneUse, true);
+ }
+
+ private WildbornPreserverReflexiveTriggeredAbility(final WildbornPreserverReflexiveTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public WildbornPreserverReflexiveTriggeredAbility copy() {
+ return new WildbornPreserverReflexiveTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.OPTION_USED;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ return event.getPlayerId().equals(this.getControllerId())
+ && event.getSourceId().equals(this.getSourceId());
+ }
+
+ @Override
+ public String getRule() {
+ return "When you do, put X +1/+1 counters on {this}.";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WildfireDevils.java b/Mage.Sets/src/mage/cards/w/WildfireDevils.java
new file mode 100644
index 00000000000..61c3c3719dc
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WildfireDevils.java
@@ -0,0 +1,115 @@
+package mage.cards.w;
+
+import mage.MageInt;
+import mage.MageObjectReference;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.meta.OrTriggeredAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.players.Player;
+import java.util.UUID;
+import mage.players.PlayerList;
+import mage.target.common.TargetCardInGraveyard;
+import mage.util.RandomUtil;
+
+/**
+ * @author TheElk801
+ */
+public final class WildfireDevils extends CardImpl {
+
+ public WildfireDevils(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
+
+ this.subtype.add(SubType.DEVIL);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(2);
+
+ // When Wildfire Devils enters the battlefield and at the beginning of your upkeep, choose a player at random. That player exiles an instant or sorcery card from their graveyard. Copy that card. You may cast the copy without paying its mana cost.
+ this.addAbility(new OrTriggeredAbility(
+ Zone.BATTLEFIELD, new WildfireDevilsEffect(), false,
+ "When {this} enters the battlefield and at the beginning of your upkeep, ",
+ new EntersBattlefieldTriggeredAbility(null, false),
+ new BeginningOfUpkeepTriggeredAbility(null, TargetController.YOU, false)
+ ));
+ }
+
+ private WildfireDevils(final WildfireDevils card) {
+ super(card);
+ }
+
+ @Override
+ public WildfireDevils copy() {
+ return new WildfireDevils(this);
+ }
+}
+
+class WildfireDevilsEffect extends OneShotEffect {
+
+ WildfireDevilsEffect() {
+ super(Outcome.Neutral);
+ staticText = "choose a player at random. That player exiles an instant or sorcery card from their graveyard. "
+ + "Copy that card. You may cast the copy without paying its mana cost.";
+ }
+
+ private WildfireDevilsEffect(final WildfireDevilsEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public WildfireDevilsEffect copy() {
+ return new WildfireDevilsEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) {
+ return false;
+ }
+ PlayerList players = game.getState().getPlayersInRange(controller.getId(), game);
+ if (players == null) {
+ return false;
+ }
+ Player randomPlayer = game.getPlayer(players.get(RandomUtil.nextInt(players.size())));
+ if (randomPlayer == null) {
+ return false;
+ }
+ game.informPlayers("The chosen random player is " + randomPlayer.getLogName());
+ if (randomPlayer.getGraveyard().getCards(game).stream().noneMatch(Card::isInstantOrSorcery)) {
+ return false;
+ }
+ TargetCardInGraveyard targetCard = new TargetCardInGraveyard(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY);
+ targetCard.setNotTarget(true);
+ if (!randomPlayer.choose(Outcome.Discard, randomPlayer.getGraveyard(), targetCard, game)) {
+ return false;
+ }
+ Card card = game.getCard(targetCard.getFirstTarget());
+ if (card == null) {
+ return false;
+ }
+ randomPlayer.moveCards(card, Zone.EXILED, source, game);
+ if (game.getState().getZone(card.getId()) != Zone.EXILED) {
+ return false;
+ }
+ Card copiedCard = game.copyCard(card, source, controller.getId());
+ if (copiedCard == null) {
+ return false;
+ }
+ randomPlayer.moveCards(copiedCard, Zone.EXILED, source, game);
+ if (!controller.chooseUse(outcome, "Cast the copy of the exiled card?", source, game)) {
+ return false;
+ }
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), Boolean.TRUE);
+ Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(copiedCard, game, true), game, true,
+ new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), null);
+ return cardWasCast;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WildfireEternal.java b/Mage.Sets/src/mage/cards/w/WildfireEternal.java
index b8171a299ab..295a70471a1 100644
--- a/Mage.Sets/src/mage/cards/w/WildfireEternal.java
+++ b/Mage.Sets/src/mage/cards/w/WildfireEternal.java
@@ -1,4 +1,3 @@
-
package mage.cards.w;
import java.util.UUID;
@@ -56,7 +55,8 @@ class WildfireEternalCastEffect extends OneShotEffect {
public WildfireEternalCastEffect() {
super(Outcome.Benefit);
- this.staticText = "you may cast an instant or sorcery card from your hand without paying its mana cost";
+ this.staticText = "you may cast an instant or sorcery card "
+ + "from your hand without paying its mana cost";
}
public WildfireEternalCastEffect(final WildfireEternalCastEffect effect) {
@@ -74,12 +74,17 @@ class WildfireEternalCastEffect extends OneShotEffect {
if (controller != null) {
FilterCard filter = new FilterInstantOrSorceryCard();
int cardsToCast = controller.getHand().count(filter, source.getControllerId(), source.getSourceId(), game);
- if (cardsToCast > 0 && controller.chooseUse(outcome, "Cast an instant or sorcery card from your hand without paying its mana cost?", source, game)) {
+ if (cardsToCast > 0
+ && controller.chooseUse(outcome, "Cast an instant or sorcery card from your "
+ + "hand without paying its mana cost?", source, game)) {
TargetCardInHand target = new TargetCardInHand(filter);
controller.chooseTarget(outcome, target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
return true;
diff --git a/Mage.Sets/src/mage/cards/w/WildwoodTracker.java b/Mage.Sets/src/mage/cards/w/WildwoodTracker.java
new file mode 100644
index 00000000000..8722bc8248c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WildwoodTracker.java
@@ -0,0 +1,61 @@
+package mage.cards.w;
+
+import mage.MageInt;
+import mage.abilities.common.AttacksOrBlocksTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.filter.predicate.permanent.AnotherPredicate;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WildwoodTracker extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterControlledCreaturePermanent();
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ filter.add(Predicates.not(new SubtypePredicate(SubType.HUMAN)));
+ }
+
+ private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter);
+
+ public WildwoodTracker(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}");
+
+ this.subtype.add(SubType.ELF);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Whenever Wildwood Tracker attacks or blocks, if you control another non-Human creature, Wildwood Tracker gets +1/+1 until end of turn.
+ this.addAbility(new ConditionalInterveningIfTriggeredAbility(
+ new AttacksOrBlocksTriggeredAbility(
+ new BoostSourceEffect(1, 1, Duration.EndOfTurn), false
+ ), condition, "Whenever {this} attacks or blocks, if you control another non-Human creature, " +
+ "{this} gets +1/+1 until end of turn."
+ ));
+ }
+
+ private WildwoodTracker(final WildwoodTracker card) {
+ super(card);
+ }
+
+ @Override
+ public WildwoodTracker copy() {
+ return new WildwoodTracker(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WindbornMuse.java b/Mage.Sets/src/mage/cards/w/WindbornMuse.java
index 0ab018990a7..251646cd7b5 100644
--- a/Mage.Sets/src/mage/cards/w/WindbornMuse.java
+++ b/Mage.Sets/src/mage/cards/w/WindbornMuse.java
@@ -28,7 +28,7 @@ public final class WindbornMuse extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
- // Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you.
+ // Creatures can't attack you unless their controller pays {2} for each creature they control that's attacking you.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackYouUnlessPayManaAllEffect(new ManaCostsImpl("{2}"))));
}
diff --git a/Mage.Sets/src/mage/cards/w/WindingCanyons.java b/Mage.Sets/src/mage/cards/w/WindingCanyons.java
index cc15ea56763..a20ba3d7aec 100644
--- a/Mage.Sets/src/mage/cards/w/WindingCanyons.java
+++ b/Mage.Sets/src/mage/cards/w/WindingCanyons.java
@@ -1,4 +1,3 @@
-
package mage.cards.w;
import java.util.UUID;
@@ -15,7 +14,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
/**
*
@@ -30,7 +29,7 @@ public final class WindingCanyons extends CardImpl {
this.addAbility(new ColorlessManaAbility());
// {2}, {tap}: Until end of turn, you may cast creature spells as though they had flash.
- Effect effect = new AddContinuousEffectToGame(new CastAsThoughItHadFlashAllEffect(Duration.EndOfTurn, new FilterCreatureCard()));
+ Effect effect = new AddContinuousEffectToGame(new CastAsThoughItHadFlashAllEffect(Duration.EndOfTurn, StaticFilters.FILTER_CARD_CREATURE));
effect.setText("Until end of turn, you may cast creature spells as though they had flash.");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(2));
ability.addCost(new TapSourceCost());
diff --git a/Mage.Sets/src/mage/cards/w/WintermoorCommander.java b/Mage.Sets/src/mage/cards/w/WintermoorCommander.java
new file mode 100644
index 00000000000..4ebf50678ae
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WintermoorCommander.java
@@ -0,0 +1,72 @@
+package mage.cards.w;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.effects.common.continuous.SetToughnessSourceEffect;
+import mage.abilities.keyword.DeathtouchAbility;
+import mage.abilities.keyword.IndestructibleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WintermoorCommander extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterControlledPermanent(SubType.KNIGHT, "Knights you control");
+ private static final DynamicValue xValue
+ = new PermanentsOnBattlefieldCount(filter);
+ private static final FilterPermanent filter2
+ = new FilterControlledPermanent(SubType.KNIGHT, "another target Knight you control");
+
+ static {
+ filter2.add(AnotherPredicate.instance);
+ }
+
+ public WintermoorCommander(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{B}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(0);
+
+ // Deathtouch
+ this.addAbility(DeathtouchAbility.getInstance());
+
+ // Wintermoor Commander's toughness is equal to the number of Knights you control.
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetToughnessSourceEffect(xValue, Duration.EndOfGame)));
+
+ // Whenever Wintermoor Commander attacks, another target Knight you control gains indestructible until end of turn.
+ Ability ability = new AttacksTriggeredAbility(new GainAbilityTargetEffect(
+ IndestructibleAbility.getInstance(), Duration.EndOfTurn
+ ), false);
+ ability.addTarget(new TargetPermanent(filter2));
+ this.addAbility(ability);
+ }
+
+ private WintermoorCommander(final WintermoorCommander card) {
+ super(card);
+ }
+
+ @Override
+ public WintermoorCommander copy() {
+ return new WintermoorCommander(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WishclawTalisman.java b/Mage.Sets/src/mage/cards/w/WishclawTalisman.java
new file mode 100644
index 00000000000..381a63d9776
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WishclawTalisman.java
@@ -0,0 +1,102 @@
+package mage.cards.w;
+
+import mage.abilities.Ability;
+import mage.abilities.common.ActivateIfConditionActivatedAbility;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.condition.common.MyTurnCondition;
+import mage.abilities.costs.common.RemoveCountersSourceCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.GainControlTargetEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.TargetPlayer;
+import mage.target.common.TargetCardInLibrary;
+import mage.target.common.TargetOpponent;
+import mage.target.targetpointer.FixedTarget;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WishclawTalisman extends CardImpl {
+
+ public WishclawTalisman(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{B}");
+
+ // Wishclaw Talisman enters the battlefield with three wish counters on it.
+ this.addAbility(new EntersBattlefieldAbility(
+ new AddCountersSourceEffect(CounterType.WISH.createInstance(3)),
+ "{this} enters the battlefield with three wish counters on it"
+ ));
+
+ // {1}, {T}, Remove a wish counter from Wishclaw Talisman: Search your library for a card, put it into your hand, then shuffle your library. An opponent gains control of Wishclaw Talisman. Activate this ability only during your turn.
+ Ability ability = new ActivateIfConditionActivatedAbility(
+ Zone.BATTLEFIELD, new WishclawTalismanEffect(), new GenericManaCost(1), MyTurnCondition.instance
+ );
+ ability.addCost(new TapSourceCost());
+ ability.addCost(new RemoveCountersSourceCost(CounterType.WISH.createInstance()));
+ this.addAbility(ability);
+ }
+
+ private WishclawTalisman(final WishclawTalisman card) {
+ super(card);
+ }
+
+ @Override
+ public WishclawTalisman copy() {
+ return new WishclawTalisman(this);
+ }
+}
+
+class WishclawTalismanEffect extends OneShotEffect {
+
+ private static final Effect effect = new SearchLibraryPutInHandEffect(new TargetCardInLibrary());
+
+ WishclawTalismanEffect() {
+ super(Outcome.Benefit);
+ staticText = "Search your library for a card, put it into your hand, then shuffle your library. " +
+ "An opponent gains control of {this}";
+ }
+
+ private WishclawTalismanEffect(final WishclawTalismanEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public WishclawTalismanEffect copy() {
+ return new WishclawTalismanEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ effect.apply(game, source);
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ TargetPlayer target = new TargetOpponent();
+ target.setNotTarget(true);
+ if (!player.choose(outcome, target, source.getSourceId(), game)) {
+ return false;
+ }
+ ContinuousEffect continuousEffect
+ = new GainControlTargetEffect(Duration.Custom, true, target.getFirstTarget());
+ continuousEffect.setTargetPointer(new FixedTarget(source.getSourceId(), game));
+ game.addEffect(continuousEffect, source);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/w/WishfulMerfolk.java b/Mage.Sets/src/mage/cards/w/WishfulMerfolk.java
new file mode 100644
index 00000000000..09ce7ad9110
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WishfulMerfolk.java
@@ -0,0 +1,96 @@
+package mage.cards.w;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.ContinuousEffectImpl;
+import mage.abilities.keyword.DefenderAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+
+import java.util.UUID;
+
+/**
+ *
+ * @author jmharmon
+ */
+
+public final class WishfulMerfolk extends CardImpl {
+
+ public WishfulMerfolk(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
+ this.subtype.add(SubType.MERFOLK);
+
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(2);
+
+ // Defender
+ this.addAbility(DefenderAbility.getInstance());
+
+ // {1}{U}: Wishful Merfolk loses defender and becomes a Human until end of turn.
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new WishfulMerfolkEffect(), new ManaCostsImpl("{1}{U}")));
+ }
+
+ public WishfulMerfolk(final WishfulMerfolk card) {
+ super(card);
+ }
+
+ @Override
+ public WishfulMerfolk copy() {
+ return new WishfulMerfolk(this);
+ }
+}
+
+class WishfulMerfolkEffect extends ContinuousEffectImpl {
+
+ public WishfulMerfolkEffect() {
+ super(Duration.EndOfTurn, Outcome.AddAbility);
+ staticText = "{this} loses defender and becomes a Human until end of turn";
+ }
+
+ public WishfulMerfolkEffect(final WishfulMerfolkEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public WishfulMerfolkEffect copy() {
+ return new WishfulMerfolkEffect(this);
+ }
+
+ @Override
+ public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
+ Permanent permanent = game.getPermanent(source.getSourceId());
+ if (permanent != null) {
+ switch (layer) {
+ case AbilityAddingRemovingEffects_6:
+ if (sublayer == SubLayer.NA) {
+ permanent.getAbilities().removeIf(entry -> entry.getId().equals(DefenderAbility.getInstance().getId()));
+ }
+ break;
+ case TypeChangingEffects_4:
+ if (permanent.getSubtype(game).contains(SubType.MERFOLK)) {
+ permanent.getSubtype(game).clear();
+ permanent.getSubtype(game).add(SubType.HUMAN);
+ }
+ break;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return false;
+ }
+
+ @Override
+ public boolean hasLayer(Layer layer) {
+ return layer == Layer.AbilityAddingRemovingEffects_6
+ || layer == Layer.TypeChangingEffects_4;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WitchingWell.java b/Mage.Sets/src/mage/cards/w/WitchingWell.java
new file mode 100644
index 00000000000..965e730f14d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WitchingWell.java
@@ -0,0 +1,44 @@
+package mage.cards.w;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.keyword.ScryEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Zone;
+
+import java.util.UUID;
+
+/**
+ *
+ * @author jmharmon
+ */
+
+public final class WitchingWell extends CardImpl {
+
+ public WitchingWell(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{U}");
+
+ // When Witching Well enters the battlefield, scry 2.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new ScryEffect(2)));
+
+ // {3}{U}, Sacrifice Witching Well: Draw two cards.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(2), new ManaCostsImpl("{3}{U}"));
+ ability.addCost(new SacrificeSourceCost());
+ this.addAbility(ability);
+ }
+
+ public WitchingWell(final WitchingWell card) {
+ super(card);
+ }
+
+ @Override
+ public WitchingWell copy() {
+ return new WitchingWell(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WitchsCottage.java b/Mage.Sets/src/mage/cards/w/WitchsCottage.java
new file mode 100644
index 00000000000..bf659a2d3b1
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WitchsCottage.java
@@ -0,0 +1,72 @@
+package mage.cards.w;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.common.EntersBattlefieldUntappedTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.PutOnLibraryTargetEffect;
+import mage.abilities.effects.common.TapSourceEffect;
+import mage.abilities.mana.BlackManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.target.common.TargetCardInYourGraveyard;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WitchsCottage extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterControlledPermanent(SubType.SWAMP);
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ }
+
+ private static final Condition condition
+ = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.FEWER_THAN, 3);
+
+ public WitchsCottage(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ this.subtype.add(SubType.SWAMP);
+
+ // ({T}: Add {B}.)
+ this.addAbility(new BlackManaAbility());
+
+ // Witch's Cottage enters the battlefield tapped unless you control three or more other Swamps.
+ this.addAbility(new EntersBattlefieldAbility(
+ new ConditionalOneShotEffect(new TapSourceEffect(), condition),
+ "tapped unless you control three or more other Swamps"
+ ));
+
+ // When Witch's Cottage enters the battlefield untapped, you may put target creature card from your graveyard on top of your library.
+ Ability ability = new EntersBattlefieldUntappedTriggeredAbility(
+ new PutOnLibraryTargetEffect(true)
+ .setText("put target creature card from your graveyard on top of your library"),
+ true
+ );
+ ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
+ this.addAbility(ability);
+ }
+
+ private WitchsCottage(final WitchsCottage card) {
+ super(card);
+ }
+
+ @Override
+ public WitchsCottage copy() {
+ return new WitchsCottage(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WitchsOven.java b/Mage.Sets/src/mage/cards/w/WitchsOven.java
new file mode 100644
index 00000000000..aa1d4807d89
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WitchsOven.java
@@ -0,0 +1,87 @@
+package mage.cards.w;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.token.FoodToken;
+import mage.target.common.TargetControlledCreaturePermanent;
+
+import java.util.Collection;
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WitchsOven extends CardImpl {
+
+ public WitchsOven(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
+
+ // {T}, Sacrifice a creature: Create a Food token. If the sacrificed creature's toughness was 4 or greater, create two Food tokens instead.
+ Ability ability = new SimpleActivatedAbility(new WitchsOvenEffect(), new TapSourceCost());
+ ability.addCost(new SacrificeTargetCost(
+ new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)
+ ));
+ this.addAbility(ability);
+ }
+
+ private WitchsOven(final WitchsOven card) {
+ super(card);
+ }
+
+ @Override
+ public WitchsOven copy() {
+ return new WitchsOven(this);
+ }
+}
+
+class WitchsOvenEffect extends OneShotEffect {
+
+ private static final Effect effect1 = new CreateTokenEffect(new FoodToken(), 1);
+ private static final Effect effect2 = new CreateTokenEffect(new FoodToken(), 2);
+
+ WitchsOvenEffect() {
+ super(Outcome.Benefit);
+ staticText = "Create a Food token. If the sacrificed creature's toughness " +
+ "was 4 or greater, create two Food tokens instead";
+ }
+
+ private WitchsOvenEffect(final WitchsOvenEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public WitchsOvenEffect copy() {
+ return new WitchsOvenEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ boolean big = source
+ .getCosts()
+ .stream()
+ .filter(SacrificeTargetCost.class::isInstance)
+ .map(SacrificeTargetCost.class::cast)
+ .map(SacrificeTargetCost::getPermanents)
+ .flatMap(Collection::stream)
+ .map(Permanent::getToughness)
+ .mapToInt(MageInt::getValue)
+ .anyMatch(i -> i > 3);
+ if (big) {
+ return effect2.apply(game, source);
+ }
+ return effect1.apply(game, source);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WitchsVengeance.java b/Mage.Sets/src/mage/cards/w/WitchsVengeance.java
new file mode 100644
index 00000000000..c75558b5197
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WitchsVengeance.java
@@ -0,0 +1,75 @@
+package mage.cards.w;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.BoostAllEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.choices.ChoiceCreatureType;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.game.Game;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WitchsVengeance extends CardImpl {
+
+ public WitchsVengeance(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}{B}");
+
+ // Creatures of the creature type of your choice get -3/-3 until end of turn.
+ this.getSpellAbility().addEffect(new WitchsVengeanceEffect());
+ }
+
+ private WitchsVengeance(final WitchsVengeance card) {
+ super(card);
+ }
+
+ @Override
+ public WitchsVengeance copy() {
+ return new WitchsVengeance(this);
+ }
+}
+
+class WitchsVengeanceEffect extends OneShotEffect {
+
+ WitchsVengeanceEffect() {
+ super(Outcome.Benefit);
+ staticText = "Creatures of the creature type of your choice get -3/-3 until end of turn.";
+ }
+
+ private WitchsVengeanceEffect(final WitchsVengeanceEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public WitchsVengeanceEffect copy() {
+ return new WitchsVengeanceEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ ChoiceCreatureType choice = new ChoiceCreatureType();
+ if (!player.choose(outcome, choice, game)) {
+ return false;
+ }
+ FilterCreaturePermanent filter = new FilterCreaturePermanent();
+ filter.add(new SubtypePredicate(SubType.byDescription(choice.getChoice())));
+ game.addEffect(new BoostAllEffect(
+ -3, -3, Duration.EndOfTurn, filter, false
+ ), source);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/w/WoeStrider.java b/Mage.Sets/src/mage/cards/w/WoeStrider.java
new file mode 100644
index 00000000000..88b5e5e173a
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WoeStrider.java
@@ -0,0 +1,65 @@
+package mage.cards.w;
+
+import mage.MageInt;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.EscapesWithAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.keyword.ScryEffect;
+import mage.abilities.keyword.EscapeAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.game.permanent.token.GoatToken;
+import mage.target.common.TargetControlledPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WoeStrider extends CardImpl {
+
+ private static final FilterControlledPermanent filter
+ = new FilterControlledCreaturePermanent("another creature");
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ }
+
+ public WoeStrider(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
+
+ this.subtype.add(SubType.HORROR);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(2);
+
+ // Whenever Woe Strider enters the battlefield, create a 0/1 white Goat creature token.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GoatToken())));
+
+ // Sacrifice another creature: Scry 1.
+ this.addAbility(new SimpleActivatedAbility(
+ new ScryEffect(1), new SacrificeTargetCost(new TargetControlledPermanent(filter))
+ ));
+
+ // Escape—{3}{B}{B}, Exile four other cards from your graveyard.
+ this.addAbility(new EscapeAbility(this, "{3}{B}{B}", 4));
+
+ // Woe Strider escapes with two +1/+1 counters on it.
+ this.addAbility(new EscapesWithAbility(2));
+ }
+
+ private WoeStrider(final WoeStrider card) {
+ super(card);
+ }
+
+ @Override
+ public WoeStrider copy() {
+ return new WoeStrider(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WolfsQuarry.java b/Mage.Sets/src/mage/cards/w/WolfsQuarry.java
new file mode 100644
index 00000000000..befa35de34b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WolfsQuarry.java
@@ -0,0 +1,31 @@
+package mage.cards.w;
+
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.game.permanent.token.WolfsQuarryToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WolfsQuarry extends CardImpl {
+
+ public WolfsQuarry(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}{G}");
+
+ // Create three 1/1 green Boar creature tokens with "When this creature dies, create a Food token."
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new WolfsQuarryToken(), 3));
+ }
+
+ private WolfsQuarry(final WolfsQuarry card) {
+ super(card);
+ }
+
+ @Override
+ public WolfsQuarry copy() {
+ return new WolfsQuarry(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WoodlandSleuth.java b/Mage.Sets/src/mage/cards/w/WoodlandSleuth.java
index bb5b2b2a95e..008cea16163 100644
--- a/Mage.Sets/src/mage/cards/w/WoodlandSleuth.java
+++ b/Mage.Sets/src/mage/cards/w/WoodlandSleuth.java
@@ -1,4 +1,3 @@
-
package mage.cards.w;
import java.util.UUID;
@@ -13,10 +12,10 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.util.RandomUtil;
@@ -30,7 +29,7 @@ public final class WoodlandSleuth extends CardImpl {
private static final String staticText = "Morbid — When {this} enters the battlefield, if a creature died this turn, return a creature card at random from your graveyard to your hand.";
public WoodlandSleuth(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SCOUT);
@@ -73,7 +72,7 @@ class WoodlandSleuthEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- Card[] cards = player.getGraveyard().getCards(new FilterCreatureCard(), game).toArray(new Card[0]);
+ Card[] cards = player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game).toArray(new Card[0]);
if (cards.length > 0) {
Card card = cards[RandomUtil.nextInt(cards.length)];
card.moveToZone(Zone.HAND, source.getSourceId(), game, true);
diff --git a/Mage.Sets/src/mage/cards/w/WordOfCommand.java b/Mage.Sets/src/mage/cards/w/WordOfCommand.java
index 68626c6457c..8dbd48ff5c6 100644
--- a/Mage.Sets/src/mage/cards/w/WordOfCommand.java
+++ b/Mage.Sets/src/mage/cards/w/WordOfCommand.java
@@ -98,7 +98,7 @@ class WordOfCommandEffect extends OneShotEffect {
controller.controlPlayersTurn(game, targetPlayer.getId());
while (controller.canRespond()) {
if (controller.chooseUse(Outcome.Benefit, "Resolve " + sourceObject.getLogName() + " now" + (card != null ? " and play " + card.getLogName() : "") + '?', source, game)) {
- // this is used to give the controller a little space to utilize his player controlling effect (look at face down creatures, hand, etc.)
+ // this is used to give the controller a little space to utilize their player controlling effect (look at face down creatures, hand, etc.)
break;
}
}
@@ -110,7 +110,7 @@ class WordOfCommandEffect extends OneShotEffect {
effect.setTargetPointer(new FixedTarget(targetPlayer.getId()));
game.addEffect(effect, source);
- // and only if mana they produce is spent to activate other mana abilities of lands he or she controls and/or play that card
+ // and only if mana they produce is spent to activate other mana abilities of lands they control and/or play that card
ManaPool manaPool = targetPlayer.getManaPool();
manaPool.setForcedToPay(true);
manaPool.storeMana();
@@ -182,7 +182,7 @@ class WordOfCommandEffect extends OneShotEffect {
} else { // Word of Command allows the chosen card to be played "as if it had flash" so we need to invoke such effect to bypass the check
AsThoughEffectImpl effect2 = new WordOfCommandTestFlashEffect();
game.addEffect(effect2, source);
- if (targetPlayer.getPlayableObjects(game, Zone.HAND).contains(card.getId())) {
+ if (targetPlayer.getPlayableObjects(game, Zone.HAND).containsKey(card.getId())) {
canPlay = true;
}
for (AsThoughEffect eff : game.getContinuousEffects().getApplicableAsThoughEffects(AsThoughEffectType.CAST_AS_INSTANT, game)) {
diff --git a/Mage.Sets/src/mage/cards/w/WordsOfWind.java b/Mage.Sets/src/mage/cards/w/WordsOfWind.java
index da3860a0893..3a06be36c92 100644
--- a/Mage.Sets/src/mage/cards/w/WordsOfWind.java
+++ b/Mage.Sets/src/mage/cards/w/WordsOfWind.java
@@ -31,7 +31,7 @@ public final class WordsOfWind extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}");
- // {1}: The next time you would draw a card this turn, each player returns a permanent he or she controls to its owner's hand instead.
+ // {1}: The next time you would draw a card this turn, each player returns a permanent they control to its owner's hand instead.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new WordsOfWindEffect(), new ManaCostsImpl("{1}")));
}
@@ -49,7 +49,7 @@ class WordsOfWindEffect extends ReplacementEffectImpl {
public WordsOfWindEffect() {
super(Duration.EndOfTurn, Outcome.ReturnToHand);
- staticText = "The next time you would draw a card this turn, each player returns a permanent he or she controls to its owner's hand instead";
+ staticText = "The next time you would draw a card this turn, each player returns a permanent they control to its owner's hand instead";
}
public WordsOfWindEffect(final WordsOfWindEffect effect) {
@@ -63,7 +63,7 @@ class WordsOfWindEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- game.informPlayers("Each player returns a permanent he or she controls to its owner's hand instead");
+ game.informPlayers("Each player returns a permanent they control to its owner's hand instead");
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
diff --git a/Mage.Sets/src/mage/cards/w/WorkshopElders.java b/Mage.Sets/src/mage/cards/w/WorkshopElders.java
new file mode 100644
index 00000000000..c1f6d264383
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WorkshopElders.java
@@ -0,0 +1,77 @@
+package mage.cards.w;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfCombatTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.continuous.AddCardTypeTargetEffect;
+import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
+import mage.abilities.effects.common.continuous.SetPowerToughnessTargetEffect;
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.TargetController;
+import mage.counters.CounterType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterArtifactCreaturePermanent;
+import mage.filter.common.FilterControlledArtifactPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.CardTypePredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WorkshopElders extends CardImpl {
+
+ private static final FilterPermanent filter
+ = new FilterArtifactCreaturePermanent("artifact creatures");
+ private static final FilterPermanent filter2
+ = new FilterControlledArtifactPermanent("noncreature artifact you control");
+
+ static {
+ filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
+ }
+
+ public WorkshopElders(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{U}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.ARTIFICER);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(4);
+
+ // Artifact creatures you control have flying.
+ this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
+ FlyingAbility.getInstance(), Duration.WhileOnBattlefield, filter
+ )));
+
+ // At the beginning of combat on your turn, you may have target noncreature artifact you control become a 0/0 artifact creature. If you do, put four +1/+1 counters on it.
+ Ability ability = new BeginningOfCombatTriggeredAbility(new AddCardTypeTargetEffect(
+ Duration.EndOfGame, CardType.ARTIFACT, CardType.CREATURE
+ ).setText("have target noncreature artifact you control become"), TargetController.YOU, true);
+ ability.addEffect(new SetPowerToughnessTargetEffect(
+ 0, 0, Duration.EndOfGame
+ ).setText("a 0/0 artifact creature."));
+ ability.addEffect(new AddCountersTargetEffect(
+ CounterType.P1P1.createInstance(4)
+ ).setText("If you do, put four +1/+1 counters on it."));
+ ability.addTarget(new TargetPermanent(filter2));
+ this.addAbility(ability);
+ }
+
+ private WorkshopElders(final WorkshopElders card) {
+ super(card);
+ }
+
+ @Override
+ public WorkshopElders copy() {
+ return new WorkshopElders(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WorldlyTutor.java b/Mage.Sets/src/mage/cards/w/WorldlyTutor.java
index 637a9ef6eaa..d6faec91c1a 100644
--- a/Mage.Sets/src/mage/cards/w/WorldlyTutor.java
+++ b/Mage.Sets/src/mage/cards/w/WorldlyTutor.java
@@ -1,4 +1,3 @@
-
package mage.cards.w;
import java.util.UUID;
@@ -6,7 +5,7 @@ import mage.abilities.effects.common.search.SearchLibraryPutOnLibraryEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.target.common.TargetCardInLibrary;
/**
@@ -16,11 +15,10 @@ import mage.target.common.TargetCardInLibrary;
public final class WorldlyTutor extends CardImpl {
public WorldlyTutor(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{G}");
-
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}");
// Search your library for a creature card and reveal that card. Shuffle your library, then put the card on top of it.
- this.getSpellAbility().addEffect(new SearchLibraryPutOnLibraryEffect(new TargetCardInLibrary(new FilterCreatureCard()), true, true));
+ this.getSpellAbility().addEffect(new SearchLibraryPutOnLibraryEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_CREATURE), true, true));
}
public WorldlyTutor(final WorldlyTutor card) {
diff --git a/Mage.Sets/src/mage/cards/w/WormsOfTheEarth.java b/Mage.Sets/src/mage/cards/w/WormsOfTheEarth.java
index 128d05dbd87..b6ea0e2a5d7 100644
--- a/Mage.Sets/src/mage/cards/w/WormsOfTheEarth.java
+++ b/Mage.Sets/src/mage/cards/w/WormsOfTheEarth.java
@@ -35,7 +35,7 @@ public final class WormsOfTheEarth extends CardImpl {
// Lands can't enter the battlefield.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new WormsOfTheEarthEnterEffect()));
- // At the beginning of each upkeep, any player may sacrifice two lands or have Worms of the Earth deal 5 damage to him or her. If a player does either, destroy Worms of the Earth.
+ // At the beginning of each upkeep, any player may sacrifice two lands or have Worms of the Earth deal 5 damage to that player. If a player does either, destroy Worms of the Earth.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new WormsOfTheEarthDestroyEffect(), TargetController.ANY, false));
}
@@ -117,7 +117,7 @@ class WormsOfTheEarthDestroyEffect extends OneShotEffect {
public WormsOfTheEarthDestroyEffect() {
super(Outcome.Benefit);
- this.staticText = "any player may sacrifice two lands or have {this} deal 5 damage to him or her. If a player does either, destroy {this}";
+ this.staticText = "any player may sacrifice two lands or have {this} deal 5 damage to that player. If a player does either, destroy {this}";
}
public WormsOfTheEarthDestroyEffect(final WormsOfTheEarthDestroyEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/w/WorthyKnight.java b/Mage.Sets/src/mage/cards/w/WorthyKnight.java
new file mode 100644
index 00000000000..636dbc351ad
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WorthyKnight.java
@@ -0,0 +1,49 @@
+package mage.cards.w;
+
+import mage.MageInt;
+import mage.abilities.common.SpellCastControllerTriggeredAbility;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.filter.FilterSpell;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.game.permanent.token.HumanToken;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WorthyKnight extends CardImpl {
+
+ private static final FilterSpell filter = new FilterSpell("a Knight spell");
+
+ static {
+ filter.add(new SubtypePredicate(SubType.KNIGHT));
+ }
+
+ public WorthyKnight(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.KNIGHT);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Whenever you cast a Knight spell, create a 1/1 white Human creature token.
+ this.addAbility(new SpellCastControllerTriggeredAbility(
+ new CreateTokenEffect(new HumanToken()), filter, false
+ ));
+ }
+
+ private WorthyKnight(final WorthyKnight card) {
+ super(card);
+ }
+
+ @Override
+ public WorthyKnight copy() {
+ return new WorthyKnight(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WoundReflection.java b/Mage.Sets/src/mage/cards/w/WoundReflection.java
index 460acc927ab..e039278c0a9 100644
--- a/Mage.Sets/src/mage/cards/w/WoundReflection.java
+++ b/Mage.Sets/src/mage/cards/w/WoundReflection.java
@@ -24,7 +24,7 @@ public final class WoundReflection extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{5}{B}");
- // At the beginning of each end step, each opponent loses life equal to the life he or she lost this turn.
+ // At the beginning of each end step, each opponent loses life equal to the life they lost this turn.
this.addAbility(new BeginningOfEndStepTriggeredAbility(new WoundReflectionEffect(), TargetController.ANY, false));
}
@@ -42,7 +42,7 @@ class WoundReflectionEffect extends OneShotEffect {
public WoundReflectionEffect() {
super(Outcome.LoseLife);
- this.staticText = "each opponent loses life equal to the life he or she lost this turn";
+ this.staticText = "each opponent loses life equal to the life they lost this turn";
}
public WoundReflectionEffect(final WoundReflectionEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/w/WreathOfGeists.java b/Mage.Sets/src/mage/cards/w/WreathOfGeists.java
index 8991b23d966..2b7090df7e9 100644
--- a/Mage.Sets/src/mage/cards/w/WreathOfGeists.java
+++ b/Mage.Sets/src/mage/cards/w/WreathOfGeists.java
@@ -1,4 +1,3 @@
-
package mage.cards.w;
import java.util.UUID;
@@ -12,10 +11,10 @@ import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
@@ -26,10 +25,9 @@ import mage.target.common.TargetCreaturePermanent;
public final class WreathOfGeists extends CardImpl {
public WreathOfGeists(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}");
this.subtype.add(SubType.AURA);
-
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
@@ -39,7 +37,7 @@ public final class WreathOfGeists extends CardImpl {
this.addAbility(ability);
// Enchanted creature gets +X/+X, where X is the number of creature cards in your graveyard.
- DynamicValue value = new CardsInControllerGraveyardCount(new FilterCreatureCard());
+ DynamicValue value = new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(value, value)));
}
diff --git a/Mage.Sets/src/mage/cards/w/WrenchMind.java b/Mage.Sets/src/mage/cards/w/WrenchMind.java
index 395e7c8e6ea..ae5dbe64aae 100644
--- a/Mage.Sets/src/mage/cards/w/WrenchMind.java
+++ b/Mage.Sets/src/mage/cards/w/WrenchMind.java
@@ -24,7 +24,7 @@ public final class WrenchMind extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}{B}");
- // Target player discards two cards unless he or she discards an artifact card.
+ // Target player discards two cards unless they discard an artifact card.
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new WrenchMindEffect());
@@ -44,7 +44,7 @@ class WrenchMindEffect extends OneShotEffect {
public WrenchMindEffect() {
super(Outcome.Discard);
- this.staticText = "Target player discards two cards unless he or she discards an artifact card";
+ this.staticText = "Target player discards two cards unless they discard an artifact card";
}
public WrenchMindEffect(final WrenchMindEffect effect) {
@@ -66,7 +66,7 @@ class WrenchMindEffect extends OneShotEffect {
if (card != null) {
targetPlayer.discard(card, source, game);
if (!card.isArtifact() && !targetPlayer.getHand().isEmpty()) {
- targetPlayer.discard(1, source, game);
+ targetPlayer.discard(1, false, source, game);
}
return true;
}
diff --git a/Mage.Sets/src/mage/cards/w/WrexialTheRisenDeep.java b/Mage.Sets/src/mage/cards/w/WrexialTheRisenDeep.java
index f30afcbf4ca..4b48efebcb9 100644
--- a/Mage.Sets/src/mage/cards/w/WrexialTheRisenDeep.java
+++ b/Mage.Sets/src/mage/cards/w/WrexialTheRisenDeep.java
@@ -46,7 +46,10 @@ public final class WrexialTheRisenDeep extends CardImpl {
// Swampwalk
this.addAbility(new SwampwalkAbility());
- // Whenever Wrexial, the Risen Deep deals combat damage to a player, you may cast target instant or sorcery card from that player's graveyard without paying its mana cost. If that card would be put into a graveyard this turn, exile it instead.
+ // Whenever Wrexial, the Risen Deep deals combat damage to a player,
+ // you may cast target instant or sorcery card from that player's graveyard
+ // without paying its mana cost. If that card would be put into a graveyard
+ // this turn, exile it instead.
this.addAbility(new WrexialTheRisenDeepTriggeredAbility());
}
@@ -89,7 +92,8 @@ class WrexialTheRisenDeepTriggeredAbility extends TriggeredAbilityImpl {
if (damagedPlayer == null) {
return false;
}
- FilterCard filter = new FilterCard("target instant or sorcery card from " + damagedPlayer.getName() + "'s graveyard");
+ FilterCard filter = new FilterCard("target instant or sorcery card from "
+ + damagedPlayer.getName() + "'s graveyard");
filter.add(new OwnerIdPredicate(damagedPlayer.getId()));
filter.add(Predicates.or(
new CardTypePredicate(CardType.INSTANT),
@@ -132,10 +136,14 @@ class WrexialTheRisenDeepEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Card card = game.getCard(source.getFirstTarget());
- if (controller == null || card == null) {
+ if (controller == null
+ || card == null) {
return false;
}
- controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
+ controller.cast(controller.chooseAbilityForCast(card, game, true),
+ game, true, new MageObjectReference(source.getSourceObject(game), game));
+ game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
game.addEffect(new WrexialReplacementEffect(card.getId()), source);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java b/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java
index d0a35959e7f..f16a7f447af 100644
--- a/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java
+++ b/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java
@@ -28,11 +28,9 @@ import java.util.UUID;
import static mage.constants.Outcome.Benefit;
-
/**
* @author jesusjbr
*/
-
public final class XantchaSleeperAgent extends CardImpl {
public XantchaSleeperAgent(UUID ownerId, CardSetInfo setInfo) {
@@ -145,14 +143,18 @@ class XantchaSleeperAgentAttackRestrictionEffect extends RestrictionEffect {
boolean allowAttack = true;
UUID ownerPlayerId = source.getSourcePermanentIfItStillExists(game).getOwnerId();
- if (defenderId.equals(ownerPlayerId)) {
+ if (defenderId.equals(ownerPlayerId)
+ && game.getPlayers().size() == 2) { // if only 2 players are left, it can't attack at all.
allowAttack = false;
- } else {
- Permanent planeswalker = game.getPermanent(defenderId);
- if (planeswalker != null && planeswalker.isControlledBy(ownerPlayerId)) {
- allowAttack = false;
- }
}
+ if (defenderId.equals(ownerPlayerId)) { // can't attack owner
+ allowAttack = false;
+ }
+ Permanent planeswalker = game.getPermanent(defenderId);
+ if (planeswalker != null && planeswalker.isControlledBy(ownerPlayerId)) { // can't attack the owner's planeswalkers
+ allowAttack = false;
+ }
+
return allowAttack;
}
}
diff --git a/Mage.Sets/src/mage/cards/x/XenagosGodOfRevels.java b/Mage.Sets/src/mage/cards/x/XenagosGodOfRevels.java
index 3eada0b3a35..e0e485e3bb0 100644
--- a/Mage.Sets/src/mage/cards/x/XenagosGodOfRevels.java
+++ b/Mage.Sets/src/mage/cards/x/XenagosGodOfRevels.java
@@ -1,14 +1,10 @@
-
package mage.cards.x;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfCombatTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.DevotionCount;
-import mage.abilities.effects.ContinuousEffect;
-import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
@@ -18,25 +14,29 @@ import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
+import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
-import mage.target.common.TargetControlledCreaturePermanent;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class XenagosGodOfRevels extends CardImpl {
- private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another target creature you control");
+ private static final FilterPermanent filter
+ = new FilterControlledCreaturePermanent("another target creature you control");
+
static {
filter.add(AnotherPredicate.instance);
}
public XenagosGodOfRevels(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{3}{R}{G}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{3}{R}{G}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.GOD);
@@ -45,21 +45,25 @@ public final class XenagosGodOfRevels extends CardImpl {
// Indestructible
this.addAbility(IndestructibleAbility.getInstance());
+
// As long as your devotion to red and green is less than seven, Xenagos isn't a creature.
- Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.R, ColoredManaSymbol.G), 7);
- effect.setText("As long as your devotion to red and green is less than seven, Xenagos isn't a creature");
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
+ this.addAbility(new SimpleStaticAbility(new LoseCreatureTypeSourceEffect(DevotionCount.RG, 7))
+ .addHint(DevotionCount.RG.getHint()));
// At the beginning of combat on your turn, another target creature you control gains haste and gets +X/+X until end of turn, where X is that creature's power.
- effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn);
- effect.setText("another target creature you control gains haste");
- Ability ability = new BeginningOfCombatTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.YOU, false, false);
+ Ability ability = new BeginningOfCombatTriggeredAbility(
+ Zone.BATTLEFIELD,
+ new GainAbilityTargetEffect(
+ HasteAbility.getInstance(), Duration.EndOfTurn
+ ).setText("another target creature you control gains haste"),
+ TargetController.YOU, false, false
+ );
ability.addEffect(new XenagosGodOfRevelsEffect());
- ability.addTarget(new TargetControlledCreaturePermanent(1,1,filter, false));
+ ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
}
- public XenagosGodOfRevels(final XenagosGodOfRevels card) {
+ private XenagosGodOfRevels(final XenagosGodOfRevels card) {
super(card);
}
@@ -71,12 +75,12 @@ public final class XenagosGodOfRevels extends CardImpl {
class XenagosGodOfRevelsEffect extends OneShotEffect {
- public XenagosGodOfRevelsEffect() {
+ XenagosGodOfRevelsEffect() {
super(Outcome.BoostCreature);
this.staticText = "and gets +X/+X until end of turn, where X is that creature's power";
}
- public XenagosGodOfRevelsEffect(final XenagosGodOfRevelsEffect effect) {
+ private XenagosGodOfRevelsEffect(final XenagosGodOfRevelsEffect effect) {
super(effect);
}
@@ -88,11 +92,13 @@ class XenagosGodOfRevelsEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
- if (targetCreature != null) {
- ContinuousEffect effect = new BoostTargetEffect(targetCreature.getPower().getValue(), targetCreature.getPower().getValue(), Duration.EndOfTurn);
- effect.setTargetPointer(this.getTargetPointer());
- game.addEffect(effect, source);
+ if (targetCreature == null) {
+ return false;
}
+ int power = targetCreature.getPower().getValue();
+ game.addEffect(new BoostTargetEffect(
+ power, power, Duration.EndOfTurn
+ ).setTargetPointer(this.getTargetPointer()), source);
return false;
}
}
diff --git a/Mage.Sets/src/mage/cards/x/XenagosTheReveler.java b/Mage.Sets/src/mage/cards/x/XenagosTheReveler.java
index 94e38731f20..195a738ccb0 100644
--- a/Mage.Sets/src/mage/cards/x/XenagosTheReveler.java
+++ b/Mage.Sets/src/mage/cards/x/XenagosTheReveler.java
@@ -123,6 +123,7 @@ class XenagosExileEffect extends OneShotEffect {
filter.add(Predicates.or(new CardTypePredicate(CardType.CREATURE),
new CardTypePredicate(CardType.LAND)));
TargetCard target1 = new TargetCard(0, Integer.MAX_VALUE, Zone.EXILED, filter);
+ target1.setNotTarget(true);
if (!exiledCards.isEmpty()
&& target1.canChoose(source.getSourceId(), source.getControllerId(), game)
&& controller.choose(Outcome.PutCardInPlay, exiledCards, target1, game)) {
diff --git a/Mage.Sets/src/mage/cards/y/YaroksFenlurker.java b/Mage.Sets/src/mage/cards/y/YaroksFenlurker.java
index 2ca7468e5f9..19800dad698 100644
--- a/Mage.Sets/src/mage/cards/y/YaroksFenlurker.java
+++ b/Mage.Sets/src/mage/cards/y/YaroksFenlurker.java
@@ -75,7 +75,8 @@ class YaroksFenlurkerEffect extends OneShotEffect {
Map cardsToExile = new HashMap<>();
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentId);
- if (opponent == null) {
+ if (opponent == null
+ || opponent.getHand().isEmpty()) {
continue;
}
int numberOfCardsToExile = Math.min(1, opponent.getHand().size());
diff --git a/Mage.Sets/src/mage/cards/y/YennettCrypticSovereign.java b/Mage.Sets/src/mage/cards/y/YennettCrypticSovereign.java
index b8021cbbde8..6794aa5a3bd 100644
--- a/Mage.Sets/src/mage/cards/y/YennettCrypticSovereign.java
+++ b/Mage.Sets/src/mage/cards/y/YennettCrypticSovereign.java
@@ -43,7 +43,8 @@ public final class YennettCrypticSovereign extends CardImpl {
// Menace
this.addAbility(new MenaceAbility());
- // Whenever Yennett, Cryptic Sovereign attacks, reveal the top card of your library. If that card's converted mana cost is odd, you may cast it without paying its mana cost. Otherwise, draw a card.
+ // Whenever Yennett, Cryptic Sovereign attacks, reveal the top card of your library. If that card's
+ // converted mana cost is odd, you may cast it without paying its mana cost. Otherwise, draw a card.
this.addAbility(new AttacksTriggeredAbility(
new YennettCrypticSovereignEffect(), false
));
@@ -92,6 +93,13 @@ class YennettCrypticSovereignEffect extends OneShotEffect {
if (card.getConvertedManaCost() % 2 == 1) {
if (player.chooseUse(outcome, "Cast " + card.getLogName() + " without paying its mana cost?", source, game)) {
player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
+ } else {
+ /*
+ 7/13/2018 | If the revealed card doesn’t have an odd converted mana cost or if that card does but you
+ choose not to cast it, you draw a card. Keep in mind that revealing a card doesn’t cause it to change
+ zones. This means that the card you draw will be the card you revealed.
+ */
+ player.drawCards(1, game);
}
} else {
player.drawCards(1, game);
diff --git a/Mage.Sets/src/mage/cards/y/YoreTillerNephilim.java b/Mage.Sets/src/mage/cards/y/YoreTillerNephilim.java
index fab802d749d..107995d4513 100644
--- a/Mage.Sets/src/mage/cards/y/YoreTillerNephilim.java
+++ b/Mage.Sets/src/mage/cards/y/YoreTillerNephilim.java
@@ -1,4 +1,3 @@
-
package mage.cards.y;
import java.util.UUID;
@@ -13,7 +12,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -33,7 +32,7 @@ public final class YoreTillerNephilim extends CardImpl {
// Whenever Yore-Tiller Nephilim attacks, return target creature card from your graveyard to the battlefield tapped and attacking.
Ability ability = new AttacksTriggeredAbility(new YoreTillerNephilimEffect(), false);
- ability.addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard()));
+ ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/y/YorvoLordOfGarenbrig.java b/Mage.Sets/src/mage/cards/y/YorvoLordOfGarenbrig.java
new file mode 100644
index 00000000000..d9cdc571ff4
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/y/YorvoLordOfGarenbrig.java
@@ -0,0 +1,101 @@
+package mage.cards.y;
+
+import mage.MageInt;
+import mage.ObjectColor;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.counters.CounterType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.ColorPredicate;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class YorvoLordOfGarenbrig extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterCreaturePermanent();
+
+ static {
+ filter.add(AnotherPredicate.instance);
+ filter.add(new ColorPredicate(ObjectColor.GREEN));
+ }
+
+ public YorvoLordOfGarenbrig(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{G}{G}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.GIANT);
+ this.subtype.add(SubType.NOBLE);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(0);
+
+ // Yorvo, Lord of Garenbrig enters the battlefield with four +1/+1 counters on it.
+ this.addAbility(new EntersBattlefieldAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance(4)),
+ "{this} enters the battlefield with four +1/+1 counters on it"
+ ));
+
+ // Whenever another green creature enters the battlefield under your control, put a +1/+1 counter on Yorvo. Then if that creature's power is greater than Yorvo's power, put another +1/+1 counter on Yorvo.
+ this.addAbility(new EntersBattlefieldControlledTriggeredAbility(
+ Zone.BATTLEFIELD, new YorvoLordOfGarenbrigEffect(), filter, false, SetTargetPointer.PERMANENT,
+ "Whenever another green creature enters the battlefield under your control, " +
+ "put a +1/+1 counter on {this}. Then if that creature's power is greater than {this}'s power, " +
+ "put another +1/+1 counter on {this}."
+ ));
+ }
+
+ private YorvoLordOfGarenbrig(final YorvoLordOfGarenbrig card) {
+ super(card);
+ }
+
+ @Override
+ public YorvoLordOfGarenbrig copy() {
+ return new YorvoLordOfGarenbrig(this);
+ }
+}
+
+class YorvoLordOfGarenbrigEffect extends OneShotEffect {
+
+ YorvoLordOfGarenbrigEffect() {
+ super(Outcome.Benefit);
+ }
+
+ private YorvoLordOfGarenbrigEffect(final YorvoLordOfGarenbrigEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public YorvoLordOfGarenbrigEffect copy() {
+ return new YorvoLordOfGarenbrigEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent sourcePerm = game.getPermanent(source.getSourceId());
+ if (sourcePerm == null) {
+ return false;
+ }
+ sourcePerm.addCounters(CounterType.P1P1.createInstance(), source, game);
+ Permanent permanent = game.getPermanentOrLKIBattlefield(targetPointer.getFirst(game, source));
+ if (permanent == null) {
+ return true;
+ }
+ game.applyEffects();
+ if (permanent.getPower().getValue() > sourcePerm.getPower().getValue()) {
+ sourcePerm.addCounters(CounterType.P1P1.createInstance(), source, game);
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/z/ZadaHedronGrinder.java b/Mage.Sets/src/mage/cards/z/ZadaHedronGrinder.java
index 7b76cdcb2f4..651b84fdddf 100644
--- a/Mage.Sets/src/mage/cards/z/ZadaHedronGrinder.java
+++ b/Mage.Sets/src/mage/cards/z/ZadaHedronGrinder.java
@@ -1,23 +1,23 @@
-
package mage.cards.z;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
-import mage.abilities.Mode;
import mage.abilities.TriggeredAbilityImpl;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CopySpellForEachItCouldTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
-import mage.filter.StaticFilters;
+import mage.filter.FilterInPlay;
+import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
+import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.Target;
-import mage.target.targetpointer.FixedTarget;
+import mage.util.TargetAddress;
/**
*
@@ -32,7 +32,9 @@ public final class ZadaHedronGrinder extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(3);
- // Whenever you cast an instant or sorcery spell that targets only Zada, Hedron Grinder, copy that spell for each other creature you control that the spell could target. Each copy targets a different one of those creatures.
+ // Whenever you cast an instant or sorcery spell that targets only Zada, Hedron Grinder,
+ // copy that spell for each other creature you control that the spell could target.
+ // Each copy targets a different one of those creatures.
this.addAbility(new ZadaHedronGrinderTriggeredAbility());
}
@@ -50,7 +52,7 @@ public final class ZadaHedronGrinder extends CardImpl {
class ZadaHedronGrinderTriggeredAbility extends TriggeredAbilityImpl {
ZadaHedronGrinderTriggeredAbility() {
- super(Zone.BATTLEFIELD, new ZadaHedronGrinderEffect(), false);
+ super(Zone.BATTLEFIELD, new ZadaHedronGrinderCopySpellEffect(), false);
}
ZadaHedronGrinderTriggeredAbility(final ZadaHedronGrinderTriggeredAbility ability) {
@@ -64,120 +66,108 @@ class ZadaHedronGrinderTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkEventType(GameEvent event, Game game) {
- return event.getType() == GameEvent.EventType.SPELL_CAST;
+ return event.getType() == EventType.SPELL_CAST;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
- if (event.getPlayerId().equals(this.getControllerId())) {
- Spell spell = game.getStack().getSpell(event.getTargetId());
- if (isControlledInstantOrSorcery(spell)) {
- boolean targetsSource = false;
- for (Ability ability : spell.getSpellAbilities()) {
- for (UUID modeId : ability.getModes().getSelectedModes()) {
- Mode mode = ability.getModes().get(modeId);
- for (Target target : mode.getTargets()) {
- if (!target.isNotTarget()) {
- for (UUID targetId : target.getTargets()) {
- if (targetId.equals(getSourceId())) {
- targetsSource = true;
- } else {
- return false;
- }
+ Spell spell = game.getStack().getSpell(event.getTargetId());
+ return checkSpell(spell, game)
+ && event.getPlayerId().equals(controllerId);
+ }
+
+ private boolean checkSpell(Spell spell, Game game) {
+ if (spell != null
+ && (spell.isInstant()
+ || spell.isSorcery())) {
+ boolean noTargets = true;
+ for (TargetAddress addr : TargetAddress.walk(spell)) {
+ if (addr != null) {
+ noTargets = false;
+ Target targetInstance = addr.getTarget(spell);
+ if (targetInstance != null) {
+ for (UUID target : targetInstance.getTargets()) {
+ if (target != null) {
+ Permanent permanent = game.getPermanent(target);
+ if (permanent == null
+ || !permanent.getId().equals(getSourceId())) {
+ return false;
}
}
}
}
}
- if (targetsSource) {
- this.getEffects().get(0).setTargetPointer(new FixedTarget(spell.getId()));
- return true;
- }
}
- }
- return false;
- }
-
- private boolean isControlledInstantOrSorcery(Spell spell) {
- return spell != null
- && (spell.isControlledBy(this.getControllerId()))
- && (spell.isInstant() || spell.isSorcery());
- }
-
- @Override
- public String getRule() {
- return "Whenever you cast an instant or sorcery spell that targets only {this}, copy that spell for each other creature you control that the spell could target. Each copy targets a different one of those creatures.";
- }
-}
-
-class ZadaHedronGrinderEffect extends OneShotEffect {
-
- public ZadaHedronGrinderEffect() {
- super(Outcome.Detriment);
- this.staticText = "copy that spell for each other creature you control that the spell could target. Each copy targets a different one of those creatures";
- }
-
- public ZadaHedronGrinderEffect(final ZadaHedronGrinderEffect effect) {
- super(effect);
- }
-
- @Override
- public ZadaHedronGrinderEffect copy() {
- return new ZadaHedronGrinderEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source));
- Player controller = game.getPlayer(source.getControllerId());
- if (spell != null && controller != null) {
- // search the target that targets source
- Target usedTarget = null;
- setUsedTarget:
- for (Ability ability : spell.getSpellAbilities()) {
- for (UUID modeId : ability.getModes().getSelectedModes()) {
- Mode mode = ability.getModes().get(modeId);
- for (Target target : mode.getTargets()) {
- if (!target.isNotTarget() && target.getFirstTarget().equals(source.getSourceId())) {
- usedTarget = target.copy();
- usedTarget.clearChosen();
- break setUsedTarget;
- }
- }
- }
- }
- if (usedTarget == null) {
+ if (noTargets) {
return false;
}
- for (Permanent creature : game.getState().getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game)) {
- if (!creature.getId().equals(source.getSourceId()) && usedTarget.canTarget(source.getControllerId(), creature.getId(), source, game)) {
- Spell copy = spell.copySpell(source.getControllerId());
- game.getStack().push(copy);
- setTarget:
- for (UUID modeId : copy.getSpellAbility().getModes().getSelectedModes()) {
- Mode mode = copy.getSpellAbility().getModes().get(modeId);
- for (Target target : mode.getTargets()) {
- if (target.getClass().equals(usedTarget.getClass())) {
- target.clearChosen(); // For targets with Max > 1 we need to clear before the text is comapred
- if (target.getMessage().equals(usedTarget.getMessage())) {
- target.addTarget(creature.getId(), copy.getSpellAbility(), game, false);
- break setTarget;
- }
- }
- }
- }
- game.fireEvent(new GameEvent(GameEvent.EventType.COPIED_STACKOBJECT, copy.getId(), spell.getId(), source.getControllerId()));
- String activateMessage = copy.getActivatedMessage(game);
- if (activateMessage.startsWith(" casts ")) {
- activateMessage = activateMessage.substring(6);
- }
- if (!game.isSimulation()) {
- game.informPlayers(controller.getLogName() + activateMessage);
- }
- }
- }
+ getEffects().get(0).setValue("triggeringSpell", spell);
return true;
}
return false;
}
+
+ @Override
+ public String getRule() {
+ return "Whenever you cast an instant or sorcery spell that targets only {this}, "
+ + "copy that spell for each other creature you control that the spell could target. "
+ + "Each copy targets a different one of those creatures.";
+ }
+}
+
+class ZadaHedronGrinderCopySpellEffect extends CopySpellForEachItCouldTargetEffect {
+
+ public ZadaHedronGrinderCopySpellEffect() {
+ this(new FilterControlledCreaturePermanent());
+ this.staticText = "copy that spell for each other creature you control "
+ + "that the spell could target. Each copy targets a different one of those creatures.";
+ }
+
+ public ZadaHedronGrinderCopySpellEffect(ZadaHedronGrinderCopySpellEffect effect) {
+ super(effect);
+ }
+
+ private ZadaHedronGrinderCopySpellEffect(FilterInPlay filter) {
+ super(filter);
+ }
+
+ @Override
+ protected Player getPlayer(Game game, Ability source) {
+ Spell spell = getSpell(game, source);
+ if (spell != null) {
+ return game.getPlayer(spell.getControllerId());
+ }
+ return null;
+ }
+
+ @Override
+ protected Spell getSpell(Game game, Ability source) {
+ return (Spell) getValue("triggeringSpell");
+ }
+
+ @Override
+ protected boolean changeTarget(Target target, Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ protected void modifyCopy(Spell copy, Game game, Ability source) {
+ Spell spell = getSpell(game, source);
+ copy.setControllerId(spell.getControllerId());
+ }
+
+ @Override
+ protected boolean okUUIDToCopyFor(UUID potentialTarget, Game game, Ability source, Spell spell) {
+ Permanent permanent = game.getPermanent(potentialTarget);
+ if (permanent == null
+ || !permanent.isControlledBy(spell.getControllerId())) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public ZadaHedronGrinderCopySpellEffect copy() {
+ return new ZadaHedronGrinderCopySpellEffect(this);
+ }
}
diff --git a/Mage.Sets/src/mage/cards/z/ZamWesell.java b/Mage.Sets/src/mage/cards/z/ZamWesell.java
index bc9d2fac4bd..7a9b511c27f 100644
--- a/Mage.Sets/src/mage/cards/z/ZamWesell.java
+++ b/Mage.Sets/src/mage/cards/z/ZamWesell.java
@@ -1,4 +1,3 @@
-
package mage.cards.z;
import java.util.UUID;
@@ -12,7 +11,7 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
-import mage.filter.common.FilterCreatureCard;
+import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
@@ -70,7 +69,7 @@ class ZamWesselEffect extends OneShotEffect {
if (controller != null) {
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
if (targetPlayer != null) {
- TargetCard targetCard = new TargetCard(0, 1, Zone.HAND, new FilterCreatureCard());
+ TargetCard targetCard = new TargetCard(0, 1, Zone.HAND, StaticFilters.FILTER_CARD_CREATURE);
controller.choose(outcome, targetPlayer.getHand(), targetCard, game);
Card copyFromCard = game.getCard(targetCard.getFirstTarget());
if (copyFromCard != null) {
diff --git a/Mage.Sets/src/mage/cards/z/ZursWeirding.java b/Mage.Sets/src/mage/cards/z/ZursWeirding.java
index 655ae2118f4..df49f02d4c5 100644
--- a/Mage.Sets/src/mage/cards/z/ZursWeirding.java
+++ b/Mage.Sets/src/mage/cards/z/ZursWeirding.java
@@ -33,7 +33,7 @@ public final class ZursWeirding extends CardImpl {
// Players play with their hands revealed.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayWithHandRevealedEffect(TargetController.ANY)));
- // If a player would draw a card, he or she reveals it instead. Then any other player may pay 2 life. If a player does, put that card into its owner's graveyard. Otherwise, that player draws a card.
+ // If a player would draw a card, they reveal it instead. Then any other player may pay 2 life. If a player does, put that card into its owner's graveyard. Otherwise, that player draws a card.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ZursWeirdingReplacementEffect()));
}
@@ -51,7 +51,7 @@ class ZursWeirdingReplacementEffect extends ReplacementEffectImpl {
public ZursWeirdingReplacementEffect() {
super(Duration.WhileOnBattlefield, Outcome.Neutral);
- this.staticText = "If a player would draw a card, he or she reveals it instead. Then any other player may pay 2 life. If a player does, put that card into its owner's graveyard. Otherwise, that player draws a card.";
+ this.staticText = "If a player would draw a card, they reveal it instead. Then any other player may pay 2 life. If a player does, put that card into its owner's graveyard. Otherwise, that player draws a card.";
}
public ZursWeirdingReplacementEffect(final ZursWeirdingReplacementEffect effect) {
diff --git a/Mage.Sets/src/mage/sets/AetherRevolt.java b/Mage.Sets/src/mage/sets/AetherRevolt.java
index e16c052f5da..30d7542c51a 100644
--- a/Mage.Sets/src/mage/sets/AetherRevolt.java
+++ b/Mage.Sets/src/mage/sets/AetherRevolt.java
@@ -22,7 +22,7 @@ public final class AetherRevolt extends ExpansionSet {
return instance;
}
- protected final List savedSpecialLand = new ArrayList<>();
+ private final List savedSpecialLand = new ArrayList<>();
private AetherRevolt() {
super("Aether Revolt", "AER", ExpansionSet.buildDate(2017, 1, 20), SetType.EXPANSION);
diff --git a/Mage.Sets/src/mage/sets/Amonkhet.java b/Mage.Sets/src/mage/sets/Amonkhet.java
index f72f4af451f..dd916747732 100644
--- a/Mage.Sets/src/mage/sets/Amonkhet.java
+++ b/Mage.Sets/src/mage/sets/Amonkhet.java
@@ -23,7 +23,7 @@ public final class Amonkhet extends ExpansionSet {
return instance;
}
- protected final List savedSpecialLand = new ArrayList<>();
+ private final List savedSpecialLand = new ArrayList<>();
private Amonkhet() {
super("Amonkhet", "AKH", ExpansionSet.buildDate(2017, 4, 28), SetType.EXPANSION);
diff --git a/Mage.Sets/src/mage/sets/Apocalypse.java b/Mage.Sets/src/mage/sets/Apocalypse.java
index e327b2f80cf..787c55c20ab 100644
--- a/Mage.Sets/src/mage/sets/Apocalypse.java
+++ b/Mage.Sets/src/mage/sets/Apocalypse.java
@@ -66,6 +66,7 @@ public final class Apocalypse extends ExpansionSet {
cards.add(new SetCardInfo("Flowstone Charger", 99, Rarity.UNCOMMON, mage.cards.f.FlowstoneCharger.class));
cards.add(new SetCardInfo("Foul Presence", 39, Rarity.UNCOMMON, mage.cards.f.FoulPresence.class));
cards.add(new SetCardInfo("Fungal Shambler", 100, Rarity.RARE, mage.cards.f.FungalShambler.class));
+ cards.add(new SetCardInfo("Gaea's Balance", 77, Rarity.UNCOMMON, mage.cards.g.GaeasBalance.class));
cards.add(new SetCardInfo("Gaea's Skyfolk", 101, Rarity.COMMON, mage.cards.g.GaeasSkyfolk.class));
cards.add(new SetCardInfo("Gerrard Capashen", 11, Rarity.RARE, mage.cards.g.GerrardCapashen.class));
cards.add(new SetCardInfo("Gerrard's Verdict", 102, Rarity.UNCOMMON, mage.cards.g.GerrardsVerdict.class));
diff --git a/Mage.Sets/src/mage/sets/BattleForZendikar.java b/Mage.Sets/src/mage/sets/BattleForZendikar.java
index ff90d62d61f..d12ac8e78b1 100644
--- a/Mage.Sets/src/mage/sets/BattleForZendikar.java
+++ b/Mage.Sets/src/mage/sets/BattleForZendikar.java
@@ -21,7 +21,7 @@ public final class BattleForZendikar extends ExpansionSet {
return instance;
}
- protected final List savedSpecialLand = new ArrayList<>();
+ private final List savedSpecialLand = new ArrayList<>();
private BattleForZendikar() {
super("Battle for Zendikar", "BFZ", ExpansionSet.buildDate(2015, 10, 2), SetType.EXPANSION);
diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java
index e01ffafdef3..881718498c4 100644
--- a/Mage.Sets/src/mage/sets/Battlebond.java
+++ b/Mage.Sets/src/mage/sets/Battlebond.java
@@ -15,7 +15,6 @@ public final class Battlebond extends ExpansionSet {
return instance;
}
-
private Battlebond() {
super("Battlebond", "BBD", ExpansionSet.buildDate(2018, 6, 8), SetType.SUPPLEMENTAL);
this.blockName = "Battlebond";
@@ -28,6 +27,8 @@ public final class Battlebond extends ExpansionSet {
this.numBoosterRare = 1;
this.ratioBoosterMythic = 8;
+ this.maxCardNumberInBooster = 254; // Don't use the 2 foil mystics copies because it would influence a random ratio
+
cards.add(new SetCardInfo("Aim High", 189, Rarity.UNCOMMON, mage.cards.a.AimHigh.class));
cards.add(new SetCardInfo("Angel of Retribution", 86, Rarity.UNCOMMON, mage.cards.a.AngelOfRetribution.class));
cards.add(new SetCardInfo("Angelic Chorus", 87, Rarity.RARE, mage.cards.a.AngelicChorus.class));
diff --git a/Mage.Sets/src/mage/sets/Commander2018Edition.java b/Mage.Sets/src/mage/sets/Commander2018Edition.java
index ac3896c8017..073f6299fa8 100644
--- a/Mage.Sets/src/mage/sets/Commander2018Edition.java
+++ b/Mage.Sets/src/mage/sets/Commander2018Edition.java
@@ -27,7 +27,7 @@ public final class Commander2018Edition extends ExpansionSet {
cards.add(new SetCardInfo("Akoum Refuge", 231, Rarity.UNCOMMON, mage.cards.a.AkoumRefuge.class));
cards.add(new SetCardInfo("Akroma's Vengeance", 62, Rarity.RARE, mage.cards.a.AkromasVengeance.class));
cards.add(new SetCardInfo("Aminatou's Augury", 6, Rarity.RARE, mage.cards.a.AminatousAugury.class));
- cards.add(new SetCardInfo("Aminatou, the Fateshifter", 37, Rarity.MYTHIC, mage.cards.a.AminatouTheFateShifter.class));
+ cards.add(new SetCardInfo("Aminatou, the Fateshifter", 37, Rarity.MYTHIC, mage.cards.a.AminatouTheFateshifter.class));
cards.add(new SetCardInfo("Ancient Stone Idol", 53, Rarity.RARE, mage.cards.a.AncientStoneIdol.class));
cards.add(new SetCardInfo("Arcane Sanctum", 232, Rarity.UNCOMMON, mage.cards.a.ArcaneSanctum.class));
cards.add(new SetCardInfo("Archetype of Imagination", 81, Rarity.UNCOMMON, mage.cards.a.ArchetypeOfImagination.class));
diff --git a/Mage.Sets/src/mage/sets/Commander2019Edition.java b/Mage.Sets/src/mage/sets/Commander2019Edition.java
index 3b6c32b3b6c..3b82f0ab895 100644
--- a/Mage.Sets/src/mage/sets/Commander2019Edition.java
+++ b/Mage.Sets/src/mage/sets/Commander2019Edition.java
@@ -54,6 +54,7 @@ public final class Commander2019Edition extends ExpansionSet {
cards.add(new SetCardInfo("Burning Vengeance", 135, Rarity.UNCOMMON, mage.cards.b.BurningVengeance.class));
cards.add(new SetCardInfo("Burnished Hart", 211, Rarity.UNCOMMON, mage.cards.b.BurnishedHart.class));
cards.add(new SetCardInfo("Call to the Netherworld", 108, Rarity.COMMON, mage.cards.c.CallToTheNetherworld.class));
+ cards.add(new SetCardInfo("Chainer, Nightmare Adept", 39, Rarity.MYTHIC, mage.cards.c.ChainerNightmareAdept.class));
cards.add(new SetCardInfo("Champion of Stray Souls", 109, Rarity.MYTHIC, mage.cards.c.ChampionOfStraySouls.class));
cards.add(new SetCardInfo("Chaos Warp", 136, Rarity.RARE, mage.cards.c.ChaosWarp.class));
cards.add(new SetCardInfo("Chemister's Insight", 80, Rarity.UNCOMMON, mage.cards.c.ChemistersInsight.class));
@@ -90,6 +91,7 @@ public final class Commander2019Edition extends ExpansionSet {
cards.add(new SetCardInfo("Elemental Bond", 163, Rarity.UNCOMMON, mage.cards.e.ElementalBond.class));
cards.add(new SetCardInfo("Elsha of the Infinite", 40, Rarity.MYTHIC, mage.cards.e.ElshaOfTheInfinite.class));
cards.add(new SetCardInfo("Emmara Tandris", 191, Rarity.RARE, mage.cards.e.EmmaraTandris.class));
+ cards.add(new SetCardInfo("Empowered Autogenerator", 54, Rarity.RARE, mage.cards.e.EmpoweredAutogenerator.class));
cards.add(new SetCardInfo("Evolving Wilds", 241, Rarity.COMMON, mage.cards.e.EvolvingWilds.class));
cards.add(new SetCardInfo("Exotic Orchard", 242, Rarity.RARE, mage.cards.e.ExoticOrchard.class));
cards.add(new SetCardInfo("Explore", 164, Rarity.COMMON, mage.cards.e.Explore.class));
@@ -158,6 +160,7 @@ public final class Commander2019Edition extends ExpansionSet {
cards.add(new SetCardInfo("Jace's Sanctum", 88, Rarity.RARE, mage.cards.j.JacesSanctum.class));
cards.add(new SetCardInfo("Jungle Hollow", 254, Rarity.COMMON, mage.cards.j.JungleHollow.class));
cards.add(new SetCardInfo("Jungle Shrine", 255, Rarity.UNCOMMON, mage.cards.j.JungleShrine.class));
+ cards.add(new SetCardInfo("K'rrik, Son of Yawgmoth", 18, Rarity.RARE, mage.cards.k.KrrikSonOfYawgmoth.class));
cards.add(new SetCardInfo("Kadena's Silencer", 8, Rarity.RARE, mage.cards.k.KadenasSilencer.class));
cards.add(new SetCardInfo("Kadena, Slinking Sorcerer", 45, Rarity.MYTHIC, mage.cards.k.KadenaSlinkingSorcerer.class));
cards.add(new SetCardInfo("Kazandu Refuge", 256, Rarity.UNCOMMON, mage.cards.k.KazanduRefuge.class));
@@ -170,6 +173,7 @@ public final class Commander2019Edition extends ExpansionSet {
cards.add(new SetCardInfo("Magmaquake", 148, Rarity.RARE, mage.cards.m.Magmaquake.class));
cards.add(new SetCardInfo("Magus of the Wheel", 149, Rarity.RARE, mage.cards.m.MagusOfTheWheel.class));
cards.add(new SetCardInfo("Malevolent Whispers", 150, Rarity.UNCOMMON, mage.cards.m.MalevolentWhispers.class));
+ cards.add(new SetCardInfo("Mandate of Peace", 4, Rarity.RARE, mage.cards.m.MandateOfPeace.class));
cards.add(new SetCardInfo("Marisi, Breaker of the Coil", 46, Rarity.MYTHIC, mage.cards.m.MarisiBreakerOfTheCoil.class));
cards.add(new SetCardInfo("Mass Diminish", 10, Rarity.RARE, mage.cards.m.MassDiminish.class));
cards.add(new SetCardInfo("Memorial to Folly", 259, Rarity.UNCOMMON, mage.cards.m.MemorialToFolly.class));
@@ -258,6 +262,7 @@ public final class Commander2019Edition extends ExpansionSet {
cards.add(new SetCardInfo("Stratus Dancer", 96, Rarity.RARE, mage.cards.s.StratusDancer.class));
cards.add(new SetCardInfo("Strionic Resonator", 224, Rarity.RARE, mage.cards.s.StrionicResonator.class));
cards.add(new SetCardInfo("Stromkirk Occultist", 153, Rarity.RARE, mage.cards.s.StromkirkOccultist.class));
+ cards.add(new SetCardInfo("Sudden Substitution", 11, Rarity.RARE, mage.cards.s.SuddenSubstitution.class));
cards.add(new SetCardInfo("Sultai Charm", 202, Rarity.UNCOMMON, mage.cards.s.SultaiCharm.class));
cards.add(new SetCardInfo("Sun Titan", 76, Rarity.MYTHIC, mage.cards.s.SunTitan.class));
cards.add(new SetCardInfo("Sundering Growth", 203, Rarity.COMMON, mage.cards.s.SunderingGrowth.class));
@@ -265,6 +270,7 @@ public final class Commander2019Edition extends ExpansionSet {
cards.add(new SetCardInfo("Sunken Hollow", 278, Rarity.RARE, mage.cards.s.SunkenHollow.class));
cards.add(new SetCardInfo("Swamp", 294, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Swiftwater Cliffs", 279, Rarity.COMMON, mage.cards.s.SwiftwaterCliffs.class));
+ cards.add(new SetCardInfo("Tahngarth, First Mate", 50, Rarity.RARE, mage.cards.t.TahngarthFirstMate.class));
cards.add(new SetCardInfo("Talrand, Sky Summoner", 97, Rarity.RARE, mage.cards.t.TalrandSkySummoner.class));
cards.add(new SetCardInfo("Tectonic Hellion", 29, Rarity.RARE, mage.cards.t.TectonicHellion.class));
cards.add(new SetCardInfo("Temple of the False God", 280, Rarity.UNCOMMON, mage.cards.t.TempleOfTheFalseGod.class));
@@ -293,8 +299,10 @@ public final class Commander2019Edition extends ExpansionSet {
cards.add(new SetCardInfo("Voice of Many", 36, Rarity.UNCOMMON, mage.cards.v.VoiceOfMany.class));
cards.add(new SetCardInfo("Volrath, the Shapestealer", 51, Rarity.MYTHIC, mage.cards.v.VolrathTheShapestealer.class));
cards.add(new SetCardInfo("Vraska the Unseen", 207, Rarity.MYTHIC, mage.cards.v.VraskaTheUnseen.class));
+ cards.add(new SetCardInfo("Wall of Stolen Identity", 13, Rarity.RARE, mage.cards.w.WallOfStolenIdentity.class));
cards.add(new SetCardInfo("Warstorm Surge", 155, Rarity.RARE, mage.cards.w.WarstormSurge.class));
cards.add(new SetCardInfo("Wayfaring Temple", 208, Rarity.RARE, mage.cards.w.WayfaringTemple.class));
+ cards.add(new SetCardInfo("Wildfire Devils", 30, Rarity.RARE, mage.cards.w.WildfireDevils.class));
cards.add(new SetCardInfo("Willbender", 102, Rarity.UNCOMMON, mage.cards.w.Willbender.class));
cards.add(new SetCardInfo("Wind-Scarred Crag", 285, Rarity.COMMON, mage.cards.w.WindScarredCrag.class));
cards.add(new SetCardInfo("Wingmate Roc", 78, Rarity.MYTHIC, mage.cards.w.WingmateRoc.class));
diff --git a/Mage.Sets/src/mage/sets/CoreSet2019.java b/Mage.Sets/src/mage/sets/CoreSet2019.java
index 132743ef002..bb7cb7ef76d 100644
--- a/Mage.Sets/src/mage/sets/CoreSet2019.java
+++ b/Mage.Sets/src/mage/sets/CoreSet2019.java
@@ -1,9 +1,7 @@
package mage.sets;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
-import mage.cards.Card;
import mage.cards.ExpansionSet;
import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo;
@@ -23,8 +21,8 @@ public final class CoreSet2019 extends ExpansionSet {
public static CoreSet2019 getInstance() {
return instance;
}
- List savedSpecialCommon = new ArrayList<>();
- protected final List savedSpecialLand = new ArrayList<>();
+
+ private final List savedSpecialLand = new ArrayList<>();
private CoreSet2019() {
super("Core Set 2019", "M19", ExpansionSet.buildDate(2018, 7, 13), SetType.CORE);
@@ -372,7 +370,7 @@ public final class CoreSet2019 extends ExpansionSet {
criteria.setCodes(this.code).notTypes(CardType.LAND);
savedCardsInfos = CardRepository.instance.findCards(criteria);
if (maxCardNumberInBooster != Integer.MAX_VALUE) {
- savedCardsInfos.removeIf(next -> next.getCardNumberAsInt() > maxCardNumberInBooster && rarity != Rarity.LAND);
+ savedCardsInfos.removeIf(next -> next.getCardNumberAsInt() > maxCardNumberInBooster);
}
savedCards.put(rarity, savedCardsInfos);
}
diff --git a/Mage.Sets/src/mage/sets/CoreSet2020.java b/Mage.Sets/src/mage/sets/CoreSet2020.java
index 8c04f68cf6d..dc5db516acd 100644
--- a/Mage.Sets/src/mage/sets/CoreSet2020.java
+++ b/Mage.Sets/src/mage/sets/CoreSet2020.java
@@ -22,7 +22,6 @@ public final class CoreSet2020 extends ExpansionSet {
return instance;
}
- private final List savedSpecialCommon = new ArrayList<>();
private final List savedSpecialLand = new ArrayList<>();
private CoreSet2020() {
@@ -399,7 +398,7 @@ public final class CoreSet2020 extends ExpansionSet {
criteria.setCodes(this.code).notTypes(CardType.LAND);
savedCardsInfos = CardRepository.instance.findCards(criteria);
if (maxCardNumberInBooster != Integer.MAX_VALUE) {
- savedCardsInfos.removeIf(next -> next.getCardNumberAsInt() > maxCardNumberInBooster && rarity != Rarity.LAND);
+ savedCardsInfos.removeIf(next -> next.getCardNumberAsInt() > maxCardNumberInBooster);
}
savedCards.put(rarity, savedCardsInfos);
}
diff --git a/Mage.Sets/src/mage/sets/Dissension.java b/Mage.Sets/src/mage/sets/Dissension.java
index 3aabb0d2cee..0b1ca438402 100644
--- a/Mage.Sets/src/mage/sets/Dissension.java
+++ b/Mage.Sets/src/mage/sets/Dissension.java
@@ -33,7 +33,7 @@ public final class Dissension extends ExpansionSet {
cards.add(new SetCardInfo("Assault Zeppelid", 103, Rarity.COMMON, mage.cards.a.AssaultZeppelid.class));
cards.add(new SetCardInfo("Aurora Eidolon", 1, Rarity.COMMON, mage.cards.a.AuroraEidolon.class));
cards.add(new SetCardInfo("Avatar of Discord", 140, Rarity.RARE, mage.cards.a.AvatarOfDiscord.class));
- cards.add(new SetCardInfo("Azorius Aethermage", 104, Rarity.UNCOMMON, mage.cards.a.AzoriusAEthermage.class));
+ cards.add(new SetCardInfo("Azorius Aethermage", 104, Rarity.UNCOMMON, mage.cards.a.AzoriusAethermage.class));
cards.add(new SetCardInfo("Azorius Chancery", 170, Rarity.COMMON, mage.cards.a.AzoriusChancery.class));
cards.add(new SetCardInfo("Azorius First-Wing", 105, Rarity.COMMON, mage.cards.a.AzoriusFirstWing.class));
cards.add(new SetCardInfo("Azorius Guildmage", 141, Rarity.UNCOMMON, mage.cards.a.AzoriusGuildmage.class));
diff --git a/Mage.Sets/src/mage/sets/DragonsMaze.java b/Mage.Sets/src/mage/sets/DragonsMaze.java
index 8e01820b2a5..ab778d037a7 100644
--- a/Mage.Sets/src/mage/sets/DragonsMaze.java
+++ b/Mage.Sets/src/mage/sets/DragonsMaze.java
@@ -23,10 +23,10 @@ public final class DragonsMaze extends ExpansionSet {
return instance;
}
- List savedSpecialRares = new ArrayList<>();
+ private List savedSpecialRares = new ArrayList<>();
private DragonsMaze() {
- super("Dragon's Maze", "DGM", ExpansionSet.buildDate(2013, 5, 03), SetType.EXPANSION);
+ super("Dragon's Maze", "DGM", ExpansionSet.buildDate(2013, 5, 3), SetType.EXPANSION);
this.blockName = "Return to Ravnica";
this.hasBoosters = true;
this.numBoosterSpecial = 1;
@@ -204,7 +204,7 @@ public final class DragonsMaze extends ExpansionSet {
criteria.rarities(rarity).doubleFaced(false);
savedCardsInfos = CardRepository.instance.findCards(criteria);
if (maxCardNumberInBooster != Integer.MAX_VALUE) {
- savedCardsInfos.removeIf(next -> next.getCardNumberAsInt() > maxCardNumberInBooster && rarity != Rarity.LAND);
+ savedCardsInfos.removeIf(next -> next.getCardNumberAsInt() > maxCardNumberInBooster);
}
savedCards.put(rarity, savedCardsInfos);
}
@@ -224,7 +224,6 @@ public final class DragonsMaze extends ExpansionSet {
@Override
public List getSpecialRare() {
- List specialRares = new ArrayList<>();
if (savedSpecialRares == null) {
CardCriteria criteria = new CardCriteria();
criteria.setCodes("GTC").name("Breeding Pool");
@@ -258,8 +257,7 @@ public final class DragonsMaze extends ExpansionSet {
criteria.setCodes("RTR").name("Temple Garden");
savedSpecialRares.addAll(CardRepository.instance.findCards(criteria));
}
- specialRares.addAll(savedSpecialRares);
- return specialRares;
+ return new ArrayList<>(savedSpecialRares);
}
@Override
diff --git a/Mage.Sets/src/mage/sets/DuelDecksDivineVsDemonic.java b/Mage.Sets/src/mage/sets/DuelDecksDivineVsDemonic.java
index 9ea0082a56a..cbf49424b25 100644
--- a/Mage.Sets/src/mage/sets/DuelDecksDivineVsDemonic.java
+++ b/Mage.Sets/src/mage/sets/DuelDecksDivineVsDemonic.java
@@ -16,7 +16,7 @@ public final class DuelDecksDivineVsDemonic extends ExpansionSet {
}
private DuelDecksDivineVsDemonic() {
- super("Duel Decks: Divine vs. Demonic", "DDC", ExpansionSet.buildDate(2009, 04, 10), SetType.SUPPLEMENTAL);
+ super("Duel Decks: Divine vs. Demonic", "DDC", ExpansionSet.buildDate(2009, 4, 10), SetType.SUPPLEMENTAL);
this.blockName = "Duel Decks";
this.hasBasicLands = true;
diff --git a/Mage.Sets/src/mage/sets/DuelDecksJaceVsChandra.java b/Mage.Sets/src/mage/sets/DuelDecksJaceVsChandra.java
index ba925a659df..1592d0482b4 100644
--- a/Mage.Sets/src/mage/sets/DuelDecksJaceVsChandra.java
+++ b/Mage.Sets/src/mage/sets/DuelDecksJaceVsChandra.java
@@ -21,7 +21,7 @@ public final class DuelDecksJaceVsChandra extends ExpansionSet {
}
private DuelDecksJaceVsChandra() {
- super("Duel Decks: Jace vs. Chandra", "DD2", ExpansionSet.buildDate(2008, 11, 07), SetType.SUPPLEMENTAL);
+ super("Duel Decks: Jace vs. Chandra", "DD2", ExpansionSet.buildDate(2008, 11, 7), SetType.SUPPLEMENTAL);
this.blockName = "Duel Decks";
this.hasBasicLands = true;
diff --git a/Mage.Sets/src/mage/sets/FateReforged.java b/Mage.Sets/src/mage/sets/FateReforged.java
index f29b7d81b36..3b6abc7104b 100644
--- a/Mage.Sets/src/mage/sets/FateReforged.java
+++ b/Mage.Sets/src/mage/sets/FateReforged.java
@@ -19,8 +19,8 @@ public final class FateReforged extends ExpansionSet {
private static final FateReforged instance = new FateReforged();
- List savedSpecialRares = new ArrayList<>();
- List savedSpecialCommon = new ArrayList<>();
+ private List savedSpecialRares = new ArrayList<>();
+ private List savedSpecialCommon = new ArrayList<>();
public static FateReforged getInstance() {
return instance;
@@ -238,7 +238,7 @@ public final class FateReforged extends ExpansionSet {
criteria.setCodes(this.code).notTypes(CardType.LAND);
savedCardsInfos = CardRepository.instance.findCards(criteria);
if (maxCardNumberInBooster != Integer.MAX_VALUE) {
- savedCardsInfos.removeIf(next -> next.getCardNumberAsInt() > maxCardNumberInBooster && rarity != Rarity.LAND);
+ savedCardsInfos.removeIf(next -> next.getCardNumberAsInt() > maxCardNumberInBooster);
}
savedCards.put(rarity, savedCardsInfos);
}
@@ -251,7 +251,6 @@ public final class FateReforged extends ExpansionSet {
@Override
public List getSpecialCommon() {
- List specialCommons = new ArrayList<>();
if (savedSpecialCommon.isEmpty()) {
// the 10 common lands from Fate Reforged can show up in the basic lands slot
// http://magic.wizards.com/en/articles/archive/feature/fetching-look-fate-reforged-2014-12-24
@@ -261,13 +260,11 @@ public final class FateReforged extends ExpansionSet {
criteria.rarities(Rarity.LAND).setCodes(this.code);
savedSpecialCommon.addAll(CardRepository.instance.findCards(criteria));
}
- specialCommons.addAll(savedSpecialCommon);
- return specialCommons;
+ return new ArrayList<>(savedSpecialCommon);
}
@Override
public List getSpecialRare() {
- List specialRares = new ArrayList<>();
if (savedSpecialRares.isEmpty()) {
CardCriteria criteria = new CardCriteria();
criteria.setCodes("KTK").name("Bloodstained Mire");
@@ -285,7 +282,6 @@ public final class FateReforged extends ExpansionSet {
criteria.setCodes("KTK").name("Wooded Foothills");
savedSpecialRares.addAll(CardRepository.instance.findCards(criteria));
}
- specialRares.addAll(savedSpecialRares);
- return specialRares;
+ return new ArrayList<>(savedSpecialRares);
}
}
diff --git a/Mage.Sets/src/mage/sets/GameNight2019.java b/Mage.Sets/src/mage/sets/GameNight2019.java
new file mode 100644
index 00000000000..ece39af0803
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/GameNight2019.java
@@ -0,0 +1,28 @@
+package mage.sets;
+
+import mage.cards.ExpansionSet;
+import mage.constants.Rarity;
+import mage.constants.SetType;
+
+/**
+ * @author TheElk801
+ */
+public final class GameNight2019 extends ExpansionSet {
+
+ private static final GameNight2019 instance = new GameNight2019();
+
+ public static GameNight2019 getInstance() {
+ return instance;
+ }
+
+ private GameNight2019() {
+ super("Game Night 2019", "GN2", ExpansionSet.buildDate(2019, 11, 15), SetType.SUPPLEMENTAL);
+ this.hasBasicLands = false; // TODO: change when spoiled
+
+ cards.add(new SetCardInfo("Calculating Lich", 3, Rarity.MYTHIC, mage.cards.c.CalculatingLich.class));
+ cards.add(new SetCardInfo("Earthshaker Giant", 5, Rarity.MYTHIC, mage.cards.e.EarthshakerGiant.class));
+ cards.add(new SetCardInfo("Fiendish Duo", 4, Rarity.MYTHIC, mage.cards.f.FiendishDuo.class));
+ cards.add(new SetCardInfo("Highcliff Felidar", 1, Rarity.MYTHIC, mage.cards.h.HighcliffFelidar.class));
+ cards.add(new SetCardInfo("Sphinx of Enlightenment", 2, Rarity.MYTHIC, mage.cards.s.SphinxOfEnlightenment.class));
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/HourOfDevastation.java b/Mage.Sets/src/mage/sets/HourOfDevastation.java
index 674806cd548..e0ec55cc55d 100644
--- a/Mage.Sets/src/mage/sets/HourOfDevastation.java
+++ b/Mage.Sets/src/mage/sets/HourOfDevastation.java
@@ -22,7 +22,7 @@ public final class HourOfDevastation extends ExpansionSet {
return instance;
}
- protected final List savedSpecialLand = new ArrayList<>();
+ private final List savedSpecialLand = new ArrayList<>();
private HourOfDevastation() {
super("Hour of Devastation", "HOU", ExpansionSet.buildDate(2017, 7, 14), SetType.EXPANSION);
diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java
index 5c0ab4bc858..1e22abab70c 100644
--- a/Mage.Sets/src/mage/sets/IceAge.java
+++ b/Mage.Sets/src/mage/sets/IceAge.java
@@ -32,6 +32,7 @@ public final class IceAge extends ExpansionSet {
cards.add(new SetCardInfo("Aggression", 169, Rarity.UNCOMMON, mage.cards.a.Aggression.class));
cards.add(new SetCardInfo("Altar of Bone", 281, Rarity.RARE, mage.cards.a.AltarOfBone.class));
cards.add(new SetCardInfo("Anarchy", 170, Rarity.UNCOMMON, mage.cards.a.Anarchy.class));
+ cards.add(new SetCardInfo("Arctic Foxes", 2, Rarity.COMMON, mage.cards.a.ArcticFoxes.class));
cards.add(new SetCardInfo("Arenson's Aura", 3, Rarity.COMMON, mage.cards.a.ArensonsAura.class));
cards.add(new SetCardInfo("Armor of Faith", 4, Rarity.COMMON, mage.cards.a.ArmorOfFaith.class));
cards.add(new SetCardInfo("Arnjlot's Ascent", 57, Rarity.COMMON, mage.cards.a.ArnjlotsAscent.class));
@@ -99,6 +100,7 @@ public final class IceAge extends ExpansionSet {
cards.add(new SetCardInfo("Elder Druid", 232, Rarity.RARE, mage.cards.e.ElderDruid.class));
cards.add(new SetCardInfo("Elemental Augury", 286, Rarity.RARE, mage.cards.e.ElementalAugury.class));
cards.add(new SetCardInfo("Elkin Bottle", 317, Rarity.RARE, mage.cards.e.ElkinBottle.class));
+ cards.add(new SetCardInfo("Elvish Healer", 22, Rarity.COMMON, mage.cards.e.ElvishHealer.class));
cards.add(new SetCardInfo("Enduring Renewal", 23, Rarity.RARE, mage.cards.e.EnduringRenewal.class));
cards.add(new SetCardInfo("Energy Storm", 24, Rarity.RARE, mage.cards.e.EnergyStorm.class));
cards.add(new SetCardInfo("Enervate", 67, Rarity.COMMON, mage.cards.e.Enervate.class));
@@ -106,6 +108,7 @@ public final class IceAge extends ExpansionSet {
cards.add(new SetCardInfo("Errantry", 183, Rarity.COMMON, mage.cards.e.Errantry.class));
cards.add(new SetCardInfo("Essence Filter", 233, Rarity.COMMON, mage.cards.e.EssenceFilter.class));
cards.add(new SetCardInfo("Essence Flare", 69, Rarity.COMMON, mage.cards.e.EssenceFlare.class));
+ cards.add(new SetCardInfo("Essence Vortex", 287, Rarity.UNCOMMON, mage.cards.e.EssenceVortex.class));
cards.add(new SetCardInfo("Fanatical Fever", 234, Rarity.UNCOMMON, mage.cards.f.FanaticalFever.class));
cards.add(new SetCardInfo("Fear", 124, Rarity.COMMON, mage.cards.f.Fear.class));
cards.add(new SetCardInfo("Fiery Justice", 288, Rarity.RARE, mage.cards.f.FieryJustice.class));
@@ -118,8 +121,6 @@ public final class IceAge extends ExpansionSet {
cards.add(new SetCardInfo("Forbidden Lore", 236, Rarity.RARE, mage.cards.f.ForbiddenLore.class));
cards.add(new SetCardInfo("Force Void", 70, Rarity.UNCOMMON, mage.cards.f.ForceVoid.class));
cards.add(new SetCardInfo("Forest", 380, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Forest", 381, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Forest", 382, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Forgotten Lore", 237, Rarity.UNCOMMON, mage.cards.f.ForgottenLore.class));
cards.add(new SetCardInfo("Formation", 25, Rarity.RARE, mage.cards.f.Formation.class));
cards.add(new SetCardInfo("Foul Familiar", 126, Rarity.COMMON, mage.cards.f.FoulFamiliar.class));
@@ -150,6 +151,7 @@ public final class IceAge extends ExpansionSet {
cards.add(new SetCardInfo("Gorilla Pack", 247, Rarity.COMMON, mage.cards.g.GorillaPack.class));
cards.add(new SetCardInfo("Gravebind", 129, Rarity.RARE, mage.cards.g.Gravebind.class));
cards.add(new SetCardInfo("Green Scarab", 28, Rarity.UNCOMMON, mage.cards.g.GreenScarab.class));
+ cards.add(new SetCardInfo("Grizzled Wolverine", 192, Rarity.COMMON, mage.cards.g.GrizzledWolverine.class));
cards.add(new SetCardInfo("Hallowed Ground", 29, Rarity.UNCOMMON, mage.cards.h.HallowedGround.class));
cards.add(new SetCardInfo("Halls of Mist", 354, Rarity.RARE, mage.cards.h.HallsOfMist.class));
cards.add(new SetCardInfo("Heal", 30, Rarity.COMMON, mage.cards.h.Heal.class));
@@ -309,6 +311,7 @@ public final class IceAge extends ExpansionSet {
cards.add(new SetCardInfo("Snow-Covered Mountain", 379, Rarity.LAND, mage.cards.s.SnowCoveredMountain.class));
cards.add(new SetCardInfo("Snow-Covered Plains", 367, Rarity.LAND, mage.cards.s.SnowCoveredPlains.class));
cards.add(new SetCardInfo("Snow-Covered Swamp", 372, Rarity.LAND, mage.cards.s.SnowCoveredSwamp.class));
+ cards.add(new SetCardInfo("Snowblind", 264, Rarity.RARE, mage.cards.s.Snowblind.class));
cards.add(new SetCardInfo("Soldevi Golem", 338, Rarity.RARE, mage.cards.s.SoldeviGolem.class));
cards.add(new SetCardInfo("Soldevi Machinist", 102, Rarity.UNCOMMON, mage.cards.s.SoldeviMachinist.class));
cards.add(new SetCardInfo("Soldevi Simulacrum", 339, Rarity.UNCOMMON, mage.cards.s.SoldeviSimulacrum.class));
diff --git a/Mage.Sets/src/mage/sets/IconicMasters.java b/Mage.Sets/src/mage/sets/IconicMasters.java
index b4dcaf5e24a..a211bac3865 100644
--- a/Mage.Sets/src/mage/sets/IconicMasters.java
+++ b/Mage.Sets/src/mage/sets/IconicMasters.java
@@ -1,4 +1,3 @@
-
package mage.sets;
import mage.cards.ExpansionSet;
@@ -6,7 +5,6 @@ import mage.constants.Rarity;
import mage.constants.SetType;
/**
- *
* @author MajorLazar
*/
public final class IconicMasters extends ExpansionSet {
@@ -28,255 +26,254 @@ public final class IconicMasters extends ExpansionSet {
this.numBoosterRare = 1;
this.ratioBoosterMythic = 8;
- cards.add(new SetCardInfo("Scion of Ugin", 1, Rarity.COMMON, mage.cards.s.ScionOfUgin.class));
+ cards.add(new SetCardInfo("Abyssal Persecutor", 78, Rarity.RARE, mage.cards.a.AbyssalPersecutor.class));
cards.add(new SetCardInfo("Abzan Battle Priest", 2, Rarity.UNCOMMON, mage.cards.a.AbzanBattlePriest.class));
cards.add(new SetCardInfo("Abzan Falconer", 3, Rarity.UNCOMMON, mage.cards.a.AbzanFalconer.class));
+ cards.add(new SetCardInfo("Aerial Predation", 154, Rarity.COMMON, mage.cards.a.AerialPredation.class));
+ cards.add(new SetCardInfo("Aether Vial", 212, Rarity.RARE, mage.cards.a.AetherVial.class));
+ cards.add(new SetCardInfo("Aetherize", 40, Rarity.UNCOMMON, mage.cards.a.Aetherize.class));
cards.add(new SetCardInfo("Ainok Bond-Kin", 4, Rarity.COMMON, mage.cards.a.AinokBondKin.class));
cards.add(new SetCardInfo("Ajani's Pridemate", 5, Rarity.UNCOMMON, mage.cards.a.AjanisPridemate.class));
+ cards.add(new SetCardInfo("Amass the Components", 41, Rarity.COMMON, mage.cards.a.AmassTheComponents.class));
+ cards.add(new SetCardInfo("Ancestral Vision", 42, Rarity.RARE, mage.cards.a.AncestralVision.class));
cards.add(new SetCardInfo("Angel of Mercy", 6, Rarity.COMMON, mage.cards.a.AngelOfMercy.class));
cards.add(new SetCardInfo("Angelic Accord", 7, Rarity.UNCOMMON, mage.cards.a.AngelicAccord.class));
+ cards.add(new SetCardInfo("Anger of the Gods", 116, Rarity.RARE, mage.cards.a.AngerOfTheGods.class));
cards.add(new SetCardInfo("Archangel of Thune", 8, Rarity.MYTHIC, mage.cards.a.ArchangelOfThune.class));
+ cards.add(new SetCardInfo("Assault Formation", 155, Rarity.UNCOMMON, mage.cards.a.AssaultFormation.class));
cards.add(new SetCardInfo("Auriok Champion", 9, Rarity.RARE, mage.cards.a.AuriokChampion.class));
cards.add(new SetCardInfo("Austere Command", 10, Rarity.RARE, mage.cards.a.AustereCommand.class));
cards.add(new SetCardInfo("Avacyn, Angel of Hope", 11, Rarity.MYTHIC, mage.cards.a.AvacynAngelOfHope.class));
+ cards.add(new SetCardInfo("Azorius Chancery", 232, Rarity.UNCOMMON, mage.cards.a.AzoriusChancery.class));
+ cards.add(new SetCardInfo("Azorius Charm", 192, Rarity.UNCOMMON, mage.cards.a.AzoriusCharm.class));
+ cards.add(new SetCardInfo("Bala Ged Scorpion", 79, Rarity.COMMON, mage.cards.b.BalaGedScorpion.class));
+ cards.add(new SetCardInfo("Balustrade Spy", 80, Rarity.COMMON, mage.cards.b.BalustradeSpy.class));
+ cards.add(new SetCardInfo("Battle-Rattle Shaman", 117, Rarity.COMMON, mage.cards.b.BattleRattleShaman.class));
cards.add(new SetCardInfo("Benevolent Ancestor", 12, Rarity.COMMON, mage.cards.b.BenevolentAncestor.class));
- cards.add(new SetCardInfo("Blinding Mage", 13, Rarity.COMMON, mage.cards.b.BlindingMage.class));
- cards.add(new SetCardInfo("Burrenton Forge-Tender", 14, Rarity.UNCOMMON, mage.cards.b.BurrentonForgeTender.class));
- cards.add(new SetCardInfo("Disenchant", 15, Rarity.COMMON, mage.cards.d.Disenchant.class));
- cards.add(new SetCardInfo("Doomed Traveler", 16, Rarity.COMMON, mage.cards.d.DoomedTraveler.class));
- cards.add(new SetCardInfo("Dragon Bell Monk", 17, Rarity.COMMON, mage.cards.d.DragonBellMonk.class));
- cards.add(new SetCardInfo("Elesh Norn, Grand Cenobite", 18, Rarity.MYTHIC, mage.cards.e.EleshNornGrandCenobite.class));
- cards.add(new SetCardInfo("Emerge Unscathed", 19, Rarity.COMMON, mage.cards.e.EmergeUnscathed.class));
- cards.add(new SetCardInfo("Emeria Angel", 20, Rarity.RARE, mage.cards.e.EmeriaAngel.class));
- cards.add(new SetCardInfo("Great Teacher's Decree", 21, Rarity.UNCOMMON, mage.cards.g.GreatTeachersDecree.class));
- cards.add(new SetCardInfo("Guard Duty", 22, Rarity.COMMON, mage.cards.g.GuardDuty.class));
- cards.add(new SetCardInfo("Guided Strike", 23, Rarity.COMMON, mage.cards.g.GuidedStrike.class));
- cards.add(new SetCardInfo("Infantry Veteran", 24, Rarity.COMMON, mage.cards.i.InfantryVeteran.class));
- cards.add(new SetCardInfo("Iona's Judgment", 25, Rarity.COMMON, mage.cards.i.IonasJudgment.class));
- cards.add(new SetCardInfo("Path of Bravery", 26, Rarity.RARE, mage.cards.p.PathOfBravery.class));
- cards.add(new SetCardInfo("Pentarch Ward", 27, Rarity.COMMON, mage.cards.p.PentarchWard.class));
- cards.add(new SetCardInfo("Restoration Angel", 28, Rarity.RARE, mage.cards.r.RestorationAngel.class));
- cards.add(new SetCardInfo("Seeker of the Way", 29, Rarity.COMMON, mage.cards.s.SeekerOfTheWay.class));
- cards.add(new SetCardInfo("Serra Angel", 30, Rarity.UNCOMMON, mage.cards.s.SerraAngel.class));
- cards.add(new SetCardInfo("Serra Ascendant", 31, Rarity.RARE, mage.cards.s.SerraAscendant.class));
- cards.add(new SetCardInfo("Stalwart Aven", 32, Rarity.COMMON, mage.cards.s.StalwartAven.class));
- cards.add(new SetCardInfo("Student of Ojutai", 33, Rarity.COMMON, mage.cards.s.StudentOfOjutai.class));
- cards.add(new SetCardInfo("Survival Cache", 34, Rarity.COMMON, mage.cards.s.SurvivalCache.class));
- cards.add(new SetCardInfo("Sustainer of the Realm", 35, Rarity.COMMON, mage.cards.s.SustainerOfTheRealm.class));
- cards.add(new SetCardInfo("Swords to Plowshares", 36, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class));
- cards.add(new SetCardInfo("Topan Freeblade", 37, Rarity.UNCOMMON, mage.cards.t.TopanFreeblade.class));
- cards.add(new SetCardInfo("Wing Shards", 38, Rarity.UNCOMMON, mage.cards.w.WingShards.class));
- cards.add(new SetCardInfo("Yosei, the Morning Star", 39, Rarity.RARE, mage.cards.y.YoseiTheMorningStar.class));
- cards.add(new SetCardInfo("Aetherize", 40, Rarity.UNCOMMON, mage.cards.a.Aetherize.class));
- cards.add(new SetCardInfo("Amass the Components", 41, Rarity.COMMON, mage.cards.a.AmassTheComponents.class));
- cards.add(new SetCardInfo("Ancestral Vision", 42, Rarity.RARE, mage.cards.a.AncestralVision.class));
cards.add(new SetCardInfo("Bewilder", 43, Rarity.COMMON, mage.cards.b.Bewilder.class));
+ cards.add(new SetCardInfo("Bladewing the Risen", 193, Rarity.UNCOMMON, mage.cards.b.BladewingTheRisen.class));
+ cards.add(new SetCardInfo("Bladewing's Thrall", 81, Rarity.UNCOMMON, mage.cards.b.BladewingsThrall.class));
+ cards.add(new SetCardInfo("Blinding Mage", 13, Rarity.COMMON, mage.cards.b.BlindingMage.class));
+ cards.add(new SetCardInfo("Blizzard Specter", 194, Rarity.UNCOMMON, mage.cards.b.BlizzardSpecter.class));
+ cards.add(new SetCardInfo("Blood Baron of Vizkopa", 195, Rarity.RARE, mage.cards.b.BloodBaronOfVizkopa.class));
+ cards.add(new SetCardInfo("Bloodghast", 82, Rarity.RARE, mage.cards.b.Bloodghast.class));
+ cards.add(new SetCardInfo("Bogardan Hellkite", 118, Rarity.RARE, mage.cards.b.BogardanHellkite.class));
+ cards.add(new SetCardInfo("Bogbrew Witch", 83, Rarity.UNCOMMON, mage.cards.b.BogbrewWitch.class));
+ cards.add(new SetCardInfo("Borderland Marauder", 119, Rarity.COMMON, mage.cards.b.BorderlandMarauder.class));
+ cards.add(new SetCardInfo("Boros Garrison", 233, Rarity.UNCOMMON, mage.cards.b.BorosGarrison.class));
+ cards.add(new SetCardInfo("Bubbling Cauldron", 213, Rarity.UNCOMMON, mage.cards.b.BubblingCauldron.class));
+ cards.add(new SetCardInfo("Burrenton Forge-Tender", 14, Rarity.UNCOMMON, mage.cards.b.BurrentonForgeTender.class));
+ cards.add(new SetCardInfo("Butcher's Glee", 84, Rarity.COMMON, mage.cards.b.ButchersGlee.class));
+ cards.add(new SetCardInfo("Carven Caryatid", 156, Rarity.UNCOMMON, mage.cards.c.CarvenCaryatid.class));
cards.add(new SetCardInfo("Cephalid Broker", 44, Rarity.UNCOMMON, mage.cards.c.CephalidBroker.class));
+ cards.add(new SetCardInfo("Channel", 157, Rarity.MYTHIC, mage.cards.c.Channel.class));
+ cards.add(new SetCardInfo("Charmbreaker Devils", 120, Rarity.RARE, mage.cards.c.CharmbreakerDevils.class));
+ cards.add(new SetCardInfo("Child of Night", 85, Rarity.COMMON, mage.cards.c.ChildOfNight.class));
+ cards.add(new SetCardInfo("Chronicler of Heroes", 196, Rarity.UNCOMMON, mage.cards.c.ChroniclerOfHeroes.class));
cards.add(new SetCardInfo("Claustrophobia", 45, Rarity.COMMON, mage.cards.c.Claustrophobia.class));
cards.add(new SetCardInfo("Condescend", 46, Rarity.UNCOMMON, mage.cards.c.Condescend.class));
cards.add(new SetCardInfo("Consecrated Sphinx", 47, Rarity.MYTHIC, mage.cards.c.ConsecratedSphinx.class));
+ cards.add(new SetCardInfo("Coordinated Assault", 121, Rarity.UNCOMMON, mage.cards.c.CoordinatedAssault.class));
+ cards.add(new SetCardInfo("Corpsejack Menace", 197, Rarity.UNCOMMON, mage.cards.c.CorpsejackMenace.class));
+ cards.add(new SetCardInfo("Crowned Ceratok", 158, Rarity.COMMON, mage.cards.c.CrownedCeratok.class));
+ cards.add(new SetCardInfo("Crucible of Fire", 122, Rarity.RARE, mage.cards.c.CrucibleOfFire.class));
cards.add(new SetCardInfo("Cryptic Command", 48, Rarity.RARE, mage.cards.c.CrypticCommand.class));
+ cards.add(new SetCardInfo("Curse of Predation", 159, Rarity.RARE, mage.cards.c.CurseOfPredation.class));
+ cards.add(new SetCardInfo("Darksteel Axe", 214, Rarity.COMMON, mage.cards.d.DarksteelAxe.class));
cards.add(new SetCardInfo("Day of the Dragons", 49, Rarity.RARE, mage.cards.d.DayOfTheDragons.class));
+ cards.add(new SetCardInfo("Dead Reveler", 86, Rarity.COMMON, mage.cards.d.DeadReveler.class));
cards.add(new SetCardInfo("Diminish", 50, Rarity.COMMON, mage.cards.d.Diminish.class));
+ cards.add(new SetCardInfo("Dimir Aqueduct", 234, Rarity.UNCOMMON, mage.cards.d.DimirAqueduct.class));
+ cards.add(new SetCardInfo("Disenchant", 15, Rarity.COMMON, mage.cards.d.Disenchant.class));
cards.add(new SetCardInfo("Dissolve", 51, Rarity.COMMON, mage.cards.d.Dissolve.class));
cards.add(new SetCardInfo("Distortion Strike", 52, Rarity.UNCOMMON, mage.cards.d.DistortionStrike.class));
- cards.add(new SetCardInfo("Doorkeeper", 53, Rarity.COMMON, mage.cards.d.Doorkeeper.class));
- cards.add(new SetCardInfo("Elusive Spellfist", 54, Rarity.COMMON, mage.cards.e.ElusiveSpellfist.class));
- cards.add(new SetCardInfo("Flusterstorm", 55, Rarity.RARE, mage.cards.f.Flusterstorm.class));
- cards.add(new SetCardInfo("Fog Bank", 56, Rarity.UNCOMMON, mage.cards.f.FogBank.class));
- cards.add(new SetCardInfo("Frost Lynx", 57, Rarity.COMMON, mage.cards.f.FrostLynx.class));
- cards.add(new SetCardInfo("Illusory Ambusher", 58, Rarity.UNCOMMON, mage.cards.i.IllusoryAmbusher.class));
- cards.add(new SetCardInfo("Illusory Angel", 59, Rarity.UNCOMMON, mage.cards.i.IllusoryAngel.class));
- cards.add(new SetCardInfo("Jace's Phantasm", 60, Rarity.COMMON, mage.cards.j.JacesPhantasm.class));
- cards.add(new SetCardInfo("Jhessian Thief", 61, Rarity.COMMON, mage.cards.j.JhessianThief.class));
- cards.add(new SetCardInfo("Jin-Gitaxias, Core Augur", 62, Rarity.MYTHIC, mage.cards.j.JinGitaxiasCoreAugur.class));
- cards.add(new SetCardInfo("Keiga, the Tide Star", 63, Rarity.RARE, mage.cards.k.KeigaTheTideStar.class));
- cards.add(new SetCardInfo("Mahamoti Djinn", 64, Rarity.UNCOMMON, mage.cards.m.MahamotiDjinn.class));
- cards.add(new SetCardInfo("Mana Drain", 65, Rarity.MYTHIC, mage.cards.m.ManaDrain.class));
- cards.add(new SetCardInfo("Mana Leak", 66, Rarity.COMMON, mage.cards.m.ManaLeak.class));
- cards.add(new SetCardInfo("Mnemonic Wall", 67, Rarity.COMMON, mage.cards.m.MnemonicWall.class));
- cards.add(new SetCardInfo("Ojutai's Breath", 68, Rarity.COMMON, mage.cards.o.OjutaisBreath.class));
- cards.add(new SetCardInfo("Phantom Monster", 69, Rarity.COMMON, mage.cards.p.PhantomMonster.class));
- cards.add(new SetCardInfo("Repeal", 70, Rarity.COMMON, mage.cards.r.Repeal.class));
- cards.add(new SetCardInfo("Riverwheel Aerialists", 71, Rarity.COMMON, mage.cards.r.RiverwheelAerialists.class));
- cards.add(new SetCardInfo("Shriekgeist", 72, Rarity.COMMON, mage.cards.s.Shriekgeist.class));
- cards.add(new SetCardInfo("Skywise Teachings", 73, Rarity.UNCOMMON, mage.cards.s.SkywiseTeachings.class));
- cards.add(new SetCardInfo("Sphinx of Uthuun", 74, Rarity.RARE, mage.cards.s.SphinxOfUthuun.class));
- cards.add(new SetCardInfo("Teferi, Mage of Zhalfir", 75, Rarity.RARE, mage.cards.t.TeferiMageOfZhalfir.class));
- cards.add(new SetCardInfo("Thought Scour", 76, Rarity.COMMON, mage.cards.t.ThoughtScour.class));
- cards.add(new SetCardInfo("Windfall", 77, Rarity.UNCOMMON, mage.cards.w.Windfall.class));
- cards.add(new SetCardInfo("Abyssal Persecutor", 78, Rarity.RARE, mage.cards.a.AbyssalPersecutor.class));
- cards.add(new SetCardInfo("Bala Ged Scorpion", 79, Rarity.COMMON, mage.cards.b.BalaGedScorpion.class));
- cards.add(new SetCardInfo("Balustrade Spy", 80, Rarity.COMMON, mage.cards.b.BalustradeSpy.class));
- cards.add(new SetCardInfo("Bladewing's Thrall", 81, Rarity.UNCOMMON, mage.cards.b.BladewingsThrall.class));
- cards.add(new SetCardInfo("Bloodghast", 82, Rarity.RARE, mage.cards.b.Bloodghast.class));
- cards.add(new SetCardInfo("Bogbrew Witch", 83, Rarity.UNCOMMON, mage.cards.b.BogbrewWitch.class));
- cards.add(new SetCardInfo("Butcher's Glee", 84, Rarity.COMMON, mage.cards.b.ButchersGlee.class));
- cards.add(new SetCardInfo("Child of Night", 85, Rarity.COMMON, mage.cards.c.ChildOfNight.class));
- cards.add(new SetCardInfo("Dead Reveler", 86, Rarity.COMMON, mage.cards.d.DeadReveler.class));
cards.add(new SetCardInfo("Doom Blade", 87, Rarity.UNCOMMON, mage.cards.d.DoomBlade.class));
- cards.add(new SetCardInfo("Duress", 88, Rarity.COMMON, mage.cards.d.Duress.class));
- cards.add(new SetCardInfo("Eternal Thirst", 89, Rarity.COMMON, mage.cards.e.EternalThirst.class));
- cards.add(new SetCardInfo("Festering Newt", 90, Rarity.COMMON, mage.cards.f.FesteringNewt.class));
- cards.add(new SetCardInfo("Foul-Tongue Invocation", 91, Rarity.COMMON, mage.cards.f.FoulTongueInvocation.class));
- cards.add(new SetCardInfo("Grisly Spectacle", 92, Rarity.COMMON, mage.cards.g.GrislySpectacle.class));
- cards.add(new SetCardInfo("Indulgent Tormentor", 93, Rarity.UNCOMMON, mage.cards.i.IndulgentTormentor.class));
- cards.add(new SetCardInfo("Haunting Hymn", 94, Rarity.UNCOMMON, mage.cards.h.HauntingHymn.class));
- cards.add(new SetCardInfo("Kokusho, the Evening Star", 95, Rarity.RARE, mage.cards.k.KokushoTheEveningStar.class));
- cards.add(new SetCardInfo("Lord of the Pit", 96, Rarity.RARE, mage.cards.l.LordOfThePit.class));
- cards.add(new SetCardInfo("Mer-Ek Nightblade", 97, Rarity.UNCOMMON, mage.cards.m.MerEkNightblade.class));
- cards.add(new SetCardInfo("Necropotence", 98, Rarity.MYTHIC, mage.cards.n.Necropotence.class));
- cards.add(new SetCardInfo("Night of Souls' Betrayal", 99, Rarity.RARE, mage.cards.n.NightOfSoulsBetrayal.class));
- cards.add(new SetCardInfo("Noxious Dragon", 100, Rarity.UNCOMMON, mage.cards.n.NoxiousDragon.class));
- cards.add(new SetCardInfo("Ob Nixilis, the Fallen", 101, Rarity.MYTHIC, mage.cards.o.ObNixilisTheFallen.class));
- cards.add(new SetCardInfo("Phyrexian Rager", 102, Rarity.COMMON, mage.cards.p.PhyrexianRager.class));
- cards.add(new SetCardInfo("Rakdos Drake", 103, Rarity.COMMON, mage.cards.r.RakdosDrake.class));
- cards.add(new SetCardInfo("Reave Soul", 104, Rarity.COMMON, mage.cards.r.ReaveSoul.class));
- cards.add(new SetCardInfo("Rotfeaster Maggot", 105, Rarity.COMMON, mage.cards.r.RotfeasterMaggot.class));
- cards.add(new SetCardInfo("Rune-Scarred Demon", 106, Rarity.RARE, mage.cards.r.RuneScarredDemon.class));
- cards.add(new SetCardInfo("Sanguine Bond", 107, Rarity.UNCOMMON, mage.cards.s.SanguineBond.class));
- cards.add(new SetCardInfo("Sheoldred, Whispering One", 108, Rarity.MYTHIC, mage.cards.s.SheoldredWhisperingOne.class));
- cards.add(new SetCardInfo("Tavern Swindler", 109, Rarity.UNCOMMON, mage.cards.t.TavernSwindler.class));
- cards.add(new SetCardInfo("Thoughtseize", 110, Rarity.RARE, mage.cards.t.Thoughtseize.class));
- cards.add(new SetCardInfo("Thrill-Kill Assassin", 111, Rarity.COMMON, mage.cards.t.ThrillKillAssassin.class));
- cards.add(new SetCardInfo("Virulent Swipe", 112, Rarity.COMMON, mage.cards.v.VirulentSwipe.class));
- cards.add(new SetCardInfo("Wight of Precinct Six", 113, Rarity.COMMON, mage.cards.w.WightOfPrecinctSix.class));
- cards.add(new SetCardInfo("Ulcerate", 114, Rarity.UNCOMMON, mage.cards.u.Ulcerate.class));
- cards.add(new SetCardInfo("Wrench Mind", 115, Rarity.COMMON, mage.cards.w.WrenchMind.class));
- cards.add(new SetCardInfo("Anger of the Gods", 116, Rarity.RARE, mage.cards.a.AngerOfTheGods.class));
- cards.add(new SetCardInfo("Battle-Rattle Shaman", 117, Rarity.COMMON, mage.cards.b.BattleRattleShaman.class));
- cards.add(new SetCardInfo("Bogardan Hellkite", 118, Rarity.RARE, mage.cards.b.BogardanHellkite.class));
- cards.add(new SetCardInfo("Borderland Marauder", 119, Rarity.COMMON, mage.cards.b.BorderlandMarauder.class));
- cards.add(new SetCardInfo("Charmbreaker Devils", 120, Rarity.RARE, mage.cards.c.CharmbreakerDevils.class));
- cards.add(new SetCardInfo("Coordinated Assault", 121, Rarity.UNCOMMON, mage.cards.c.CoordinatedAssault.class));
- cards.add(new SetCardInfo("Crucible of Fire", 122, Rarity.RARE, mage.cards.c.CrucibleOfFire.class));
+ cards.add(new SetCardInfo("Doomed Traveler", 16, Rarity.COMMON, mage.cards.d.DoomedTraveler.class));
+ cards.add(new SetCardInfo("Doorkeeper", 53, Rarity.COMMON, mage.cards.d.Doorkeeper.class));
cards.add(new SetCardInfo("Draconic Roar", 123, Rarity.COMMON, mage.cards.d.DraconicRoar.class));
+ cards.add(new SetCardInfo("Dragon Bell Monk", 17, Rarity.COMMON, mage.cards.d.DragonBellMonk.class));
cards.add(new SetCardInfo("Dragon Egg", 124, Rarity.COMMON, mage.cards.d.DragonEgg.class));
cards.add(new SetCardInfo("Dragon Tempest", 125, Rarity.UNCOMMON, mage.cards.d.DragonTempest.class));
+ cards.add(new SetCardInfo("Dragonloft Idol", 215, Rarity.UNCOMMON, mage.cards.d.DragonloftIdol.class));
cards.add(new SetCardInfo("Dragonlord's Servant", 126, Rarity.COMMON, mage.cards.d.DragonlordsServant.class));
+ cards.add(new SetCardInfo("Duress", 88, Rarity.COMMON, mage.cards.d.Duress.class));
+ cards.add(new SetCardInfo("Durkwood Baloth", 160, Rarity.COMMON, mage.cards.d.DurkwoodBaloth.class));
+ cards.add(new SetCardInfo("Duskdale Wurm", 161, Rarity.COMMON, mage.cards.d.DuskdaleWurm.class));
cards.add(new SetCardInfo("Earth Elemental", 127, Rarity.COMMON, mage.cards.e.EarthElemental.class));
+ cards.add(new SetCardInfo("Electrolyze", 198, Rarity.UNCOMMON, mage.cards.e.Electrolyze.class));
+ cards.add(new SetCardInfo("Elesh Norn, Grand Cenobite", 18, Rarity.MYTHIC, mage.cards.e.EleshNornGrandCenobite.class));
+ cards.add(new SetCardInfo("Elusive Spellfist", 54, Rarity.COMMON, mage.cards.e.ElusiveSpellfist.class));
+ cards.add(new SetCardInfo("Emerge Unscathed", 19, Rarity.COMMON, mage.cards.e.EmergeUnscathed.class));
+ cards.add(new SetCardInfo("Emeria Angel", 20, Rarity.RARE, mage.cards.e.EmeriaAngel.class));
+ cards.add(new SetCardInfo("Enlarge", 162, Rarity.UNCOMMON, mage.cards.e.Enlarge.class));
+ cards.add(new SetCardInfo("Eternal Thirst", 89, Rarity.COMMON, mage.cards.e.EternalThirst.class));
+ cards.add(new SetCardInfo("Evolving Wilds", 235, Rarity.COMMON, mage.cards.e.EvolvingWilds.class));
+ cards.add(new SetCardInfo("Festering Newt", 90, Rarity.COMMON, mage.cards.f.FesteringNewt.class));
cards.add(new SetCardInfo("Fireball", 128, Rarity.UNCOMMON, mage.cards.f.Fireball.class));
+ cards.add(new SetCardInfo("Firemane Angel", 199, Rarity.RARE, mage.cards.f.FiremaneAngel.class));
+ cards.add(new SetCardInfo("Flusterstorm", 55, Rarity.RARE, mage.cards.f.Flusterstorm.class));
+ cards.add(new SetCardInfo("Fog Bank", 56, Rarity.UNCOMMON, mage.cards.f.FogBank.class));
+ cards.add(new SetCardInfo("Foul-Tongue Invocation", 91, Rarity.COMMON, mage.cards.f.FoulTongueInvocation.class));
+ cards.add(new SetCardInfo("Frost Lynx", 57, Rarity.COMMON, mage.cards.f.FrostLynx.class));
cards.add(new SetCardInfo("Furnace Whelp", 129, Rarity.COMMON, mage.cards.f.FurnaceWhelp.class));
cards.add(new SetCardInfo("Fury Charm", 130, Rarity.COMMON, mage.cards.f.FuryCharm.class));
+ cards.add(new SetCardInfo("Genesis Hydra", 163, Rarity.RARE, mage.cards.g.GenesisHydra.class));
+ cards.add(new SetCardInfo("Genesis Wave", 164, Rarity.RARE, mage.cards.g.GenesisWave.class));
+ cards.add(new SetCardInfo("Glimpse the Unthinkable", 200, Rarity.RARE, mage.cards.g.GlimpseTheUnthinkable.class));
+ cards.add(new SetCardInfo("Golgari Rot Farm", 236, Rarity.UNCOMMON, mage.cards.g.GolgariRotFarm.class));
+ cards.add(new SetCardInfo("Graven Cairns", 237, Rarity.RARE, mage.cards.g.GravenCairns.class));
+ cards.add(new SetCardInfo("Great Teacher's Decree", 21, Rarity.UNCOMMON, mage.cards.g.GreatTeachersDecree.class));
+ cards.add(new SetCardInfo("Greater Basilisk", 165, Rarity.COMMON, mage.cards.g.GreaterBasilisk.class));
+ cards.add(new SetCardInfo("Grisly Spectacle", 92, Rarity.COMMON, mage.cards.g.GrislySpectacle.class));
+ cards.add(new SetCardInfo("Grove of the Burnwillows", 238, Rarity.RARE, mage.cards.g.GroveOfTheBurnwillows.class));
+ cards.add(new SetCardInfo("Gruul Turf", 239, Rarity.UNCOMMON, mage.cards.g.GruulTurf.class));
+ cards.add(new SetCardInfo("Guard Duty", 22, Rarity.COMMON, mage.cards.g.GuardDuty.class));
+ cards.add(new SetCardInfo("Guardian Idol", 216, Rarity.COMMON, mage.cards.g.GuardianIdol.class));
+ cards.add(new SetCardInfo("Guided Strike", 23, Rarity.COMMON, mage.cards.g.GuidedStrike.class));
cards.add(new SetCardInfo("Guttersnipe", 131, Rarity.UNCOMMON, mage.cards.g.Guttersnipe.class));
cards.add(new SetCardInfo("Hammerhand", 132, Rarity.COMMON, mage.cards.h.Hammerhand.class));
+ cards.add(new SetCardInfo("Haunting Hymn", 93, Rarity.UNCOMMON, mage.cards.h.HauntingHymn.class));
cards.add(new SetCardInfo("Heat Ray", 133, Rarity.COMMON, mage.cards.h.HeatRay.class));
+ cards.add(new SetCardInfo("Heroes' Bane", 166, Rarity.UNCOMMON, mage.cards.h.HeroesBane.class));
cards.add(new SetCardInfo("Hoarding Dragon", 134, Rarity.UNCOMMON, mage.cards.h.HoardingDragon.class));
+ cards.add(new SetCardInfo("Horizon Canopy", 240, Rarity.RARE, mage.cards.h.HorizonCanopy.class));
+ cards.add(new SetCardInfo("Hunt the Weak", 167, Rarity.COMMON, mage.cards.h.HuntTheWeak.class));
+ cards.add(new SetCardInfo("Hunting Pack", 168, Rarity.UNCOMMON, mage.cards.h.HuntingPack.class));
+ cards.add(new SetCardInfo("Hypersonic Dragon", 201, Rarity.RARE, mage.cards.h.HypersonicDragon.class));
+ cards.add(new SetCardInfo("Illusory Ambusher", 58, Rarity.UNCOMMON, mage.cards.i.IllusoryAmbusher.class));
+ cards.add(new SetCardInfo("Illusory Angel", 59, Rarity.UNCOMMON, mage.cards.i.IllusoryAngel.class));
+ cards.add(new SetCardInfo("Indulgent Tormentor", 94, Rarity.UNCOMMON, mage.cards.i.IndulgentTormentor.class));
+ cards.add(new SetCardInfo("Infantry Veteran", 24, Rarity.COMMON, mage.cards.i.InfantryVeteran.class));
+ cards.add(new SetCardInfo("Inspiring Call", 169, Rarity.UNCOMMON, mage.cards.i.InspiringCall.class));
+ cards.add(new SetCardInfo("Iona's Judgment", 25, Rarity.COMMON, mage.cards.i.IonasJudgment.class));
+ cards.add(new SetCardInfo("Ivy Elemental", 170, Rarity.COMMON, mage.cards.i.IvyElemental.class));
+ cards.add(new SetCardInfo("Izzet Boilerworks", 241, Rarity.UNCOMMON, mage.cards.i.IzzetBoilerworks.class));
+ cards.add(new SetCardInfo("Jace's Phantasm", 60, Rarity.COMMON, mage.cards.j.JacesPhantasm.class));
+ cards.add(new SetCardInfo("Jaddi Offshoot", 171, Rarity.COMMON, mage.cards.j.JaddiOffshoot.class));
+ cards.add(new SetCardInfo("Jhessian Thief", 61, Rarity.COMMON, mage.cards.j.JhessianThief.class));
+ cards.add(new SetCardInfo("Jin-Gitaxias, Core Augur", 62, Rarity.MYTHIC, mage.cards.j.JinGitaxiasCoreAugur.class));
+ cards.add(new SetCardInfo("Jugan, the Rising Star", 172, Rarity.RARE, mage.cards.j.JuganTheRisingStar.class));
+ cards.add(new SetCardInfo("Jungle Barrier", 202, Rarity.UNCOMMON, mage.cards.j.JungleBarrier.class));
+ cards.add(new SetCardInfo("Keiga, the Tide Star", 63, Rarity.RARE, mage.cards.k.KeigaTheTideStar.class));
cards.add(new SetCardInfo("Keldon Halberdier", 135, Rarity.COMMON, mage.cards.k.KeldonHalberdier.class));
cards.add(new SetCardInfo("Kiki-Jiki, Mirror Breaker", 136, Rarity.MYTHIC, mage.cards.k.KikiJikiMirrorBreaker.class));
cards.add(new SetCardInfo("Kiln Fiend", 137, Rarity.COMMON, mage.cards.k.KilnFiend.class));
- cards.add(new SetCardInfo("Mark of Mutiny", 138, Rarity.COMMON, mage.cards.m.MarkOfMutiny.class));
- cards.add(new SetCardInfo("Magus of the Moon", 139, Rarity.RARE, mage.cards.m.MagusOfTheMoon.class));
- cards.add(new SetCardInfo("Monastery Swiftspear", 140, Rarity.UNCOMMON, mage.cards.m.MonasterySwiftspear.class));
- cards.add(new SetCardInfo("Pillar of Flame", 141, Rarity.COMMON, mage.cards.p.PillarOfFlame.class));
- cards.add(new SetCardInfo("Prodigal Pyromancer", 142, Rarity.UNCOMMON, mage.cards.p.ProdigalPyromancer.class));
- cards.add(new SetCardInfo("Rift Bolt", 143, Rarity.UNCOMMON, mage.cards.r.RiftBolt.class));
- cards.add(new SetCardInfo("Ryusei, the Falling Star", 144, Rarity.RARE, mage.cards.r.RyuseiTheFallingStar.class));
- cards.add(new SetCardInfo("Scourge of Valkas", 145, Rarity.RARE, mage.cards.s.ScourgeOfValkas.class));
- cards.add(new SetCardInfo("Splatter Thug", 146, Rarity.COMMON, mage.cards.s.SplatterThug.class));
- cards.add(new SetCardInfo("Staggershock", 147, Rarity.UNCOMMON, mage.cards.s.Staggershock.class));
- cards.add(new SetCardInfo("Surreal Memoir", 148, Rarity.UNCOMMON, mage.cards.s.SurrealMemoir.class));
- cards.add(new SetCardInfo("Thundermaw Hellkite", 149, Rarity.MYTHIC, mage.cards.t.ThundermawHellkite.class));
- cards.add(new SetCardInfo("Tormenting Voice", 150, Rarity.COMMON, mage.cards.t.TormentingVoice.class));
- cards.add(new SetCardInfo("Trumpet Blast", 151, Rarity.COMMON, mage.cards.t.TrumpetBlast.class));
- cards.add(new SetCardInfo("Urabrask the Hidden", 152, Rarity.MYTHIC, mage.cards.u.UrabraskTheHidden.class));
- cards.add(new SetCardInfo("Vent Sentinel", 153, Rarity.COMMON, mage.cards.v.VentSentinel.class));
- cards.add(new SetCardInfo("Aerial Predation", 154, Rarity.COMMON, mage.cards.a.AerialPredation.class));
- cards.add(new SetCardInfo("Assault Formation", 155, Rarity.UNCOMMON, mage.cards.a.AssaultFormation.class));
- cards.add(new SetCardInfo("Carven Caryatid", 156, Rarity.UNCOMMON, mage.cards.c.CarvenCaryatid.class));
- cards.add(new SetCardInfo("Channel", 157, Rarity.MYTHIC, mage.cards.c.Channel.class));
- cards.add(new SetCardInfo("Crowned Ceratok", 158, Rarity.COMMON, mage.cards.c.CrownedCeratok.class));
- cards.add(new SetCardInfo("Curse of Predation", 159, Rarity.RARE, mage.cards.c.CurseOfPredation.class));
- cards.add(new SetCardInfo("Durkwood Baloth", 160, Rarity.COMMON, mage.cards.d.DurkwoodBaloth.class));
- cards.add(new SetCardInfo("Duskdale Wurm", 161, Rarity.COMMON, mage.cards.d.DuskdaleWurm.class));
- cards.add(new SetCardInfo("Enlarge", 162, Rarity.UNCOMMON, mage.cards.e.Enlarge.class));
- cards.add(new SetCardInfo("Genesis Hydra", 163, Rarity.RARE, mage.cards.g.GenesisHydra.class));
- cards.add(new SetCardInfo("Genesis Wave", 164, Rarity.RARE, mage.cards.g.GenesisWave.class));
- cards.add(new SetCardInfo("Greater Basilisk", 165, Rarity.COMMON, mage.cards.g.GreaterBasilisk.class));
- cards.add(new SetCardInfo("Heroes' Bane", 166, Rarity.UNCOMMON, mage.cards.h.HeroesBane.class));
- cards.add(new SetCardInfo("Hunting Pack", 167, Rarity.UNCOMMON, mage.cards.h.HuntingPack.class));
- cards.add(new SetCardInfo("Hunt the Weak", 168, Rarity.COMMON, mage.cards.h.HuntTheWeak.class));
- cards.add(new SetCardInfo("Inspiring Call", 169, Rarity.UNCOMMON, mage.cards.i.InspiringCall.class));
- cards.add(new SetCardInfo("Ivy Elemental", 170, Rarity.COMMON, mage.cards.i.IvyElemental.class));
- cards.add(new SetCardInfo("Jaddi Offshoot", 171, Rarity.COMMON, mage.cards.j.JaddiOffshoot.class));
- cards.add(new SetCardInfo("Jugan, the Rising Star", 172, Rarity.RARE, mage.cards.j.JuganTheRisingStar.class));
+ cards.add(new SetCardInfo("Knight of the Reliquary", 203, Rarity.RARE, mage.cards.k.KnightOfTheReliquary.class));
+ cards.add(new SetCardInfo("Kokusho, the Evening Star", 95, Rarity.RARE, mage.cards.k.KokushoTheEveningStar.class));
+ cards.add(new SetCardInfo("Kolaghan Monument", 217, Rarity.UNCOMMON, mage.cards.k.KolaghanMonument.class));
cards.add(new SetCardInfo("Lead the Stampede", 173, Rarity.COMMON, mage.cards.l.LeadTheStampede.class));
+ cards.add(new SetCardInfo("Lightning Helix", 204, Rarity.UNCOMMON, mage.cards.l.LightningHelix.class));
+ cards.add(new SetCardInfo("Lord of the Pit", 96, Rarity.RARE, mage.cards.l.LordOfThePit.class));
cards.add(new SetCardInfo("Lotus Cobra", 174, Rarity.RARE, mage.cards.l.LotusCobra.class));
cards.add(new SetCardInfo("Lure", 175, Rarity.UNCOMMON, mage.cards.l.Lure.class));
- cards.add(new SetCardInfo("Nantuko Shaman", 176, Rarity.COMMON, mage.cards.n.NantukoShaman.class));
- cards.add(new SetCardInfo("Nature's Claim", 177, Rarity.COMMON, mage.cards.n.NaturesClaim.class));
- cards.add(new SetCardInfo("Netcaster Spider", 178, Rarity.COMMON, mage.cards.n.NetcasterSpider.class));
- cards.add(new SetCardInfo("Obstinate Baloth", 179, Rarity.RARE, mage.cards.o.ObstinateBaloth.class));
- cards.add(new SetCardInfo("Overgrown Battlement", 180, Rarity.UNCOMMON, mage.cards.o.OvergrownBattlement.class));
- cards.add(new SetCardInfo("Phantom Tiger", 181, Rarity.COMMON, mage.cards.p.PhantomTiger.class));
- cards.add(new SetCardInfo("Prey's Vengeance", 182, Rarity.COMMON, mage.cards.p.PreysVengeance.class));
- cards.add(new SetCardInfo("Primeval Titan", 183, Rarity.MYTHIC, mage.cards.p.PrimevalTitan.class));
- cards.add(new SetCardInfo("Rampaging Baloths", 184, Rarity.RARE, mage.cards.r.RampagingBaloths.class));
- cards.add(new SetCardInfo("Search for Tomorrow", 185, Rarity.COMMON, mage.cards.s.SearchForTomorrow.class));
- cards.add(new SetCardInfo("Sultai Flayer", 186, Rarity.UNCOMMON, mage.cards.s.SultaiFlayer.class));
- cards.add(new SetCardInfo("Timberland Guide", 187, Rarity.COMMON, mage.cards.t.TimberlandGuide.class));
- cards.add(new SetCardInfo("Undercity Troll", 188, Rarity.UNCOMMON, mage.cards.u.UndercityTroll.class));
- cards.add(new SetCardInfo("Vorinclex, Voice of Hunger", 189, Rarity.MYTHIC, mage.cards.v.VorinclexVoiceOfHunger.class));
- cards.add(new SetCardInfo("Wall of Roots", 190, Rarity.COMMON, mage.cards.w.WallOfRoots.class));
- cards.add(new SetCardInfo("Wildsize", 191, Rarity.COMMON, mage.cards.w.Wildsize.class));
- cards.add(new SetCardInfo("Azorius Charm", 192, Rarity.UNCOMMON, mage.cards.a.AzoriusCharm.class));
- cards.add(new SetCardInfo("Bladewing the Risen", 193, Rarity.UNCOMMON, mage.cards.b.BladewingTheRisen.class));
- cards.add(new SetCardInfo("Blizzard Specter", 194, Rarity.UNCOMMON, mage.cards.b.BlizzardSpecter.class));
- cards.add(new SetCardInfo("Blood Baron of Vizkopa", 195, Rarity.RARE, mage.cards.b.BloodBaronOfVizkopa.class));
- cards.add(new SetCardInfo("Chronicler of Heroes", 196, Rarity.UNCOMMON, mage.cards.c.ChroniclerOfHeroes.class));
- cards.add(new SetCardInfo("Corpsejack Menace", 197, Rarity.UNCOMMON, mage.cards.c.CorpsejackMenace.class));
- cards.add(new SetCardInfo("Electrolyze", 198, Rarity.UNCOMMON, mage.cards.e.Electrolyze.class));
- cards.add(new SetCardInfo("Firemane Angel", 199, Rarity.RARE, mage.cards.f.FiremaneAngel.class));
- cards.add(new SetCardInfo("Glimpse the Unthinkable", 200, Rarity.RARE, mage.cards.g.GlimpseTheUnthinkable.class));
- cards.add(new SetCardInfo("Hypersonic Dragon", 201, Rarity.RARE, mage.cards.h.HypersonicDragon.class));
- cards.add(new SetCardInfo("Jungle Barrier", 202, Rarity.UNCOMMON, mage.cards.j.JungleBarrier.class));
- cards.add(new SetCardInfo("Knight of the Reliquary", 203, Rarity.RARE, mage.cards.k.KnightOfTheReliquary.class));
- cards.add(new SetCardInfo("Lightning Helix", 204, Rarity.UNCOMMON, mage.cards.l.LightningHelix.class));
+ cards.add(new SetCardInfo("Magus of the Moon", 138, Rarity.RARE, mage.cards.m.MagusOfTheMoon.class));
+ cards.add(new SetCardInfo("Mahamoti Djinn", 64, Rarity.UNCOMMON, mage.cards.m.MahamotiDjinn.class));
cards.add(new SetCardInfo("Malfegor", 205, Rarity.RARE, mage.cards.m.Malfegor.class));
- cards.add(new SetCardInfo("Rosheen Meanderer", 206, Rarity.UNCOMMON, mage.cards.r.RosheenMeanderer.class));
- cards.add(new SetCardInfo("Savageborn Hydra", 207, Rarity.RARE, mage.cards.s.SavagebornHydra.class));
- cards.add(new SetCardInfo("Simic Sky Swallower", 208, Rarity.RARE, mage.cards.s.SimicSkySwallower.class));
- cards.add(new SetCardInfo("Spiritmonger", 209, Rarity.RARE, mage.cards.s.Spiritmonger.class));
- cards.add(new SetCardInfo("Supreme Verdict", 210, Rarity.RARE, mage.cards.s.SupremeVerdict.class));
- cards.add(new SetCardInfo("Vizkopa Guildmage", 211, Rarity.UNCOMMON, mage.cards.v.VizkopaGuildmage.class));
- cards.add(new SetCardInfo("Aether Vial", 212, Rarity.RARE, mage.cards.a.AetherVial.class));
- cards.add(new SetCardInfo("Bubbling Cauldron", 213, Rarity.UNCOMMON, mage.cards.b.BubblingCauldron.class));
- cards.add(new SetCardInfo("Darksteel Axe", 214, Rarity.COMMON, mage.cards.d.DarksteelAxe.class));
- cards.add(new SetCardInfo("Dragonloft Idol", 215, Rarity.UNCOMMON, mage.cards.d.DragonloftIdol.class));
- cards.add(new SetCardInfo("Guardian Idol", 216, Rarity.COMMON, mage.cards.g.GuardianIdol.class));
- cards.add(new SetCardInfo("Kolaghan Monument", 217, Rarity.UNCOMMON, mage.cards.k.KolaghanMonument.class));
+ cards.add(new SetCardInfo("Mana Drain", 65, Rarity.MYTHIC, mage.cards.m.ManaDrain.class));
+ cards.add(new SetCardInfo("Mana Leak", 66, Rarity.COMMON, mage.cards.m.ManaLeak.class));
cards.add(new SetCardInfo("Manakin", 218, Rarity.COMMON, mage.cards.m.Manakin.class));
+ cards.add(new SetCardInfo("Mark of Mutiny", 139, Rarity.COMMON, mage.cards.m.MarkOfMutiny.class));
+ cards.add(new SetCardInfo("Mer-Ek Nightblade", 97, Rarity.UNCOMMON, mage.cards.m.MerEkNightblade.class));
cards.add(new SetCardInfo("Mind Stone", 219, Rarity.COMMON, mage.cards.m.MindStone.class));
cards.add(new SetCardInfo("Mindcrank", 220, Rarity.UNCOMMON, mage.cards.m.Mindcrank.class));
cards.add(new SetCardInfo("Mishra's Bauble", 221, Rarity.UNCOMMON, mage.cards.m.MishrasBauble.class));
+ cards.add(new SetCardInfo("Mnemonic Wall", 67, Rarity.COMMON, mage.cards.m.MnemonicWall.class));
+ cards.add(new SetCardInfo("Monastery Swiftspear", 140, Rarity.UNCOMMON, mage.cards.m.MonasterySwiftspear.class));
cards.add(new SetCardInfo("Moonglove Extract", 222, Rarity.COMMON, mage.cards.m.MoongloveExtract.class));
- cards.add(new SetCardInfo("Oblivion Stone", 223, Rarity.RARE, mage.cards.o.OblivionStone.class));
- cards.add(new SetCardInfo("Palladium Myr", 224, Rarity.UNCOMMON, mage.cards.p.PalladiumMyr.class));
- cards.add(new SetCardInfo("Pristine Talisman", 225, Rarity.UNCOMMON, mage.cards.p.PristineTalisman.class));
- cards.add(new SetCardInfo("Runed Servitor", 226, Rarity.COMMON, mage.cards.r.RunedServitor.class));
- cards.add(new SetCardInfo("Sandstone Oracle", 227, Rarity.UNCOMMON, mage.cards.s.SandstoneOracle.class));
- cards.add(new SetCardInfo("Serum Powder", 228, Rarity.RARE, mage.cards.s.SerumPowder.class));
- cards.add(new SetCardInfo("Star Compass", 229, Rarity.COMMON, mage.cards.s.StarCompass.class));
- cards.add(new SetCardInfo("Thran Dynamo", 230, Rarity.UNCOMMON, mage.cards.t.ThranDynamo.class));
- cards.add(new SetCardInfo("Trepanation Blade", 231, Rarity.UNCOMMON, mage.cards.t.TrepanationBlade.class));
- cards.add(new SetCardInfo("Azorius Chancery", 232, Rarity.UNCOMMON, mage.cards.a.AzoriusChancery.class));
- cards.add(new SetCardInfo("Boros Garrison", 233, Rarity.UNCOMMON, mage.cards.b.BorosGarrison.class));
- cards.add(new SetCardInfo("Dimir Aqueduct", 234, Rarity.UNCOMMON, mage.cards.d.DimirAqueduct.class));
- cards.add(new SetCardInfo("Evolving Wilds", 235, Rarity.COMMON, mage.cards.e.EvolvingWilds.class));
- cards.add(new SetCardInfo("Golgari Rot Farm", 236, Rarity.UNCOMMON, mage.cards.g.GolgariRotFarm.class));
- cards.add(new SetCardInfo("Graven Cairns", 237, Rarity.RARE, mage.cards.g.GravenCairns.class));
- cards.add(new SetCardInfo("Grove of the Burnwillows", 238, Rarity.RARE, mage.cards.g.GroveOfTheBurnwillows.class));
- cards.add(new SetCardInfo("Gruul Turf", 239, Rarity.UNCOMMON, mage.cards.g.GruulTurf.class));
- cards.add(new SetCardInfo("Horizon Canopy", 240, Rarity.RARE, mage.cards.h.HorizonCanopy.class));
- cards.add(new SetCardInfo("Izzet Boilerworks", 241, Rarity.UNCOMMON, mage.cards.i.IzzetBoilerworks.class));
+ cards.add(new SetCardInfo("Nantuko Shaman", 176, Rarity.COMMON, mage.cards.n.NantukoShaman.class));
+ cards.add(new SetCardInfo("Nature's Claim", 177, Rarity.COMMON, mage.cards.n.NaturesClaim.class));
+ cards.add(new SetCardInfo("Necropotence", 98, Rarity.MYTHIC, mage.cards.n.Necropotence.class));
+ cards.add(new SetCardInfo("Netcaster Spider", 178, Rarity.COMMON, mage.cards.n.NetcasterSpider.class));
+ cards.add(new SetCardInfo("Night of Souls' Betrayal", 99, Rarity.RARE, mage.cards.n.NightOfSoulsBetrayal.class));
cards.add(new SetCardInfo("Nimbus Maze", 242, Rarity.RARE, mage.cards.n.NimbusMaze.class));
+ cards.add(new SetCardInfo("Noxious Dragon", 100, Rarity.UNCOMMON, mage.cards.n.NoxiousDragon.class));
+ cards.add(new SetCardInfo("Ob Nixilis, the Fallen", 101, Rarity.MYTHIC, mage.cards.o.ObNixilisTheFallen.class));
+ cards.add(new SetCardInfo("Oblivion Stone", 223, Rarity.RARE, mage.cards.o.OblivionStone.class));
+ cards.add(new SetCardInfo("Obstinate Baloth", 179, Rarity.RARE, mage.cards.o.ObstinateBaloth.class));
+ cards.add(new SetCardInfo("Ojutai's Breath", 68, Rarity.COMMON, mage.cards.o.OjutaisBreath.class));
cards.add(new SetCardInfo("Orzhov Basilica", 243, Rarity.UNCOMMON, mage.cards.o.OrzhovBasilica.class));
+ cards.add(new SetCardInfo("Overgrown Battlement", 180, Rarity.UNCOMMON, mage.cards.o.OvergrownBattlement.class));
+ cards.add(new SetCardInfo("Palladium Myr", 224, Rarity.UNCOMMON, mage.cards.p.PalladiumMyr.class));
+ cards.add(new SetCardInfo("Path of Bravery", 26, Rarity.RARE, mage.cards.p.PathOfBravery.class));
+ cards.add(new SetCardInfo("Pentarch Ward", 27, Rarity.COMMON, mage.cards.p.PentarchWard.class));
+ cards.add(new SetCardInfo("Phantom Monster", 69, Rarity.COMMON, mage.cards.p.PhantomMonster.class));
+ cards.add(new SetCardInfo("Phantom Tiger", 181, Rarity.COMMON, mage.cards.p.PhantomTiger.class));
+ cards.add(new SetCardInfo("Phyrexian Rager", 102, Rarity.COMMON, mage.cards.p.PhyrexianRager.class));
+ cards.add(new SetCardInfo("Pillar of Flame", 141, Rarity.COMMON, mage.cards.p.PillarOfFlame.class));
+ cards.add(new SetCardInfo("Prey's Vengeance", 182, Rarity.COMMON, mage.cards.p.PreysVengeance.class));
+ cards.add(new SetCardInfo("Primeval Titan", 183, Rarity.MYTHIC, mage.cards.p.PrimevalTitan.class));
+ cards.add(new SetCardInfo("Pristine Talisman", 225, Rarity.UNCOMMON, mage.cards.p.PristineTalisman.class));
+ cards.add(new SetCardInfo("Prodigal Pyromancer", 142, Rarity.UNCOMMON, mage.cards.p.ProdigalPyromancer.class));
cards.add(new SetCardInfo("Radiant Fountain", 244, Rarity.COMMON, mage.cards.r.RadiantFountain.class));
cards.add(new SetCardInfo("Rakdos Carnarium", 245, Rarity.UNCOMMON, mage.cards.r.RakdosCarnarium.class));
+ cards.add(new SetCardInfo("Rakdos Drake", 103, Rarity.COMMON, mage.cards.r.RakdosDrake.class));
+ cards.add(new SetCardInfo("Rampaging Baloths", 184, Rarity.RARE, mage.cards.r.RampagingBaloths.class));
+ cards.add(new SetCardInfo("Reave Soul", 104, Rarity.COMMON, mage.cards.r.ReaveSoul.class));
+ cards.add(new SetCardInfo("Repeal", 70, Rarity.COMMON, mage.cards.r.Repeal.class));
+ cards.add(new SetCardInfo("Restoration Angel", 28, Rarity.RARE, mage.cards.r.RestorationAngel.class));
+ cards.add(new SetCardInfo("Rift Bolt", 143, Rarity.UNCOMMON, mage.cards.r.RiftBolt.class));
cards.add(new SetCardInfo("River of Tears", 246, Rarity.RARE, mage.cards.r.RiverOfTears.class));
+ cards.add(new SetCardInfo("Riverwheel Aerialists", 71, Rarity.COMMON, mage.cards.r.RiverwheelAerialists.class));
+ cards.add(new SetCardInfo("Rosheen Meanderer", 206, Rarity.UNCOMMON, mage.cards.r.RosheenMeanderer.class));
+ cards.add(new SetCardInfo("Rotfeaster Maggot", 105, Rarity.COMMON, mage.cards.r.RotfeasterMaggot.class));
+ cards.add(new SetCardInfo("Rune-Scarred Demon", 106, Rarity.RARE, mage.cards.r.RuneScarredDemon.class));
+ cards.add(new SetCardInfo("Runed Servitor", 226, Rarity.COMMON, mage.cards.r.RunedServitor.class));
+ cards.add(new SetCardInfo("Ryusei, the Falling Star", 144, Rarity.RARE, mage.cards.r.RyuseiTheFallingStar.class));
+ cards.add(new SetCardInfo("Sandstone Oracle", 227, Rarity.UNCOMMON, mage.cards.s.SandstoneOracle.class));
+ cards.add(new SetCardInfo("Sanguine Bond", 107, Rarity.UNCOMMON, mage.cards.s.SanguineBond.class));
+ cards.add(new SetCardInfo("Savageborn Hydra", 207, Rarity.RARE, mage.cards.s.SavagebornHydra.class));
+ cards.add(new SetCardInfo("Scion of Ugin", 1, Rarity.COMMON, mage.cards.s.ScionOfUgin.class));
+ cards.add(new SetCardInfo("Scourge of Valkas", 145, Rarity.RARE, mage.cards.s.ScourgeOfValkas.class));
+ cards.add(new SetCardInfo("Search for Tomorrow", 185, Rarity.COMMON, mage.cards.s.SearchForTomorrow.class));
+ cards.add(new SetCardInfo("Seeker of the Way", 29, Rarity.COMMON, mage.cards.s.SeekerOfTheWay.class));
cards.add(new SetCardInfo("Selesnya Sanctuary", 247, Rarity.UNCOMMON, mage.cards.s.SelesnyaSanctuary.class));
+ cards.add(new SetCardInfo("Serra Angel", 30, Rarity.UNCOMMON, mage.cards.s.SerraAngel.class));
+ cards.add(new SetCardInfo("Serra Ascendant", 31, Rarity.RARE, mage.cards.s.SerraAscendant.class));
+ cards.add(new SetCardInfo("Serum Powder", 228, Rarity.RARE, mage.cards.s.SerumPowder.class));
+ cards.add(new SetCardInfo("Sheoldred, Whispering One", 108, Rarity.MYTHIC, mage.cards.s.SheoldredWhisperingOne.class));
cards.add(new SetCardInfo("Shimmering Grotto", 248, Rarity.COMMON, mage.cards.s.ShimmeringGrotto.class));
+ cards.add(new SetCardInfo("Shriekgeist", 72, Rarity.COMMON, mage.cards.s.Shriekgeist.class));
cards.add(new SetCardInfo("Simic Growth Chamber", 249, Rarity.UNCOMMON, mage.cards.s.SimicGrowthChamber.class));
-
+ cards.add(new SetCardInfo("Simic Sky Swallower", 208, Rarity.RARE, mage.cards.s.SimicSkySwallower.class));
+ cards.add(new SetCardInfo("Skywise Teachings", 73, Rarity.UNCOMMON, mage.cards.s.SkywiseTeachings.class));
+ cards.add(new SetCardInfo("Sphinx of Uthuun", 74, Rarity.RARE, mage.cards.s.SphinxOfUthuun.class));
+ cards.add(new SetCardInfo("Spiritmonger", 209, Rarity.RARE, mage.cards.s.Spiritmonger.class));
+ cards.add(new SetCardInfo("Splatter Thug", 146, Rarity.COMMON, mage.cards.s.SplatterThug.class));
+ cards.add(new SetCardInfo("Staggershock", 147, Rarity.UNCOMMON, mage.cards.s.Staggershock.class));
+ cards.add(new SetCardInfo("Stalwart Aven", 32, Rarity.COMMON, mage.cards.s.StalwartAven.class));
+ cards.add(new SetCardInfo("Star Compass", 229, Rarity.COMMON, mage.cards.s.StarCompass.class));
+ cards.add(new SetCardInfo("Student of Ojutai", 33, Rarity.COMMON, mage.cards.s.StudentOfOjutai.class));
+ cards.add(new SetCardInfo("Sultai Flayer", 186, Rarity.UNCOMMON, mage.cards.s.SultaiFlayer.class));
+ cards.add(new SetCardInfo("Supreme Verdict", 210, Rarity.RARE, mage.cards.s.SupremeVerdict.class));
+ cards.add(new SetCardInfo("Surreal Memoir", 148, Rarity.UNCOMMON, mage.cards.s.SurrealMemoir.class));
+ cards.add(new SetCardInfo("Survival Cache", 34, Rarity.COMMON, mage.cards.s.SurvivalCache.class));
+ cards.add(new SetCardInfo("Sustainer of the Realm", 35, Rarity.COMMON, mage.cards.s.SustainerOfTheRealm.class));
+ cards.add(new SetCardInfo("Swords to Plowshares", 36, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class));
+ cards.add(new SetCardInfo("Tavern Swindler", 109, Rarity.UNCOMMON, mage.cards.t.TavernSwindler.class));
+ cards.add(new SetCardInfo("Teferi, Mage of Zhalfir", 75, Rarity.RARE, mage.cards.t.TeferiMageOfZhalfir.class));
+ cards.add(new SetCardInfo("Thought Scour", 76, Rarity.COMMON, mage.cards.t.ThoughtScour.class));
+ cards.add(new SetCardInfo("Thoughtseize", 110, Rarity.RARE, mage.cards.t.Thoughtseize.class));
+ cards.add(new SetCardInfo("Thran Dynamo", 230, Rarity.UNCOMMON, mage.cards.t.ThranDynamo.class));
+ cards.add(new SetCardInfo("Thrill-Kill Assassin", 111, Rarity.COMMON, mage.cards.t.ThrillKillAssassin.class));
+ cards.add(new SetCardInfo("Thundermaw Hellkite", 149, Rarity.MYTHIC, mage.cards.t.ThundermawHellkite.class));
+ cards.add(new SetCardInfo("Timberland Guide", 187, Rarity.COMMON, mage.cards.t.TimberlandGuide.class));
+ cards.add(new SetCardInfo("Topan Freeblade", 37, Rarity.UNCOMMON, mage.cards.t.TopanFreeblade.class));
+ cards.add(new SetCardInfo("Tormenting Voice", 150, Rarity.COMMON, mage.cards.t.TormentingVoice.class));
+ cards.add(new SetCardInfo("Trepanation Blade", 231, Rarity.UNCOMMON, mage.cards.t.TrepanationBlade.class));
+ cards.add(new SetCardInfo("Trumpet Blast", 151, Rarity.COMMON, mage.cards.t.TrumpetBlast.class));
+ cards.add(new SetCardInfo("Ulcerate", 112, Rarity.UNCOMMON, mage.cards.u.Ulcerate.class));
+ cards.add(new SetCardInfo("Undercity Troll", 188, Rarity.UNCOMMON, mage.cards.u.UndercityTroll.class));
+ cards.add(new SetCardInfo("Urabrask the Hidden", 152, Rarity.MYTHIC, mage.cards.u.UrabraskTheHidden.class));
+ cards.add(new SetCardInfo("Vent Sentinel", 153, Rarity.COMMON, mage.cards.v.VentSentinel.class));
+ cards.add(new SetCardInfo("Virulent Swipe", 113, Rarity.COMMON, mage.cards.v.VirulentSwipe.class));
+ cards.add(new SetCardInfo("Vizkopa Guildmage", 211, Rarity.UNCOMMON, mage.cards.v.VizkopaGuildmage.class));
+ cards.add(new SetCardInfo("Vorinclex, Voice of Hunger", 189, Rarity.MYTHIC, mage.cards.v.VorinclexVoiceOfHunger.class));
+ cards.add(new SetCardInfo("Wall of Roots", 190, Rarity.COMMON, mage.cards.w.WallOfRoots.class));
+ cards.add(new SetCardInfo("Wight of Precinct Six", 114, Rarity.COMMON, mage.cards.w.WightOfPrecinctSix.class));
+ cards.add(new SetCardInfo("Wildsize", 191, Rarity.COMMON, mage.cards.w.Wildsize.class));
+ cards.add(new SetCardInfo("Windfall", 77, Rarity.UNCOMMON, mage.cards.w.Windfall.class));
+ cards.add(new SetCardInfo("Wing Shards", 38, Rarity.UNCOMMON, mage.cards.w.WingShards.class));
+ cards.add(new SetCardInfo("Wrench Mind", 115, Rarity.COMMON, mage.cards.w.WrenchMind.class));
+ cards.add(new SetCardInfo("Yosei, the Morning Star", 39, Rarity.RARE, mage.cards.y.YoseiTheMorningStar.class));
}
}
diff --git a/Mage.Sets/src/mage/sets/Kaladesh.java b/Mage.Sets/src/mage/sets/Kaladesh.java
index 404da667adc..db2f010aa1d 100644
--- a/Mage.Sets/src/mage/sets/Kaladesh.java
+++ b/Mage.Sets/src/mage/sets/Kaladesh.java
@@ -23,7 +23,7 @@ public final class Kaladesh extends ExpansionSet {
return instance;
}
- protected final List savedSpecialLand = new ArrayList<>();
+ private final List savedSpecialLand = new ArrayList<>();
private Kaladesh() {
super("Kaladesh", "KLD", ExpansionSet.buildDate(2016, 9, 30), SetType.EXPANSION);
diff --git a/Mage.Sets/src/mage/sets/Masters25.java b/Mage.Sets/src/mage/sets/Masters25.java
index b3dff91f480..6b87c8b9a7c 100644
--- a/Mage.Sets/src/mage/sets/Masters25.java
+++ b/Mage.Sets/src/mage/sets/Masters25.java
@@ -1,14 +1,13 @@
package mage.sets;
-/**
- *
- * @author JayDi85
- */
import mage.cards.ExpansionSet;
import mage.constants.Rarity;
import mage.constants.SetType;
+/**
+ * @author JayDi85
+ */
public final class Masters25 extends ExpansionSet {
private static final Masters25 instance = new Masters25();
diff --git a/Mage.Sets/src/mage/sets/MastersEditionIII.java b/Mage.Sets/src/mage/sets/MastersEditionIII.java
index 20f24d901e1..61c5d64e4fc 100644
--- a/Mage.Sets/src/mage/sets/MastersEditionIII.java
+++ b/Mage.Sets/src/mage/sets/MastersEditionIII.java
@@ -96,6 +96,7 @@ public final class MastersEditionIII extends ExpansionSet {
cards.add(new SetCardInfo("Forest", 228, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Forest", 229, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Forest", 230, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Forked Lightning", 100, Rarity.UNCOMMON, mage.cards.f.ForkedLightning.class));
cards.add(new SetCardInfo("Freyalise's Winds", 119, Rarity.RARE, mage.cards.f.FreyalisesWinds.class));
cards.add(new SetCardInfo("Frost Giant", 101, Rarity.UNCOMMON, mage.cards.f.FrostGiant.class));
cards.add(new SetCardInfo("Gabriel Angelfire", 148, Rarity.RARE, mage.cards.g.GabrielAngelfire.class));
diff --git a/Mage.Sets/src/mage/sets/MastersEditionIV.java b/Mage.Sets/src/mage/sets/MastersEditionIV.java
index 6a680a577b1..555bfe9b183 100644
--- a/Mage.Sets/src/mage/sets/MastersEditionIV.java
+++ b/Mage.Sets/src/mage/sets/MastersEditionIV.java
@@ -22,7 +22,7 @@ public final class MastersEditionIV extends ExpansionSet {
return instance;
}
- protected final List savedSpecialLand = new ArrayList<>();
+ private final List savedSpecialLand = new ArrayList<>();
private MastersEditionIV() {
super("Masters Edition IV", "ME4", ExpansionSet.buildDate(2011, 1, 10), SetType.MAGIC_ONLINE);
diff --git a/Mage.Sets/src/mage/sets/MercadianMasques.java b/Mage.Sets/src/mage/sets/MercadianMasques.java
index d1ed0a59ca5..259ea4bb027 100644
--- a/Mage.Sets/src/mage/sets/MercadianMasques.java
+++ b/Mage.Sets/src/mage/sets/MercadianMasques.java
@@ -235,6 +235,7 @@ public final class MercadianMasques extends ExpansionSet {
cards.add(new SetCardInfo("Plains", 334, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Power Matrix", 309, Rarity.RARE, mage.cards.p.PowerMatrix.class));
cards.add(new SetCardInfo("Primeval Shambler", 152, Rarity.UNCOMMON, mage.cards.p.PrimevalShambler.class));
+ cards.add(new SetCardInfo("Puffer Extract", 310, Rarity.UNCOMMON, mage.cards.p.PufferExtract.class));
cards.add(new SetCardInfo("Pulverize", 207, Rarity.RARE, mage.cards.p.Pulverize.class));
cards.add(new SetCardInfo("Putrefaction", 153, Rarity.UNCOMMON, mage.cards.p.Putrefaction.class));
cards.add(new SetCardInfo("Puppet's Verdict", 208, Rarity.RARE, mage.cards.p.PuppetsVerdict.class));
@@ -286,6 +287,7 @@ public final class MercadianMasques extends ExpansionSet {
cards.add(new SetCardInfo("Sever Soul", 159, Rarity.COMMON, mage.cards.s.SeverSoul.class));
cards.add(new SetCardInfo("Shock Troops", 212, Rarity.COMMON, mage.cards.s.ShockTroops.class));
cards.add(new SetCardInfo("Shoving Match", 103, Rarity.UNCOMMON, mage.cards.s.ShovingMatch.class));
+ cards.add(new SetCardInfo("Silent Assassin", 160, Rarity.RARE, mage.cards.s.SilentAssassin.class));
cards.add(new SetCardInfo("Silverglade Elemental", 269, Rarity.COMMON, mage.cards.s.SilvergladeElemental.class));
cards.add(new SetCardInfo("Silverglade Pathfinder", 270, Rarity.UNCOMMON, mage.cards.s.SilvergladePathfinder.class));
cards.add(new SetCardInfo("Sizzle", 213, Rarity.COMMON, mage.cards.s.Sizzle.class));
diff --git a/Mage.Sets/src/mage/sets/Mirage.java b/Mage.Sets/src/mage/sets/Mirage.java
index 6e87d40a7ca..9fa3fd6af01 100644
--- a/Mage.Sets/src/mage/sets/Mirage.java
+++ b/Mage.Sets/src/mage/sets/Mirage.java
@@ -49,6 +49,7 @@ public final class Mirage extends ExpansionSet {
cards.add(new SetCardInfo("Benthic Djinn", 257, Rarity.RARE, mage.cards.b.BenthicDjinn.class));
cards.add(new SetCardInfo("Binding Agony", 106, Rarity.COMMON, mage.cards.b.BindingAgony.class));
cards.add(new SetCardInfo("Blighted Shaman", 107, Rarity.UNCOMMON, mage.cards.b.BlightedShaman.class));
+ cards.add(new SetCardInfo("Blind Fury", 158, Rarity.UNCOMMON, mage.cards.b.BlindFury.class));
cards.add(new SetCardInfo("Blinding Light", 5, Rarity.UNCOMMON, mage.cards.b.BlindingLight.class));
cards.add(new SetCardInfo("Blistering Barrier", 159, Rarity.COMMON, mage.cards.b.BlisteringBarrier.class));
cards.add(new SetCardInfo("Bone Harvest", 108, Rarity.COMMON, mage.cards.b.BoneHarvest.class));
@@ -78,6 +79,7 @@ public final class Mirage extends ExpansionSet {
cards.add(new SetCardInfo("Coral Fighters", 59, Rarity.UNCOMMON, mage.cards.c.CoralFighters.class));
cards.add(new SetCardInfo("Crash of Rhinos", 210, Rarity.COMMON, mage.cards.c.CrashOfRhinos.class));
cards.add(new SetCardInfo("Crimson Hellkite", 167, Rarity.RARE, mage.cards.c.CrimsonHellkite.class));
+ cards.add(new SetCardInfo("Crimson Roc", 168, Rarity.UNCOMMON, mage.cards.c.CrimsonRoc.class));
cards.add(new SetCardInfo("Crypt Cobra", 114, Rarity.UNCOMMON, mage.cards.c.CryptCobra.class));
cards.add(new SetCardInfo("Crystal Golem", 298, Rarity.UNCOMMON, mage.cards.c.CrystalGolem.class));
cards.add(new SetCardInfo("Crystal Vein", 325, Rarity.UNCOMMON, mage.cards.c.CrystalVein.class));
@@ -207,6 +209,7 @@ public final class Mirage extends ExpansionSet {
cards.add(new SetCardInfo("Mountain", 346, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Mtenda Griffin", 28, Rarity.UNCOMMON, mage.cards.m.MtendaGriffin.class));
cards.add(new SetCardInfo("Mtenda Herder", 29, Rarity.COMMON, mage.cards.m.MtendaHerder.class));
+ cards.add(new SetCardInfo("Mtenda Lion", 230, Rarity.COMMON, mage.cards.m.MtendaLion.class));
cards.add(new SetCardInfo("Mystical Tutor", 80, Rarity.UNCOMMON, mage.cards.m.MysticalTutor.class));
cards.add(new SetCardInfo("Natural Balance", 231, Rarity.RARE, mage.cards.n.NaturalBalance.class));
cards.add(new SetCardInfo("Nettletooth Djinn", 232, Rarity.UNCOMMON, mage.cards.n.NettletoothDjinn.class));
@@ -248,6 +251,7 @@ public final class Mirage extends ExpansionSet {
cards.add(new SetCardInfo("Reckless Embermage", 189, Rarity.RARE, mage.cards.r.RecklessEmbermage.class));
cards.add(new SetCardInfo("Regeneration", 236, Rarity.COMMON, mage.cards.r.Regeneration.class));
cards.add(new SetCardInfo("Reign of Chaos", 190, Rarity.UNCOMMON, mage.cards.r.ReignOfChaos.class));
+ cards.add(new SetCardInfo("Reign of Terror", 137, Rarity.UNCOMMON, mage.cards.r.ReignOfTerror.class));
cards.add(new SetCardInfo("Reparations", 278, Rarity.RARE, mage.cards.r.Reparations.class));
cards.add(new SetCardInfo("Restless Dead", 138, Rarity.COMMON, mage.cards.r.RestlessDead.class));
cards.add(new SetCardInfo("Ritual of Steel", 36, Rarity.COMMON, mage.cards.r.RitualOfSteel.class));
@@ -325,10 +329,12 @@ public final class Mirage extends ExpansionSet {
cards.add(new SetCardInfo("Volcanic Dragon", 201, Rarity.RARE, mage.cards.v.VolcanicDragon.class));
cards.add(new SetCardInfo("Volcanic Geyser", 202, Rarity.UNCOMMON, mage.cards.v.VolcanicGeyser.class));
cards.add(new SetCardInfo("Waiting in the Weeds", 252, Rarity.RARE, mage.cards.w.WaitingInTheWeeds.class));
+ cards.add(new SetCardInfo("Wall of Resistance", 46, Rarity.COMMON, mage.cards.w.WallOfResistance.class));
cards.add(new SetCardInfo("Wall of Roots", 253, Rarity.COMMON, mage.cards.w.WallOfRoots.class));
cards.add(new SetCardInfo("Ward of Lights", 47, Rarity.COMMON, mage.cards.w.WardOfLights.class));
cards.add(new SetCardInfo("Warping Wurm", 287, Rarity.RARE, mage.cards.w.WarpingWurm.class));
cards.add(new SetCardInfo("Wave Elemental", 102, Rarity.UNCOMMON, mage.cards.w.WaveElemental.class));
+ cards.add(new SetCardInfo("Wellspring", 288, Rarity.RARE, mage.cards.w.Wellspring.class));
cards.add(new SetCardInfo("Wild Elephant", 254, Rarity.COMMON, mage.cards.w.WildElephant.class));
cards.add(new SetCardInfo("Wildfire Emissary", 203, Rarity.UNCOMMON, mage.cards.w.WildfireEmissary.class));
cards.add(new SetCardInfo("Windreaper Falcon", 289, Rarity.UNCOMMON, mage.cards.w.WindreaperFalcon.class));
diff --git a/Mage.Sets/src/mage/sets/OathOfTheGatewatch.java b/Mage.Sets/src/mage/sets/OathOfTheGatewatch.java
index 538d9dc6851..80f4bae9c88 100644
--- a/Mage.Sets/src/mage/sets/OathOfTheGatewatch.java
+++ b/Mage.Sets/src/mage/sets/OathOfTheGatewatch.java
@@ -26,7 +26,7 @@ public final class OathOfTheGatewatch extends ExpansionSet {
return instance;
}
- protected final List savedSpecialLand = new ArrayList<>();
+ private final List