diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form
index 8008ce940d9..dcbf9fe7373 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form
+++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form
@@ -83,10 +83,10 @@
-
+
-
+
@@ -114,31 +114,31 @@
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
+
+
+
+
+
@@ -155,20 +155,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -183,6 +169,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -204,11 +209,9 @@
-
-
-
-
-
+
+
+
@@ -531,7 +534,7 @@
-
+
@@ -1223,7 +1226,7 @@
-
+
@@ -2097,7 +2100,7 @@
-
+
diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java
index 2d464312ebe..6199384a981 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java
@@ -54,6 +54,7 @@ import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
+import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.filechooser.FileFilter;
@@ -81,7 +82,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
private static final Logger log = Logger.getLogger(PreferencesDialog.class);
public static final String KEY_HAND_USE_BIG_CARDS = "handUseBigCards";
- public static final String KEY_SHOW_TOOLTIPS_ANY_ZONE = "showTooltipsInAnyZone";
+ public static final String KEY_SHOW_TOOLTIPS_DELAY = "showTooltipsDelay";
public static final String KEY_SHOW_CARD_NAMES = "showCardNames";
public static final String KEY_PERMANENTS_IN_ONE_PILE = "nonLandPermanentsInOnePile";
public static final String KEY_SHOW_PLAYER_NAMES_PERMANENTLY = "showPlayerNamesPermanently";
@@ -338,8 +339,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
tabMain = new javax.swing.JPanel();
main_card = new javax.swing.JPanel();
displayBigCardsInHand = new javax.swing.JCheckBox();
- showToolTipsInAnyZone = new javax.swing.JCheckBox();
showCardName = new javax.swing.JCheckBox();
+ tooltipDelayLabel = new javax.swing.JLabel();
+ tooltipDelay = new javax.swing.JSlider();
main_game = new javax.swing.JPanel();
nonLandPermanentsInOnePile = new javax.swing.JCheckBox();
showPlayerNamesPermanently = new javax.swing.JCheckBox();
@@ -478,17 +480,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
}
});
- showToolTipsInAnyZone.setSelected(true);
- showToolTipsInAnyZone.setText("Show card tooltips while hovering with the mouse pointer over a card");
- showToolTipsInAnyZone.setToolTipText("");
- showToolTipsInAnyZone.setActionCommand("");
- showToolTipsInAnyZone.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
- showToolTipsInAnyZone.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- showToolTipsInAnyZoneActionPerformed(evt);
- }
- });
-
showCardName.setSelected(true);
showCardName.setText("Show card name on card panel");
showCardName.setToolTipText("Write the card's name on the card to make the card name more recognizable.");
@@ -500,30 +491,45 @@ public class PreferencesDialog extends javax.swing.JDialog {
}
});
+ tooltipDelayLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
+ tooltipDelayLabel.setText("Delay in milliseconds for showing the card tooltip text");
+ tooltipDelayLabel.setToolTipText("The time the appearance of the tooltip window for a card is delayed.
\nIf set to zero, the tooltip window won't be shown at all.");
+
+ tooltipDelay.setMajorTickSpacing(1000);
+ tooltipDelay.setMaximum(5000);
+ tooltipDelay.setMinorTickSpacing(100);
+ tooltipDelay.setPaintLabels(true);
+ tooltipDelay.setPaintTicks(true);
+ tooltipDelay.setSnapToTicks(true);
+ tooltipDelay.setToolTipText("The time the appearance of the tooltip window for a card is delayed.
\nIf set to zero, the tooltip window won't be shown at all.");
+ tooltipDelay.setValue(300);
+
javax.swing.GroupLayout main_cardLayout = new javax.swing.GroupLayout(main_card);
main_card.setLayout(main_cardLayout);
main_cardLayout.setHorizontalGroup(
main_cardLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(main_cardLayout.createSequentialGroup()
- .addContainerGap()
+ .addGap(6, 6, 6)
.addGroup(main_cardLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(tooltipDelayLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(displayBigCardsInHand, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(tooltipDelay, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(main_cardLayout.createSequentialGroup()
- .addComponent(displayBigCardsInHand, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addContainerGap())
- .addGroup(main_cardLayout.createSequentialGroup()
- .addGroup(main_cardLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(showToolTipsInAnyZone)
- .addComponent(showCardName))
- .addGap(0, 0, Short.MAX_VALUE))))
+ .addComponent(showCardName)
+ .addGap(0, 0, Short.MAX_VALUE)))
+ .addContainerGap())
);
main_cardLayout.setVerticalGroup(
main_cardLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(main_cardLayout.createSequentialGroup()
.addComponent(displayBigCardsInHand)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(showToolTipsInAnyZone)
+ .addComponent(showCardName)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(showCardName))
+ .addComponent(tooltipDelayLabel)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(tooltipDelay, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addContainerGap())
);
main_game.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Game"));
@@ -603,10 +609,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addGroup(main_gameLayout.createSequentialGroup()
.addContainerGap()
.addGroup(main_gameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addGroup(main_gameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
- .addComponent(showPlayerNamesPermanently, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(nonLandPermanentsInOnePile, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(showAbilityPickerForced, javax.swing.GroupLayout.Alignment.LEADING))
+ .addComponent(showPlayerNamesPermanently, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(nonLandPermanentsInOnePile, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(showAbilityPickerForced)
.addComponent(cbConfirmEmptyManaPool, javax.swing.GroupLayout.DEFAULT_SIZE, 485, Short.MAX_VALUE)
.addComponent(cbAllowRequestToShowHandCards, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(cbShowStormCounter, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
@@ -691,10 +696,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
tabMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(tabMainLayout.createSequentialGroup()
.addContainerGap()
- .addComponent(main_card, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(main_card, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(main_game, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(main_gamelog, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
@@ -911,7 +916,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addComponent(jLabelEndOfTurn)
.addComponent(checkBoxEndTurnOthers))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(phases_stopSettings, javax.swing.GroupLayout.DEFAULT_SIZE, 183, Short.MAX_VALUE)
+ .addComponent(phases_stopSettings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap())
);
@@ -1696,7 +1701,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
);
tabAvatarsLayout.setVerticalGroup(
tabAvatarsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(avatarPane, javax.swing.GroupLayout.PREFERRED_SIZE, 418, Short.MAX_VALUE)
+ .addComponent(avatarPane, javax.swing.GroupLayout.PREFERRED_SIZE, 438, Short.MAX_VALUE)
);
tabsPanel.addTab("Avatars", tabAvatars);
@@ -1877,7 +1882,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addComponent(cbProxyType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(18, 18, 18)
.addComponent(pnlProxySettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addContainerGap(107, Short.MAX_VALUE))
+ .addContainerGap(127, Short.MAX_VALUE))
);
pnlProxySettings.getAccessibleContext().setAccessibleDescription("");
@@ -1931,7 +1936,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
// main
save(prefs, dialog.displayBigCardsInHand, KEY_HAND_USE_BIG_CARDS, "true", "false", UPDATE_CACHE_POLICY);
- save(prefs, dialog.showToolTipsInAnyZone, KEY_SHOW_TOOLTIPS_ANY_ZONE, "true", "false", UPDATE_CACHE_POLICY);
+ save(prefs, dialog.tooltipDelay, KEY_SHOW_TOOLTIPS_DELAY, "true", "false", UPDATE_CACHE_POLICY);
save(prefs, dialog.showCardName, KEY_SHOW_CARD_NAMES, "true", "false", UPDATE_CACHE_POLICY);
save(prefs, dialog.nonLandPermanentsInOnePile, KEY_PERMANENTS_IN_ONE_PILE, "true", "false", UPDATE_CACHE_POLICY);
save(prefs, dialog.showPlayerNamesPermanently, KEY_SHOW_PLAYER_NAMES_PERMANENTLY, "true", "false", UPDATE_CACHE_POLICY);
@@ -2222,10 +2227,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
// TODO add your handling code here:
}//GEN-LAST:event_cbEnableOtherSoundsActionPerformed
- private void showToolTipsInAnyZoneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showToolTipsInAnyZoneActionPerformed
- // TODO add your handling code here:
- }//GEN-LAST:event_showToolTipsInAnyZoneActionPerformed
-
private void cbStopAttackActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbStopAttackActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_cbStopAttackActionPerformed
@@ -2349,7 +2350,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
private static void loadPhases(Preferences prefs) {
load(prefs, dialog.displayBigCardsInHand, KEY_HAND_USE_BIG_CARDS, "true", "true");
- load(prefs, dialog.showToolTipsInAnyZone, KEY_SHOW_TOOLTIPS_ANY_ZONE, "true");
+ load(prefs, dialog.tooltipDelay, KEY_SHOW_TOOLTIPS_DELAY, "300");
load(prefs, dialog.showCardName, KEY_SHOW_CARD_NAMES, "true");
load(prefs, dialog.nonLandPermanentsInOnePile, KEY_PERMANENTS_IN_ONE_PILE, "true");
load(prefs, dialog.showPlayerNamesPermanently, KEY_SHOW_PLAYER_NAMES_PERMANENTLY, "true");
@@ -2573,6 +2574,18 @@ public class PreferencesDialog extends javax.swing.JDialog {
field.setText(prop);
}
+ private static void load(Preferences prefs, JSlider field, String propName, String defaultValue) {
+ String prop = prefs.get(propName, defaultValue);
+ int value;
+ try {
+ value = Integer.parseInt(prop);
+ } catch (NumberFormatException e) {
+ // It's OK to ignore "e" here because returning a default value is the documented behaviour on invalid input.
+ value = Integer.parseInt(defaultValue);
+ }
+ field.setValue(value);
+ }
+
private static void load(Preferences prefs, JComboBox field, String propName, String defaultValue) {
String prop = prefs.get(propName, defaultValue);
field.setSelectedItem(prop);
@@ -2602,6 +2615,13 @@ public class PreferencesDialog extends javax.swing.JDialog {
}
}
+ private static void save(Preferences prefs, JSlider slider, String propName, String yesValue, String noValue, boolean updateCache) {
+ prefs.put(propName, Integer.toString(slider.getValue()));
+ if (updateCache) {
+ updateCache(propName, Integer.toString(slider.getValue()));
+ }
+ }
+
private static void save(Preferences prefs, JTextField textField, String propName) {
prefs.put(propName, textField.getText().trim());
updateCache(propName, textField.getText().trim());
@@ -2616,6 +2636,18 @@ public class PreferencesDialog extends javax.swing.JDialog {
tabsPanel.setSelectedIndex(0);
}
+ public static int getCachedValue(String key, int def) {
+ String stringValue = getCachedValue(key, String.valueOf(def));
+ int value;
+ try {
+ value = Integer.parseInt(stringValue);
+ } catch (NumberFormatException e) {
+ // It's OK to ignore "e" here because returning a default value is the documented behaviour on invalid input.
+ value = def;
+ }
+ return value;
+ }
+
public static String getCachedValue(String key, String def) {
if (cache.containsKey(key)) {
return cache.get(key);
@@ -2852,7 +2884,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JCheckBox showAbilityPickerForced;
private javax.swing.JCheckBox showCardName;
private javax.swing.JCheckBox showPlayerNamesPermanently;
- private javax.swing.JCheckBox showToolTipsInAnyZone;
private javax.swing.JPanel sounds_backgroundMusic;
private javax.swing.JPanel sounds_clips;
private javax.swing.JPanel tabAvatars;
@@ -2862,6 +2893,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JPanel tabPhases;
private javax.swing.JPanel tabSounds;
private javax.swing.JTabbedPane tabsPanel;
+ private javax.swing.JSlider tooltipDelay;
+ private javax.swing.JLabel tooltipDelayLabel;
private javax.swing.JTextField txtBackgroundImagePath;
private javax.swing.JTextField txtBattlefieldIBGMPath;
private javax.swing.JTextField txtBattlefieldImagePath;
diff --git a/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java b/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java
index c236a42741b..9226a64c967 100644
--- a/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java
+++ b/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java
@@ -74,6 +74,7 @@ public class MageActionCallback implements ActionCallback {
private TransferData popupData;
private JComponent cardInfoPane;
private volatile boolean popupTextWindowOpen = false;
+ private int tooltipDelay;
enum EnlargedWindowState {
@@ -140,8 +141,8 @@ public class MageActionCallback implements ActionCallback {
private void showTooltipPopup(final TransferData data, final Component parentComponent, final Point parentPoint) {
if (data.component != null) {
- String showTooltips = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_ANY_ZONE, "true");
- if (showTooltips.equals("false")) {
+ tooltipDelay = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_DELAY, 300);
+ if (tooltipDelay == 0) {
return;
}
}
@@ -169,7 +170,7 @@ public class MageActionCallback implements ActionCallback {
ThreadUtils.threadPool2.submit(new Runnable() {
@Override
public void run() {
- ThreadUtils.sleep(300);
+ ThreadUtils.sleep(tooltipDelay);
if (tooltipCard == null || !tooltipCard.equals(data.card) || session == null || !popupTextWindowOpen || !enlargedWindowState.equals(EnlargedWindowState.CLOSED)) {
return;
diff --git a/Mage.Sets/src/mage/sets/alarareborn/SagesOfTheAnima.java b/Mage.Sets/src/mage/sets/alarareborn/SagesOfTheAnima.java
index 6c47d17f83a..95362b5c595 100644
--- a/Mage.Sets/src/mage/sets/alarareborn/SagesOfTheAnima.java
+++ b/Mage.Sets/src/mage/sets/alarareborn/SagesOfTheAnima.java
@@ -119,7 +119,7 @@ class SagesOfTheAnimaReplacementEffect extends ReplacementEffectImpl {
cards.remove(revealedCard);
}
}
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard());
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard());
while (player.canRespond() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game);
diff --git a/Mage.Sets/src/mage/sets/alliances/Browse.java b/Mage.Sets/src/mage/sets/alliances/Browse.java
index 407eeca3648..db9b35396c9 100644
--- a/Mage.Sets/src/mage/sets/alliances/Browse.java
+++ b/Mage.Sets/src/mage/sets/alliances/Browse.java
@@ -97,14 +97,13 @@ class BrowseEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
if (cards.size() > 0) {
player.lookAtCards("Browse", cards, game);
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put in your hand"));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put in your hand"));
if (player.choose(Outcome.Benefit, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/alliances/SoldeviSage1.java b/Mage.Sets/src/mage/sets/alliances/SoldeviSage1.java
index 0e262118d58..8f762f5fe25 100644
--- a/Mage.Sets/src/mage/sets/alliances/SoldeviSage1.java
+++ b/Mage.Sets/src/mage/sets/alliances/SoldeviSage1.java
@@ -110,7 +110,7 @@ class SoldeviSageEffect extends OneShotEffect {
}
if (drawnCards.size() > 0) {
- TargetCard cardToDiscard = new TargetCard(Zone.PICK, new FilterCard("card to discard"));
+ TargetCard cardToDiscard = new TargetCard(Zone.HAND, new FilterCard("card to discard"));
cardToDiscard.setNotTarget(true);
if (player.choose(Outcome.Discard, drawnCards, cardToDiscard, game)) {
Card card = player.getHand().get(cardToDiscard.getFirstTarget(), game);
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/BrunaLightOfAlabaster.java b/Mage.Sets/src/mage/sets/avacynrestored/BrunaLightOfAlabaster.java
index 574072de20b..8ce9357753f 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/BrunaLightOfAlabaster.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/BrunaLightOfAlabaster.java
@@ -27,8 +27,7 @@
*/
package mage.sets.avacynrestored;
-import mage.constants.CardType;
-import mage.constants.Rarity;
+import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksOrBlocksTriggeredAbility;
@@ -37,21 +36,22 @@ import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
+import mage.constants.CardType;
import mage.constants.Outcome;
+import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.filter.predicate.other.AuraCardCanAttachToPermanentId;
+import mage.filter.predicate.other.AuraPermanentCanAttachToPermanentId;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetCard;
import mage.target.TargetPermanent;
-import java.util.UUID;
-import mage.filter.predicate.other.AuraCardCanAttachToPermanentId;
-import mage.filter.predicate.other.AuraPermanentCanAttachToPermanentId;
/**
* @author noxx
*/
@@ -138,7 +138,7 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
int count = player.getHand().count(filterAuraCard, game);
while (player.canRespond() && count > 0 && player.chooseUse(Outcome.Benefit, "Attach an Aura from your hand?", source, game)) {
- TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard);
+ TargetCard targetAura = new TargetCard(Zone.HAND, filterAuraCard);
if (player.choose(Outcome.Benefit, player.getHand(), targetAura, game)) {
Card aura = game.getCard(targetAura.getFirstTarget());
if (aura != null) {
@@ -152,7 +152,7 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
count = player.getGraveyard().count(filterAuraCard, game);
while (player.canRespond() && count > 0 && player.chooseUse(Outcome.Benefit, "Attach an Aura from your graveyard?", source, game)) {
- TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard);
+ TargetCard targetAura = new TargetCard(Zone.GRAVEYARD, filterAuraCard);
if (player.choose(Outcome.Benefit, player.getGraveyard(), targetAura, game)) {
Card aura = game.getCard(targetAura.getFirstTarget());
if (aura != null) {
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/LairDelve.java b/Mage.Sets/src/mage/sets/avacynrestored/LairDelve.java
index 0021f383139..46fa4bd7673 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/LairDelve.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/LairDelve.java
@@ -38,10 +38,8 @@ import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardsImpl;
-import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
-import mage.target.TargetCard;
/**
*
@@ -106,20 +104,7 @@ class LairDelveEffect extends OneShotEffect {
}
}
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
- while (player.canRespond() && cards.size() > 1) {
- player.choose(Outcome.Neutral, cards, target, game);
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
- target.clearChosen();
- }
- if (cards.size() == 1) {
- Card card = cards.get(cards.iterator().next(), game);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
+ player.putCardsOnBottomOfLibrary(cards, game, source, true);
return true;
}
diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java b/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java
index 64440a19c86..5cad5cf83be 100644
--- a/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java
+++ b/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java
@@ -173,7 +173,7 @@ class KioraRevealEffect extends OneShotEffect {
if ((creatureCardFound || landCardFound)
&& controller.chooseUse(Outcome.DrawCard,
"Put a creature card and/or a land card into your hand?", source, game)) {
- TargetCard target = new TargetCard(Zone.PICK, new FilterCreatureCard("creature card to put into your hand"));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCreatureCard("creature card to put into your hand"));
if (creatureCardFound && controller.chooseTarget(Outcome.DrawCard, cards, target, source, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/bornofthegods/HeroesPodium.java b/Mage.Sets/src/mage/sets/bornofthegods/HeroesPodium.java
index 9aa39c10839..fa6145a76c9 100644
--- a/Mage.Sets/src/mage/sets/bornofthegods/HeroesPodium.java
+++ b/Mage.Sets/src/mage/sets/bornofthegods/HeroesPodium.java
@@ -165,7 +165,6 @@ class HeroesPodiumEffect extends OneShotEffect {
if (filter.match(card, game)) {
legendaryIncluded = true;
}
- game.setZone(card.getId(), Zone.PICK);
}
}
player.lookAtCards("Heroes' Podium", cards, game);
@@ -178,7 +177,7 @@ class HeroesPodiumEffect extends OneShotEffect {
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
return true;
} else {
- TargetCard target = new TargetCard(Zone.PICK, filter);
+ TargetCard target = new TargetCard(Zone.LIBRARY, filter);
if (player.choose(outcome, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/bornofthegods/LoyalPegasus.java b/Mage.Sets/src/mage/sets/bornofthegods/LoyalPegasus.java
index 0a01871d90d..bd2ab37453b 100644
--- a/Mage.Sets/src/mage/sets/bornofthegods/LoyalPegasus.java
+++ b/Mage.Sets/src/mage/sets/bornofthegods/LoyalPegasus.java
@@ -53,7 +53,7 @@ public class LoyalPegasus extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// Loyal Pegasus can't attack or block alone.
- this.addAbility(CantAttackAloneAbility.getInstance());
+ this.addAbility(new CantAttackAloneAbility());
this.addAbility(CantBlockAloneAbility.getInstance());
}
diff --git a/Mage.Sets/src/mage/sets/commander/KodamasReach.java b/Mage.Sets/src/mage/sets/commander/KodamasReach.java
index 103a617285c..19c3bae05cf 100644
--- a/Mage.Sets/src/mage/sets/commander/KodamasReach.java
+++ b/Mage.Sets/src/mage/sets/commander/KodamasReach.java
@@ -106,7 +106,7 @@ class KodamasReachEffect extends OneShotEffect {
}
controller.revealCards(sourceObject.getIdName(), revealed, game);
if (target.getTargets().size() == 2) {
- TargetCard target2 = new TargetCard(Zone.PICK, filter);
+ TargetCard target2 = new TargetCard(Zone.LIBRARY, filter);
controller.choose(Outcome.Benefit, revealed, target2, game);
Card card = revealed.get(target2.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/commander2013/AEthermagesTouch.java b/Mage.Sets/src/mage/sets/commander2013/AEthermagesTouch.java
index 5f4e767c3db..f50c8cdaae4 100644
--- a/Mage.Sets/src/mage/sets/commander2013/AEthermagesTouch.java
+++ b/Mage.Sets/src/mage/sets/commander2013/AEthermagesTouch.java
@@ -112,12 +112,12 @@ class AEthermagesTouchEffect extends OneShotEffect {
if (!cards.isEmpty()) {
player.revealCards("AEthermage's Touch", cards, game);
- TargetCard target = new TargetCard(Zone.PICK, filterPutOntoBattlefield);
+ TargetCard target = new TargetCard(Zone.LIBRARY, filterPutOntoBattlefield);
if (properCardFound && player.choose(Outcome.PutCreatureInPlay, cards, target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
cards.remove(card);
- if (card.putOntoBattlefield(game, Zone.PICK, source.getSourceId(), source.getControllerId())) {
+ if (card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId())) {
// It gains \"At the beginning of your end step, return this creature to its owner's hand.\"
Ability ability = new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(true), TargetController.YOU, null, false);
ContinuousEffect effect = new GainAbilityTargetEffect(ability, Duration.Custom);
diff --git a/Mage.Sets/src/mage/sets/commander2013/LimDulsVault.java b/Mage.Sets/src/mage/sets/commander2013/LimDulsVault.java
index 10b1524f4f0..b3a64dece08 100644
--- a/Mage.Sets/src/mage/sets/commander2013/LimDulsVault.java
+++ b/Mage.Sets/src/mage/sets/commander2013/LimDulsVault.java
@@ -101,7 +101,6 @@ class LimDulsVaultEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
player.lookAtCards("Lim-Dul's Vault", cards, game);
@@ -112,7 +111,7 @@ class LimDulsVaultEffect extends OneShotEffect {
player.shuffleLibrary(game);
}
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard(doAgain ? textBottom : textTop));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard(doAgain ? textBottom : textTop));
while (player.canRespond() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game);
diff --git a/Mage.Sets/src/mage/sets/commander2015/ArjunTheShiftingFlame.java b/Mage.Sets/src/mage/sets/commander2015/ArjunTheShiftingFlame.java
index 2c146818d31..f716946b9fb 100644
--- a/Mage.Sets/src/mage/sets/commander2015/ArjunTheShiftingFlame.java
+++ b/Mage.Sets/src/mage/sets/commander2015/ArjunTheShiftingFlame.java
@@ -33,18 +33,12 @@ import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlyingAbility;
-import mage.cards.Card;
import mage.cards.CardImpl;
-import mage.cards.Cards;
-import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
-import mage.constants.Zone;
-import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
-import mage.target.TargetCard;
/**
*
@@ -94,25 +88,7 @@ class ArjunTheShiftingFlameEffect extends OneShotEffect {
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
int count = you.getHand().size();
- Cards cards = new CardsImpl();
- for (Card card : you.getHand().getCards(game)) {
- cards.add(card.getId());
- }
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
- while (you.canRespond() && cards.size() > 1) {
- you.choose(Outcome.Neutral, cards, target, game);
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
- target.clearChosen();
- }
- if (cards.size() == 1) {
- Card card = cards.get(cards.iterator().next(), game);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
- you.getHand().clear();
+ you.putCardsOnBottomOfLibrary(you.getHand(), game, source, true);
you.drawCards(count, game);
}
return true;
diff --git a/Mage.Sets/src/mage/sets/conflux/WorldlyCounsel.java b/Mage.Sets/src/mage/sets/conflux/WorldlyCounsel.java
index bd8ded0fbfb..d288aecf7d7 100644
--- a/Mage.Sets/src/mage/sets/conflux/WorldlyCounsel.java
+++ b/Mage.Sets/src/mage/sets/conflux/WorldlyCounsel.java
@@ -99,7 +99,6 @@ class WorldlyCounselEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
player.lookAtCards("Worldly Counsel", cards, game);
@@ -111,7 +110,7 @@ class WorldlyCounselEffect extends OneShotEffect {
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
return true;
} else {
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put into your hand"));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into your hand"));
if (player.choose(Outcome.DrawCard, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
@@ -121,22 +120,7 @@ class WorldlyCounselEffect extends OneShotEffect {
}
}
}
-
-
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
- while (cards.size() > 1) {
- player.choose(Outcome.Neutral, cards, target, game);
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
- target.clearChosen();
- }
- if (cards.size() == 1) {
- Card card = cards.get(cards.iterator().next(), game);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
+ player.putCardsOnBottomOfLibrary(cards, game, source, true);
return true;
}
}
diff --git a/Mage.Sets/src/mage/sets/darkascension/CallToTheKindred.java b/Mage.Sets/src/mage/sets/darkascension/CallToTheKindred.java
index 7f880c0f522..ba5bd4e5c11 100644
--- a/Mage.Sets/src/mage/sets/darkascension/CallToTheKindred.java
+++ b/Mage.Sets/src/mage/sets/darkascension/CallToTheKindred.java
@@ -43,7 +43,6 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
-import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.Predicates;
@@ -125,7 +124,6 @@ class CallToTheKindredEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
player.lookAtCards("Call to the Kindred", cards, game);
@@ -142,32 +140,17 @@ class CallToTheKindredEffect extends OneShotEffect {
filter.setMessage(sb.toString());
if (cards.count(filter, game) > 0 && player.chooseUse(Outcome.DrawCard, "Do you wish to put a creature card onto the battlefield?", source, game)) {
- TargetCard target = new TargetCard(Zone.PICK, filter);
+ TargetCard target = new TargetCard(Zone.LIBRARY, filter);
if (player.choose(Outcome.PutCreatureInPlay, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
cards.remove(card);
- card.putOntoBattlefield(game, Zone.PICK, source.getSourceId(), source.getControllerId());
+ card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId());
}
}
}
-
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
- while (player.canRespond() && cards.size() > 1) {
- player.choose(Outcome.Neutral, cards, target, game);
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
- target.clearChosen();
- }
- if (cards.size() == 1) {
- Card card = cards.get(cards.iterator().next(), game);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
-
+ player.putCardsOnBottomOfLibrary(cards, game, source, true);
return true;
}
}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/sets/darkascension/GruesomeDiscovery.java b/Mage.Sets/src/mage/sets/darkascension/GruesomeDiscovery.java
index a9223d9c4af..3192b0f5a16 100644
--- a/Mage.Sets/src/mage/sets/darkascension/GruesomeDiscovery.java
+++ b/Mage.Sets/src/mage/sets/darkascension/GruesomeDiscovery.java
@@ -29,10 +29,6 @@ package mage.sets.darkascension;
import java.util.List;
import java.util.UUID;
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Rarity;
-import mage.constants.Zone;
import mage.abilities.Ability;
import mage.abilities.condition.common.MorbidCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
@@ -40,6 +36,10 @@ import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.discard.DiscardTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
@@ -105,7 +105,7 @@ class GruesomeDiscoveryEffect extends OneShotEffect {
targetPlayer.discard(2, source, game);
}
- TargetCard target = new TargetCard(2, Zone.PICK, new FilterCard());
+ TargetCard target = new TargetCard(2, Zone.HAND, new FilterCard());
if (player.choose(Outcome.Benefit, targetPlayer.getHand(), target, game)) {
List targets = target.getTargets();
for (UUID targetId : targets) {
diff --git a/Mage.Sets/src/mage/sets/darkascension/JarOfEyeballs.java b/Mage.Sets/src/mage/sets/darkascension/JarOfEyeballs.java
index 857ff6a3238..d8a5d62eb25 100644
--- a/Mage.Sets/src/mage/sets/darkascension/JarOfEyeballs.java
+++ b/Mage.Sets/src/mage/sets/darkascension/JarOfEyeballs.java
@@ -203,12 +203,11 @@ class JarOfEyeballsEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
player.lookAtCards("Jar of Eyeballs", cards, game);
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put into your hand"));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into your hand"));
if (player.choose(Outcome.DrawCard, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
@@ -216,22 +215,7 @@ class JarOfEyeballsEffect extends OneShotEffect {
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
}
}
-
- target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
- while (cards.size() > 1) {
- player.choose(Outcome.Neutral, cards, target, game);
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
- target.clearChosen();
- }
- if (cards.size() == 1) {
- Card card = cards.get(cards.iterator().next(), game);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
-
+ player.putCardsOnBottomOfLibrary(cards, game, source, true);
return true;
}
}
diff --git a/Mage.Sets/src/mage/sets/dissension/ResearchDevelopment.java b/Mage.Sets/src/mage/sets/dissension/ResearchDevelopment.java
index 959e9e2fc81..7f8df2846f9 100644
--- a/Mage.Sets/src/mage/sets/dissension/ResearchDevelopment.java
+++ b/Mage.Sets/src/mage/sets/dissension/ResearchDevelopment.java
@@ -27,6 +27,8 @@
*/
package mage.sets.dissension;
+import java.util.Set;
+import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
@@ -44,9 +46,6 @@ import mage.game.permanent.token.ElementalToken;
import mage.players.Player;
import mage.target.TargetCard;
-import java.util.Set;
-import java.util.UUID;
-
/**
*
* @author magenoxx
@@ -120,7 +119,7 @@ class ResearchEffect extends OneShotEffect {
filteredCards.add(card.getId());
}
- TargetCard target = new TargetCard(Zone.PICK, filter);
+ TargetCard target = new TargetCard(Zone.OUTSIDE, filter);
if (player.choose(Outcome.Benefit, filteredCards, target, game)) {
Card card = player.getSideboard().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/MasterOfCruelties.java b/Mage.Sets/src/mage/sets/dragonsmaze/MasterOfCruelties.java
index 776570e5a0f..50a8dd16d8a 100644
--- a/Mage.Sets/src/mage/sets/dragonsmaze/MasterOfCruelties.java
+++ b/Mage.Sets/src/mage/sets/dragonsmaze/MasterOfCruelties.java
@@ -69,7 +69,7 @@ public class MasterOfCruelties extends CardImpl {
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
// Master of Cruelties can only attack alone.
- this.addAbility(CanAttackOnlyAloneAbility.getInstance());
+ this.addAbility(new CanAttackOnlyAloneAbility());
// Whenever Master of Cruelties attacks a player and isn't blocked, that player's life total becomes 1. Master of Cruelties assigns no combat damage this combat.
this.addAbility(new MasterOfCrueltiesTriggeredAbility());
@@ -111,7 +111,7 @@ class MasterOfCrueltiesTriggeredAbility extends TriggeredAbilityImpl {
public boolean checkTrigger(GameEvent event, Game game) {
Permanent sourcePermanent = game.getPermanent(getSourceId());
if (sourcePermanent.isAttacking()) {
- for (CombatGroup combatGroup: game.getCombat().getGroups()) {
+ for (CombatGroup combatGroup : game.getCombat().getGroups()) {
if (combatGroup.getBlockers().isEmpty() && combatGroup.getAttackers().contains(getSourceId())) {
// check if a player is attacked (instead of a planeswalker)
Player defendingPlayer = game.getPlayer(combatGroup.getDefenderId());
@@ -184,11 +184,11 @@ class MasterOfCrueltiesNoDamageEffect extends ContinuousRuleModifyingEffectImpl
return false;
}
}
-
+
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
DamageEvent damageEvent = (DamageEvent) event;
- return event.getSourceId().equals(source.getSourceId()) && damageEvent.isCombatDamage();
-
+ return event.getSourceId().equals(source.getSourceId()) && damageEvent.isCombatDamage();
+
}
}
diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/BlessedReincarnation.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/BlessedReincarnation.java
index b2a0500f83a..346ae0439ef 100644
--- a/Mage.Sets/src/mage/sets/dragonsoftarkir/BlessedReincarnation.java
+++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/BlessedReincarnation.java
@@ -125,7 +125,7 @@ class BlessedReincarnationEffect extends OneShotEffect {
}
if (card.getCardType().contains(CardType.CREATURE)) {
- card.putOntoBattlefield(game, Zone.PICK, source.getSourceId(), player.getId());
+ card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId());
}
if (cards.size() > 0) {
diff --git a/Mage.Sets/src/mage/sets/eventide/Evershrike.java b/Mage.Sets/src/mage/sets/eventide/Evershrike.java
index 776939f0dcd..e764436aead 100644
--- a/Mage.Sets/src/mage/sets/eventide/Evershrike.java
+++ b/Mage.Sets/src/mage/sets/eventide/Evershrike.java
@@ -123,7 +123,7 @@ class EvershrikeEffect extends OneShotEffect {
filterAuraCard.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, xAmount));
int count = controller.getHand().count(filterAuraCard, game);
while (controller.canRespond() && count > 0 && controller.chooseUse(Outcome.Benefit, "Do you wish to put an Aura card from your hand onto Evershrike", source, game)) {
- TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard);
+ TargetCard targetAura = new TargetCard(Zone.HAND, filterAuraCard);
if (controller.choose(Outcome.Benefit, controller.getHand(), targetAura, game)) {
Card aura = game.getCard(targetAura.getFirstTarget());
if (aura != null) {
diff --git a/Mage.Sets/src/mage/sets/eventide/TalarasBane.java b/Mage.Sets/src/mage/sets/eventide/TalarasBane.java
index 13902a46f22..62e483c7bac 100644
--- a/Mage.Sets/src/mage/sets/eventide/TalarasBane.java
+++ b/Mage.Sets/src/mage/sets/eventide/TalarasBane.java
@@ -105,7 +105,7 @@ class TalarasBaneEffect extends OneShotEffect {
Card card = null;
if (targetPlayer != null && you != null) {
targetPlayer.revealCards("Talaras Bane", targetPlayer.getHand(), game);
- TargetCard target = new TargetCard(Zone.PICK, filter);
+ TargetCard target = new TargetCard(Zone.HAND, filter);
if (you.choose(Outcome.Benefit, targetPlayer.getHand(), target, game)) {
card = targetPlayer.getHand().get(target.getFirstTarget(), game);
}
diff --git a/Mage.Sets/src/mage/sets/fifthdawn/PlungeIntoDarkness.java b/Mage.Sets/src/mage/sets/fifthdawn/PlungeIntoDarkness.java
index ecfc295f542..f43581055ab 100644
--- a/Mage.Sets/src/mage/sets/fifthdawn/PlungeIntoDarkness.java
+++ b/Mage.Sets/src/mage/sets/fifthdawn/PlungeIntoDarkness.java
@@ -156,12 +156,11 @@ class PlungeIntoDarknessSearchEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
player.lookAtCards("Plunge into Darkness", cards, game);
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put into your hand"));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into your hand"));
if (player.choose(Outcome.DrawCard, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/fifthdawn/PossessedPortal.java b/Mage.Sets/src/mage/sets/fifthdawn/PossessedPortal.java
new file mode 100644
index 00000000000..246be1f7596
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/fifthdawn/PossessedPortal.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.sets.fifthdawn;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.Cost;
+import mage.abilities.costs.common.DiscardCardCost;
+import mage.abilities.costs.common.SacrificeTargetCost;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.ReplacementEffectImpl;
+import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.players.Player;
+import mage.target.common.TargetControlledPermanent;
+
+/**
+ *
+ * @author emerald000
+ */
+public class PossessedPortal extends CardImpl {
+
+ public PossessedPortal(UUID ownerId) {
+ super(ownerId, 144, "Possessed Portal", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{8}");
+ this.expansionSetCode = "5DN";
+
+ // 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.
+ this.addAbility(new BeginningOfEndStepTriggeredAbility(new PossessedPortalEffect(), TargetController.ANY, false));
+ }
+
+ public PossessedPortal(final PossessedPortal card) {
+ super(card);
+ }
+
+ @Override
+ public PossessedPortal copy() {
+ return new PossessedPortal(this);
+ }
+}
+
+class PossessedPortalReplacementEffect extends ReplacementEffectImpl {
+
+ PossessedPortalReplacementEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.Neutral);
+ this.staticText = "If a player would draw a card, that player skips that draw instead";
+ }
+
+ PossessedPortalReplacementEffect(final PossessedPortalReplacementEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public PossessedPortalReplacementEffect copy() {
+ return new PossessedPortalReplacementEffect(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.DRAW_CARD;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ return true;
+ }
+}
+
+class PossessedPortalEffect extends OneShotEffect {
+
+ PossessedPortalEffect() {
+ super(Outcome.Benefit);
+ this.staticText = "each player sacrifices a permanent unless he or she discards a card";
+ }
+
+ PossessedPortalEffect(final PossessedPortalEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public PossessedPortalEffect copy() {
+ return new PossessedPortalEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
+ Player player = game.getPlayer(playerId);
+ Cost discardCost = new DiscardCardCost();
+ if (discardCost.canPay(source, source.getSourceId(), playerId, game)
+ && player.chooseUse(Outcome.Discard, "Discard a card? (Otherwise sacrifice a permanent)", source, game)) {
+ discardCost.pay(source, game, source.getSourceId(), playerId, true);
+ }
+ else {
+ Cost sacrificeCost = new SacrificeTargetCost(new TargetControlledPermanent());
+ sacrificeCost.pay(source, game, source.getSourceId(), playerId, true);
+ }
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/fifthedition/SylvanLibrary.java b/Mage.Sets/src/mage/sets/fifthedition/SylvanLibrary.java
index d20b20c4158..113e73b9d49 100644
--- a/Mage.Sets/src/mage/sets/fifthedition/SylvanLibrary.java
+++ b/Mage.Sets/src/mage/sets/fifthedition/SylvanLibrary.java
@@ -136,7 +136,7 @@ class SylvanLibraryEffect extends OneShotEffect {
}
int numberOfCardsToPutBack = cardsPutBack.size();
if (numberOfCardsToPutBack > 1) {
- TargetCard target2 = new TargetCard(Zone.PICK, new FilterCard("card to put on the top of your library (last chosen will be on top)"));
+ TargetCard target2 = new TargetCard(Zone.HAND, new FilterCard("card to put on the top of your library (last chosen will be on top)"));
while (controller.canRespond() && cardsPutBack.size() > 1) {
controller.choose(Outcome.Benefit, cardsPutBack, target2, game);
Card card = cardsPutBack.get(target2.getFirstTarget(), game);
diff --git a/Mage.Sets/src/mage/sets/futuresight/GlitteringWish.java b/Mage.Sets/src/mage/sets/futuresight/GlitteringWish.java
index 9f2aa2e6e1a..102dbe5da1c 100644
--- a/Mage.Sets/src/mage/sets/futuresight/GlitteringWish.java
+++ b/Mage.Sets/src/mage/sets/futuresight/GlitteringWish.java
@@ -29,9 +29,6 @@ package mage.sets.futuresight;
import java.util.Set;
import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Rarity;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
@@ -39,7 +36,9 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
+import mage.constants.CardType;
import mage.constants.Outcome;
+import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicate;
@@ -128,7 +127,7 @@ class GlitteringWishEffect extends OneShotEffect {
filteredCards.add(card.getId());
}
- TargetCard target = new TargetCard(Zone.PICK, filter);
+ TargetCard target = new TargetCard(Zone.OUTSIDE, filter);
if (player.choose(Outcome.Benefit, filteredCards, target, game)) {
Card card = player.getSideboard().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/gatecrash/DimirCharm.java b/Mage.Sets/src/mage/sets/gatecrash/DimirCharm.java
index eca00ed3f00..df95815b303 100644
--- a/Mage.Sets/src/mage/sets/gatecrash/DimirCharm.java
+++ b/Mage.Sets/src/mage/sets/gatecrash/DimirCharm.java
@@ -119,7 +119,6 @@ class DimirCharmEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if(card != null){
cards.add(card);
- game.getState().setZone(card.getId(), Zone.PICK);
}
}
if(cards.size() > 0){
diff --git a/Mage.Sets/src/mage/sets/gatecrash/EmberBeast.java b/Mage.Sets/src/mage/sets/gatecrash/EmberBeast.java
index 77ebea7de25..3451bdc4a57 100644
--- a/Mage.Sets/src/mage/sets/gatecrash/EmberBeast.java
+++ b/Mage.Sets/src/mage/sets/gatecrash/EmberBeast.java
@@ -28,12 +28,12 @@
package mage.sets.gatecrash;
import java.util.UUID;
-import mage.constants.CardType;
-import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.keyword.CantAttackAloneAbility;
import mage.abilities.keyword.CantBlockAloneAbility;
import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Rarity;
/**
*
@@ -50,7 +50,7 @@ public class EmberBeast extends CardImpl {
this.toughness = new MageInt(4);
// Ember Beast can't attack or block alone.
- this.addAbility(CantAttackAloneAbility.getInstance());
+ this.addAbility(new CantAttackAloneAbility());
this.addAbility(CantBlockAloneAbility.getInstance());
}
diff --git a/Mage.Sets/src/mage/sets/gatecrash/LordOfTheVoid.java b/Mage.Sets/src/mage/sets/gatecrash/LordOfTheVoid.java
index 124f66d644f..8c8719399de 100644
--- a/Mage.Sets/src/mage/sets/gatecrash/LordOfTheVoid.java
+++ b/Mage.Sets/src/mage/sets/gatecrash/LordOfTheVoid.java
@@ -1,5 +1,5 @@
/*
-/*
+ /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
@@ -29,10 +29,6 @@
package mage.sets.gatecrash;
import java.util.UUID;
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Rarity;
-import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
@@ -42,6 +38,10 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.players.Player;
@@ -58,13 +58,12 @@ public class LordOfTheVoid extends CardImpl {
this.expansionSetCode = "GTC";
this.subtype.add("Demon");
-
this.power = new MageInt(7);
this.toughness = new MageInt(7);
//Flying
this.addAbility(FlyingAbility.getInstance());
-
+
//Whenever Lord of the Void deals combat damage to a player, exile the top seven cards of that player's library, then put a creature card from among them onto the battlefield under your control.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new LordOfTheVoidEffect(), false, true));
}
@@ -79,11 +78,10 @@ public class LordOfTheVoid extends CardImpl {
}
}
-
class LordOfTheVoidEffect extends OneShotEffect {
public LordOfTheVoidEffect() {
- super(Outcome.PutCardInPlay);
+ super(Outcome.PutCreatureInPlay);
this.staticText = "exile the top seven cards of that player's library, then put a creature card from among them onto the battlefield under your control";
}
@@ -103,22 +101,16 @@ class LordOfTheVoidEffect extends OneShotEffect {
if (player == null || controller == null) {
return false;
}
-
+
Cards cards = new CardsImpl();
- int max = Math.min(player.getLibrary().size(), 7);
- for(int i = 0; i < max; i++){
- Card card = player.getLibrary().removeFromTop(game);
- if (card != null) {
- card.moveToExile(null, "", source.getSourceId(), game);
- cards.add(card);
- }
- }
- if(cards.getCards(new FilterCreatureCard(), game).size() > 0){
+ cards.addAll(player.getLibrary().getTopCards(game, 7));
+ controller.moveCards(cards, Zone.EXILED, source, game);
+ if (cards.getCards(new FilterCreatureCard(), game).size() > 0) {
TargetCard target = new TargetCard(Zone.EXILED, new FilterCreatureCard());
- if(controller.chooseTarget(Outcome.PutCreatureInPlay, cards, target, source, game)){
+ if (controller.chooseTarget(outcome, cards, target, source, game)) {
Card card = cards.get(target.getFirstTarget(), game);
- if(card != null){
- card.putOntoBattlefield(game, Zone.EXILED, source.getSourceId(), source.getControllerId());
+ if (card != null) {
+ controller.moveCards(cards.getCards(game), Zone.BATTLEFIELD, source, game, false, false, false, null);
}
}
}
diff --git a/Mage.Sets/src/mage/sets/iceage/OrcishLibrarian.java b/Mage.Sets/src/mage/sets/iceage/OrcishLibrarian.java
index ed8f653acad..1904068c864 100644
--- a/Mage.Sets/src/mage/sets/iceage/OrcishLibrarian.java
+++ b/Mage.Sets/src/mage/sets/iceage/OrcishLibrarian.java
@@ -105,7 +105,6 @@ class OrcishLibrarianEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
@@ -120,7 +119,7 @@ class OrcishLibrarianEffect extends OneShotEffect {
}
}
player.lookAtCards("OrcishLibrarian", cards, game);
- TargetCard target = new TargetCard (Zone.PICK, new FilterCard("card to put on the top of target player's library"));
+ TargetCard target = new TargetCard (Zone.LIBRARY, new FilterCard("card to put on the top of target player's library"));
while (player.canRespond() && cards.size() > 0) {
player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game);
diff --git a/Mage.Sets/src/mage/sets/innistrad/ForbiddenAlchemy.java b/Mage.Sets/src/mage/sets/innistrad/ForbiddenAlchemy.java
index 0ff05dc5e7b..8a110da6ef4 100644
--- a/Mage.Sets/src/mage/sets/innistrad/ForbiddenAlchemy.java
+++ b/Mage.Sets/src/mage/sets/innistrad/ForbiddenAlchemy.java
@@ -100,14 +100,13 @@ class ForbiddenAlchemyEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
if (cards.size() > 0) {
player.lookAtCards("Forbidden Alchemy", cards, game);
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put in your hand"));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put in your hand"));
if (player.choose(Outcome.Benefit, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/innistrad/NightTerrors.java b/Mage.Sets/src/mage/sets/innistrad/NightTerrors.java
index f8dc2b78031..2c42fbd3b2e 100644
--- a/Mage.Sets/src/mage/sets/innistrad/NightTerrors.java
+++ b/Mage.Sets/src/mage/sets/innistrad/NightTerrors.java
@@ -91,7 +91,7 @@ class NightTerrorsEffect extends OneShotEffect {
if (player != null && targetPlayer != null) {
targetPlayer.revealCards("Night Terrors", targetPlayer.getHand(), game);
- TargetCard target = new TargetCard(Zone.PICK, new FilterNonlandCard("nonland card to exile"));
+ TargetCard target = new TargetCard(Zone.HAND, new FilterNonlandCard("nonland card to exile"));
if (player.choose(Outcome.Exile, targetPlayer.getHand(), target, game)) {
Card card = targetPlayer.getHand().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/invasion/RevivingVapors.java b/Mage.Sets/src/mage/sets/invasion/RevivingVapors.java
index d867fbc732b..5d990487002 100644
--- a/Mage.Sets/src/mage/sets/invasion/RevivingVapors.java
+++ b/Mage.Sets/src/mage/sets/invasion/RevivingVapors.java
@@ -104,7 +104,7 @@ class RevivingVaporsEffect extends OneShotEffect {
if (cards.size() == 1) {
card = cards.getRandom(game);
} else {
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put into your hand"));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into your hand"));
target.setRequired(true);
if (controller.choose(Outcome.DrawCard, cards, target, game)) {
card = cards.get(target.getFirstTarget(), game);
diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/SightlessBrawler.java b/Mage.Sets/src/mage/sets/journeyintonyx/SightlessBrawler.java
index c12742e364e..8ef66a7f064 100644
--- a/Mage.Sets/src/mage/sets/journeyintonyx/SightlessBrawler.java
+++ b/Mage.Sets/src/mage/sets/journeyintonyx/SightlessBrawler.java
@@ -32,12 +32,11 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.combat.CanAttackOnlyAloneEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
-import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.BestowAbility;
import mage.abilities.keyword.CantAttackAloneAbility;
import mage.cards.CardImpl;
-import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
@@ -61,16 +60,16 @@ public class SightlessBrawler extends CardImpl {
// Bestow 4W (If you cast this card for its bestow cost, it's an Aura spell with enchant creature. It becomes a creature again if it's not attached to a creature.)
this.addAbility(new BestowAbility(this, "{4}{W}"));
// Sightless Brawler can't attack alone.
- this.addAbility(CantAttackAloneAbility.getInstance());
+ this.addAbility(new CantAttackAloneAbility());
// Enchanted creature gets +3/+2 and can't attack alone.
- Effect effect = new BoostEnchantedEffect(3,2, Duration.WhileOnBattlefield);
+ Effect effect = new BoostEnchantedEffect(3, 2, Duration.WhileOnBattlefield);
effect.setText("Enchanted creature gets +3/+2");
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
- effect = new GainAbilityAttachedEffect(CantAttackAloneAbility.getInstance(), AttachmentType.AURA, Duration.WhileOnBattlefield);
+ effect = new CanAttackOnlyAloneEffect();
effect.setText("and can't attack alone");
ability.addEffect(effect);
- this.addAbility(ability);
-
+ this.addAbility(ability);
+
}
public SightlessBrawler(final SightlessBrawler card) {
diff --git a/Mage.Sets/src/mage/sets/judgment/BurningWish.java b/Mage.Sets/src/mage/sets/judgment/BurningWish.java
index 8036f321e15..b4a1b6de5a6 100644
--- a/Mage.Sets/src/mage/sets/judgment/BurningWish.java
+++ b/Mage.Sets/src/mage/sets/judgment/BurningWish.java
@@ -29,16 +29,15 @@ package mage.sets.judgment;
import java.util.Set;
import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
+import mage.constants.CardType;
import mage.constants.Outcome;
+import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.CardTypePredicate;
@@ -116,7 +115,7 @@ class BurningWishEffect extends OneShotEffect {
filteredCards.add(card.getId());
}
- TargetCard target = new TargetCard(Zone.PICK, filter);
+ TargetCard target = new TargetCard(Zone.OUTSIDE, filter);
if (player.choose(Outcome.Benefit, filteredCards, target, game)) {
Card card = player.getSideboard().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/judgment/CunningWish.java b/Mage.Sets/src/mage/sets/judgment/CunningWish.java
index 3a334aab0da..2ded7e0fa2e 100644
--- a/Mage.Sets/src/mage/sets/judgment/CunningWish.java
+++ b/Mage.Sets/src/mage/sets/judgment/CunningWish.java
@@ -29,16 +29,15 @@ package mage.sets.judgment;
import java.util.Set;
import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
+import mage.constants.CardType;
import mage.constants.Outcome;
+import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.CardTypePredicate;
@@ -116,7 +115,7 @@ class CunningWishEffect extends OneShotEffect {
filteredCards.add(card.getId());
}
- TargetCard target = new TargetCard(Zone.PICK, filter);
+ TargetCard target = new TargetCard(Zone.OUTSIDE, filter);
if (player.choose(Outcome.Benefit, filteredCards, target, game)) {
Card card = player.getSideboard().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/judgment/FlashOfInsight.java b/Mage.Sets/src/mage/sets/judgment/FlashOfInsight.java
index eda686cff99..e5d93bd9abc 100644
--- a/Mage.Sets/src/mage/sets/judgment/FlashOfInsight.java
+++ b/Mage.Sets/src/mage/sets/judgment/FlashOfInsight.java
@@ -118,12 +118,11 @@ class FlashOfInsightEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
player.lookAtCards(sourceObject.getName(), cards, game);
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put into your hand"));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into your hand"));
if (player.choose(Outcome.DrawCard, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
@@ -133,27 +132,7 @@ class FlashOfInsightEffect extends OneShotEffect {
}
}
- target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
- if (cards.size() > 0) {
- game.informPlayers(new StringBuilder(sourceObject.getName()).append(": ")
- .append(player.getLogName()).append(" puts ")
- .append(cards.size() == 1 ? "a":cards.size())
- .append(" card").append(cards.size() > 1 ? "s":"")
- .append(" on the bottom of his or her library").toString());
- }
- while (player.canRespond() && cards.size() > 1) {
- player.choose(Outcome.Neutral, cards, target, game);
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
- target.clearChosen();
- }
- if (cards.size() == 1) {
- Card card = cards.get(cards.iterator().next(), game);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
+ player.putCardsOnBottomOfLibrary(cards, game, source, true);
return true;
}
diff --git a/Mage.Sets/src/mage/sets/judgment/GoldenWish.java b/Mage.Sets/src/mage/sets/judgment/GoldenWish.java
index 2b76472ddf7..0ff30edc173 100644
--- a/Mage.Sets/src/mage/sets/judgment/GoldenWish.java
+++ b/Mage.Sets/src/mage/sets/judgment/GoldenWish.java
@@ -29,16 +29,15 @@ package mage.sets.judgment;
import java.util.Set;
import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
+import mage.constants.CardType;
import mage.constants.Outcome;
+import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
@@ -119,7 +118,7 @@ class GoldenWishEffect extends OneShotEffect {
filteredCards.add(card.getId());
}
- TargetCard target = new TargetCard(Zone.PICK, filter);
+ TargetCard target = new TargetCard(Zone.OUTSIDE, filter);
if (player.choose(Outcome.Benefit, filteredCards, target, game)) {
Card card = player.getSideboard().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/judgment/LivingWish.java b/Mage.Sets/src/mage/sets/judgment/LivingWish.java
index 907c97c9655..8db132bc324 100644
--- a/Mage.Sets/src/mage/sets/judgment/LivingWish.java
+++ b/Mage.Sets/src/mage/sets/judgment/LivingWish.java
@@ -29,16 +29,15 @@ package mage.sets.judgment;
import java.util.Set;
import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
+import mage.constants.CardType;
import mage.constants.Outcome;
+import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
@@ -119,7 +118,7 @@ class LivingWishEffect extends OneShotEffect {
filteredCards.add(card.getId());
}
- TargetCard target = new TargetCard(Zone.PICK, filter);
+ TargetCard target = new TargetCard(Zone.OUTSIDE, filter);
if (player.choose(Outcome.Benefit, filteredCards, target, game)) {
Card card = player.getSideboard().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/BitterRevelation.java b/Mage.Sets/src/mage/sets/khansoftarkir/BitterRevelation.java
index ee3fad23826..ac9dd2ce9e2 100644
--- a/Mage.Sets/src/mage/sets/khansoftarkir/BitterRevelation.java
+++ b/Mage.Sets/src/mage/sets/khansoftarkir/BitterRevelation.java
@@ -101,7 +101,7 @@ class BitterRevelationEffect extends OneShotEffect {
if (cards.size() > 0) {
Cards cardsToHand = new CardsImpl();
player.lookAtCards("Bitter Revelation", cards, game);
- TargetCard target = new TargetCard(Math.min(2, cards.size()), Zone.PICK, new FilterCard("two cards to put in your hand"));
+ TargetCard target = new TargetCard(Math.min(2, cards.size()), Zone.LIBRARY, new FilterCard("two cards to put in your hand"));
if (player.choose(Outcome.DrawCard, cards, target, game)) {
for (UUID targetId : target.getTargets()) {
Card card = cards.get(targetId, game);
diff --git a/Mage.Sets/src/mage/sets/limitedalpha/NaturalSelection.java b/Mage.Sets/src/mage/sets/limitedalpha/NaturalSelection.java
index 659fd8c3e48..160c4130168 100644
--- a/Mage.Sets/src/mage/sets/limitedalpha/NaturalSelection.java
+++ b/Mage.Sets/src/mage/sets/limitedalpha/NaturalSelection.java
@@ -100,13 +100,12 @@ class NaturalSelectionEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
you.lookAtCards("Natural Selection", cards, game);
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the top of target player's library"));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put on the top of target player's library"));
while (player.canRespond() && cards.size() > 1) {
you.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game);
diff --git a/Mage.Sets/src/mage/sets/lorwyn/AmoeboidChangeling.java b/Mage.Sets/src/mage/sets/lorwyn/AmoeboidChangeling.java
index 5141b2e47a0..6d29eed8e10 100644
--- a/Mage.Sets/src/mage/sets/lorwyn/AmoeboidChangeling.java
+++ b/Mage.Sets/src/mage/sets/lorwyn/AmoeboidChangeling.java
@@ -28,7 +28,6 @@
package mage.sets.lorwyn;
import java.util.UUID;
-
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@@ -39,7 +38,9 @@ import mage.abilities.keyword.ChangelingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
+import mage.constants.Layer;
import mage.constants.Rarity;
+import mage.constants.SubLayer;
import mage.constants.Zone;
import mage.target.common.TargetCreaturePermanent;
@@ -58,17 +59,18 @@ public class AmoeboidChangeling extends CardImpl {
// Changeling
this.addAbility(ChangelingAbility.getInstance());
-
+
// {tap}: Target creature gains all creature types until end of turn.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityTargetEffect(ChangelingAbility.getInstance(), Duration.EndOfTurn), new TapSourceCost());
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
+ new GainAbilityTargetEffect(ChangelingAbility.getInstance(), Duration.EndOfTurn, null, false, Layer.TypeChangingEffects_4, SubLayer.NA), new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
-
+
this.addAbility(ability);
-
+
// {tap}: Target creature loses all creature types until end of turn.
ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseAllCreatureTypesTargetEffect(Duration.EndOfTurn), new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
-
+
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/lorwyn/WingsOfVelisVel.java b/Mage.Sets/src/mage/sets/lorwyn/WingsOfVelisVel.java
index c6288c24a5d..ffe50cb4db3 100644
--- a/Mage.Sets/src/mage/sets/lorwyn/WingsOfVelisVel.java
+++ b/Mage.Sets/src/mage/sets/lorwyn/WingsOfVelisVel.java
@@ -36,7 +36,9 @@ import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
+import mage.constants.Layer;
import mage.constants.Rarity;
+import mage.constants.SubLayer;
import mage.target.common.TargetCreaturePermanent;
/**
@@ -52,20 +54,20 @@ public class WingsOfVelisVel extends CardImpl {
// Changeling
this.addAbility(ChangelingAbility.getInstance());
-
+
// Target creature becomes 4/4, gains all creature types, and gains flying until end of turn.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
Effect effect = new SetPowerToughnessTargetEffect(4, 4, Duration.EndOfTurn);
effect.setText("Target creature becomes 4/4");
- this.getSpellAbility().addEffect(effect);
-
- effect = new GainAbilityTargetEffect(ChangelingAbility.getInstance(), Duration.EndOfTurn);
+ this.getSpellAbility().addEffect(effect);
+
+ effect = new GainAbilityTargetEffect(ChangelingAbility.getInstance(), Duration.EndOfTurn, null, false, Layer.TypeChangingEffects_4, SubLayer.NA);
effect.setText(", gains all creature types");
- this.getSpellAbility().addEffect(effect);
+ this.getSpellAbility().addEffect(effect);
effect = new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn);
effect.setText(", and gains flying until end of turn");
- this.getSpellAbility().addEffect(effect);
+ this.getSpellAbility().addEffect(effect);
}
public WingsOfVelisVel(final WingsOfVelisVel card) {
diff --git a/Mage.Sets/src/mage/sets/magic2010/JackalFamiliar.java b/Mage.Sets/src/mage/sets/magic2010/JackalFamiliar.java
index 3b37baf1bd1..67059c5f0fa 100644
--- a/Mage.Sets/src/mage/sets/magic2010/JackalFamiliar.java
+++ b/Mage.Sets/src/mage/sets/magic2010/JackalFamiliar.java
@@ -27,14 +27,13 @@
*/
package mage.sets.magic2010;
-import mage.constants.CardType;
-import mage.constants.Rarity;
+import java.util.UUID;
import mage.MageInt;
import mage.abilities.keyword.CantAttackAloneAbility;
import mage.abilities.keyword.CantBlockAloneAbility;
import mage.cards.CardImpl;
-
-import java.util.UUID;
+import mage.constants.CardType;
+import mage.constants.Rarity;
/**
* @author magenoxx_at_gmail.com
@@ -50,7 +49,7 @@ public class JackalFamiliar extends CardImpl {
this.toughness = new MageInt(2);
// Jackal Familiar can't attack or block alone.
- this.addAbility(CantAttackAloneAbility.getInstance());
+ this.addAbility(new CantAttackAloneAbility());
this.addAbility(CantBlockAloneAbility.getInstance());
}
diff --git a/Mage.Sets/src/mage/sets/magic2010/MirrorOfFate.java b/Mage.Sets/src/mage/sets/magic2010/MirrorOfFate.java
index 2452f5850b2..66e1f8a8890 100644
--- a/Mage.Sets/src/mage/sets/magic2010/MirrorOfFate.java
+++ b/Mage.Sets/src/mage/sets/magic2010/MirrorOfFate.java
@@ -28,10 +28,6 @@
package mage.sets.magic2010;
import java.util.UUID;
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Rarity;
-import mage.constants.Zone;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
@@ -40,6 +36,10 @@ import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardsImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicate;
import mage.game.ExileZone;
@@ -113,7 +113,7 @@ class MirrorOfFateEffect extends OneShotEffect {
card.moveToExile(null, null, source.getSourceId(), game);
}
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on top of your library"));
+ TargetCard target = new TargetCard(Zone.EXILED, new FilterCard("card to put on top of your library"));
while (player.canRespond() && cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game);
diff --git a/Mage.Sets/src/mage/sets/magic2010/Polymorph.java b/Mage.Sets/src/mage/sets/magic2010/Polymorph.java
index 504714b1a9c..e3347137348 100644
--- a/Mage.Sets/src/mage/sets/magic2010/Polymorph.java
+++ b/Mage.Sets/src/mage/sets/magic2010/Polymorph.java
@@ -29,10 +29,6 @@ package mage.sets.magic2010;
import java.util.Set;
import java.util.UUID;
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Rarity;
-import mage.constants.Zone;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
@@ -40,6 +36,10 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Library;
@@ -112,7 +112,7 @@ class PolymorphEffect extends OneShotEffect {
}
if (card.getCardType().contains(CardType.CREATURE)) {
- card.putOntoBattlefield(game, Zone.PICK, source.getSourceId(), player.getId());
+ card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId());
}
if (cards.size() > 0) {
diff --git a/Mage.Sets/src/mage/sets/magic2012/Monomania.java b/Mage.Sets/src/mage/sets/magic2012/Monomania.java
index 3af809a1c33..b4f936b023b 100644
--- a/Mage.Sets/src/mage/sets/magic2012/Monomania.java
+++ b/Mage.Sets/src/mage/sets/magic2012/Monomania.java
@@ -27,13 +27,14 @@
*/
package mage.sets.magic2012;
-import mage.constants.CardType;
-import mage.constants.Rarity;
+import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
+import mage.constants.CardType;
import mage.constants.Outcome;
+import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
@@ -41,8 +42,6 @@ import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPlayer;
-import java.util.UUID;
-
/**
*
* @author nantuko
@@ -86,7 +85,7 @@ class MonomaniaEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getFirstTarget());
if (player != null) {
- TargetCard target = new TargetCard(Zone.PICK, filter);
+ TargetCard target = new TargetCard(Zone.HAND, filter);
if (player.choose(Outcome.Detriment, player.getHand(), target, game)) {
while (player.getHand().size() > 1) {
for (UUID uuid : player.getHand()) {
diff --git a/Mage.Sets/src/mage/sets/magic2012/SphinxOfUthuun.java b/Mage.Sets/src/mage/sets/magic2012/SphinxOfUthuun.java
index 6537fddc3b9..237af470bb3 100644
--- a/Mage.Sets/src/mage/sets/magic2012/SphinxOfUthuun.java
+++ b/Mage.Sets/src/mage/sets/magic2012/SphinxOfUthuun.java
@@ -108,7 +108,6 @@ class SphinxOfUthuunEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
player.revealCards(sourceObject.getName(), cards, game);
@@ -117,7 +116,7 @@ class SphinxOfUthuunEffect extends OneShotEffect {
if (!opponents.isEmpty()) {
Player opponent = game.getPlayer(opponents.iterator().next());
- TargetCard target = new TargetCard(0, cards.size(), Zone.PICK, new FilterCard("cards to put in the first pile"));
+ TargetCard target = new TargetCard(0, cards.size(), Zone.LIBRARY, new FilterCard("cards to put in the first pile"));
target.setRequired(false);
List pile1 = new ArrayList<>();
Cards pile1CardsIds = new CardsImpl();
diff --git a/Mage.Sets/src/mage/sets/magic2013/MoggFlunkies.java b/Mage.Sets/src/mage/sets/magic2013/MoggFlunkies.java
index 79bd8785521..8f101217fc4 100644
--- a/Mage.Sets/src/mage/sets/magic2013/MoggFlunkies.java
+++ b/Mage.Sets/src/mage/sets/magic2013/MoggFlunkies.java
@@ -27,14 +27,13 @@
*/
package mage.sets.magic2013;
-import mage.constants.CardType;
-import mage.constants.Rarity;
+import java.util.UUID;
import mage.MageInt;
import mage.abilities.keyword.CantAttackAloneAbility;
import mage.abilities.keyword.CantBlockAloneAbility;
import mage.cards.CardImpl;
-
-import java.util.UUID;
+import mage.constants.CardType;
+import mage.constants.Rarity;
/**
* @author magenoxx_at_gmail.com
@@ -50,7 +49,7 @@ public class MoggFlunkies extends CardImpl {
this.toughness = new MageInt(3);
// Mogg Flunkies can't attack or block alone.
- this.addAbility(CantAttackAloneAbility.getInstance());
+ this.addAbility(new CantAttackAloneAbility());
this.addAbility(CantBlockAloneAbility.getInstance());
}
diff --git a/Mage.Sets/src/mage/sets/magic2014/GlimpseTheFuture.java b/Mage.Sets/src/mage/sets/magic2014/GlimpseTheFuture.java
index a51c086bc3c..7148c510bf0 100644
--- a/Mage.Sets/src/mage/sets/magic2014/GlimpseTheFuture.java
+++ b/Mage.Sets/src/mage/sets/magic2014/GlimpseTheFuture.java
@@ -95,14 +95,13 @@ class GlimpseTheFutureEffect extends OneShotEffect {
Card card = controller.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
if (cards.size() > 0) {
controller.lookAtCards("Glimpse the Future", cards, game);
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put in your hand"));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put in your hand"));
if (controller.choose(Outcome.Benefit, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/magicorigins/BondedConstruct.java b/Mage.Sets/src/mage/sets/magicorigins/BondedConstruct.java
index 5f464c632ae..95f00778a4d 100644
--- a/Mage.Sets/src/mage/sets/magicorigins/BondedConstruct.java
+++ b/Mage.Sets/src/mage/sets/magicorigins/BondedConstruct.java
@@ -48,7 +48,7 @@ public class BondedConstruct extends CardImpl {
this.toughness = new MageInt(1);
// Bonded Construct can't attack alone.
- this.addAbility(CantAttackAloneAbility.getInstance());
+ this.addAbility(new CantAttackAloneAbility());
}
public BondedConstruct(final BondedConstruct card) {
diff --git a/Mage.Sets/src/mage/sets/masterseditionii/Errantry.java b/Mage.Sets/src/mage/sets/masterseditionii/Errantry.java
index b9214d5aa2a..2685f464a89 100644
--- a/Mage.Sets/src/mage/sets/masterseditionii/Errantry.java
+++ b/Mage.Sets/src/mage/sets/masterseditionii/Errantry.java
@@ -32,12 +32,10 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.combat.CanAttackOnlyAloneEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
-import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
-import mage.abilities.keyword.CanAttackOnlyAloneAbility;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
-import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
@@ -49,7 +47,7 @@ import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LoneFox
-
+ *
*/
public class Errantry extends CardImpl {
@@ -66,8 +64,8 @@ public class Errantry extends CardImpl {
this.addAbility(ability);
// Enchanted creature gets +3/+0 and can only attack alone.
ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 0, Duration.WhileOnBattlefield));
- Effect effect = new GainAbilityAttachedEffect(CanAttackOnlyAloneAbility.getInstance(), AttachmentType.AURA);
- effect.setText("and can only attack alone.");
+ Effect effect = new CanAttackOnlyAloneEffect();
+ effect.setText("and can only attack alone");
ability.addEffect(effect);
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/mirage/PainfulMemories.java b/Mage.Sets/src/mage/sets/mirage/PainfulMemories.java
index 590ff980988..2b4bc26a633 100644
--- a/Mage.Sets/src/mage/sets/mirage/PainfulMemories.java
+++ b/Mage.Sets/src/mage/sets/mirage/PainfulMemories.java
@@ -92,7 +92,7 @@ class PainfulMemoriesEffect extends OneShotEffect {
targetPlayer.revealCards("Painful Memories", targetPlayer.getHand(), game);
if (targetPlayer.getHand().size() > 0) {
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard());
+ TargetCard target = new TargetCard(Zone.HAND, new FilterCard());
if (you.choose(Outcome.Benefit, targetPlayer.getHand(), target, game)) {
Card card = targetPlayer.getHand().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/MitoticManipulation.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/MitoticManipulation.java
index 9c2a6e67099..b903d4199ae 100644
--- a/Mage.Sets/src/mage/sets/mirrodinbesieged/MitoticManipulation.java
+++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/MitoticManipulation.java
@@ -109,7 +109,6 @@ class MitoticManipulationEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
if (permanentNames.contains(card.getName())) {
cardsFound.add(card);
}
@@ -118,7 +117,7 @@ class MitoticManipulationEffect extends OneShotEffect {
player.lookAtCards("Mitotic Manipulation", cards, game);
if (!cardsFound.isEmpty() && player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put a card on the battlefield?", source, game)) {
- TargetCard target = new TargetCard(Zone.PICK, filter);
+ TargetCard target = new TargetCard(Zone.LIBRARY, filter);
if (player.choose(Outcome.PutCardInPlay, cardsFound, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
@@ -128,22 +127,7 @@ class MitoticManipulationEffect extends OneShotEffect {
}
}
}
-
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
- while (player.canRespond() && cards.size() > 1) {
- player.choose(Outcome.Neutral, cards, target, game);
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
- target.clearChosen();
- }
- if (cards.size() == 1) {
- Card card = cards.get(cards.iterator().next(), game);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
-
+ player.putCardsOnBottomOfLibrary(cards, game, source, true);
return true;
}
}
diff --git a/Mage.Sets/src/mage/sets/modernmasters/ThievingSprite.java b/Mage.Sets/src/mage/sets/modernmasters/ThievingSprite.java
index 1d6cdd19721..d67cc288672 100644
--- a/Mage.Sets/src/mage/sets/modernmasters/ThievingSprite.java
+++ b/Mage.Sets/src/mage/sets/modernmasters/ThievingSprite.java
@@ -118,7 +118,7 @@ class ThievingSpriteEffect extends OneShotEffect {
Cards cardsInHand = new CardsImpl();
cardsInHand.addAll(targetPlayer.getHand());
- TargetCard target = new TargetCard(numberOfFaeries, Zone.PICK, new FilterCard());
+ TargetCard target = new TargetCard(numberOfFaeries, Zone.HAND, new FilterCard());
if (targetPlayer.choose(Outcome.Discard, cardsInHand, target, game)) {
List targets = target.getTargets();
@@ -133,7 +133,7 @@ class ThievingSpriteEffect extends OneShotEffect {
revealedCards.addAll(targetPlayer.getHand());
}
- TargetCard targetInHand = new TargetCard(Zone.PICK, new FilterCard("card to discard"));
+ TargetCard targetInHand = new TargetCard(Zone.HAND, new FilterCard("card to discard"));
if (!revealedCards.isEmpty()) {
targetPlayer.revealCards("Thieving Sprite", revealedCards, game);
diff --git a/Mage.Sets/src/mage/sets/newphyrexia/EntomberExarch.java b/Mage.Sets/src/mage/sets/newphyrexia/EntomberExarch.java
index 147f62f486d..50bfaeca161 100644
--- a/Mage.Sets/src/mage/sets/newphyrexia/EntomberExarch.java
+++ b/Mage.Sets/src/mage/sets/newphyrexia/EntomberExarch.java
@@ -28,9 +28,6 @@
package mage.sets.newphyrexia;
import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
@@ -39,7 +36,9 @@ import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
+import mage.constants.CardType;
import mage.constants.Outcome;
+import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
@@ -108,7 +107,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.PICK, filter);
+ TargetCard target = new TargetCard(Zone.HAND, filter);
if (you.choose(Outcome.Benefit, player.getHand(), target, game)) {
Card card = player.getHand().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/newphyrexia/PsychicSurgery.java b/Mage.Sets/src/mage/sets/newphyrexia/PsychicSurgery.java
index 960184d8448..ba3ed78b01d 100644
--- a/Mage.Sets/src/mage/sets/newphyrexia/PsychicSurgery.java
+++ b/Mage.Sets/src/mage/sets/newphyrexia/PsychicSurgery.java
@@ -139,7 +139,7 @@ class PsychicSurgeryEffect extends OneShotEffect {
player.lookAtCards("Psychic Surgery", cards, game);
if (!cards.isEmpty() && player.chooseUse(Outcome.Exile, "Do you wish to exile a card?", source, game)) {
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to exile"));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to exile"));
if (player.choose(Outcome.Exile, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
@@ -148,22 +148,7 @@ class PsychicSurgeryEffect extends OneShotEffect {
}
}
}
-
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on top of his library"));
- while (player.canRespond() && cards.size() > 1) {
- player.choose(Outcome.Neutral, cards, target, game);
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
- }
- target.clearChosen();
- }
- if (cards.size() == 1) {
- Card card = cards.get(cards.iterator().next(), game);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
- }
-
+ player.putCardsOnBottomOfLibrary(cards, game, source, true);
return true;
}
return false;
diff --git a/Mage.Sets/src/mage/sets/newphyrexia/ShrineOfPiercingVision.java b/Mage.Sets/src/mage/sets/newphyrexia/ShrineOfPiercingVision.java
index 8086c1af2f3..830b69cb6e7 100644
--- a/Mage.Sets/src/mage/sets/newphyrexia/ShrineOfPiercingVision.java
+++ b/Mage.Sets/src/mage/sets/newphyrexia/ShrineOfPiercingVision.java
@@ -122,13 +122,12 @@ class ShrineOfPiercingVisionEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
player.lookAtCards("Shrine of Piercing Vision", cards, game);
if (!cards.isEmpty()) {
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put into your hand"));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into your hand"));
if (player.choose(Outcome.DrawCard, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
@@ -138,22 +137,7 @@ class ShrineOfPiercingVisionEffect extends OneShotEffect {
}
}
}
-
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
- while (player.canRespond() && cards.size() > 1) {
- player.choose(Outcome.Neutral, cards, target, game);
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
- target.clearChosen();
- }
- if (cards.size() == 1) {
- Card card = cards.get(cards.iterator().next(), game);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
-
+ player.putCardsOnBottomOfLibrary(cards, game, source, true);
return true;
}
}
diff --git a/Mage.Sets/src/mage/sets/odyssey/BalshanBeguiler.java b/Mage.Sets/src/mage/sets/odyssey/BalshanBeguiler.java
index 77c3aa7de3a..f1fa6de190e 100644
--- a/Mage.Sets/src/mage/sets/odyssey/BalshanBeguiler.java
+++ b/Mage.Sets/src/mage/sets/odyssey/BalshanBeguiler.java
@@ -97,7 +97,7 @@ class BalshanBeguilerEffect extends OneShotEffect {
cards.addAll(player.getLibrary().getTopCards(game, 2));
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard());
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard());
if (you.choose(Outcome.Benefit, cards, target, game)) {
Card card = player.getLibrary().getCard(target.getFirstTarget(), game);
card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, true);
diff --git a/Mage.Sets/src/mage/sets/planechase2012/SilentBladeOni.java b/Mage.Sets/src/mage/sets/planechase2012/SilentBladeOni.java
index 6295725eea2..7a91c35bc01 100644
--- a/Mage.Sets/src/mage/sets/planechase2012/SilentBladeOni.java
+++ b/Mage.Sets/src/mage/sets/planechase2012/SilentBladeOni.java
@@ -103,7 +103,7 @@ class SilentBladeOniEffect extends OneShotEffect {
Cards cardsInHand = new CardsImpl();
cardsInHand.addAll(opponent.getHand());
if (cardsInHand.size() > 0) {
- TargetCard target = new TargetCard(1, Zone.PICK, new FilterNonlandCard());
+ 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) {
diff --git a/Mage.Sets/src/mage/sets/ravnica/CongregationAtDawn.java b/Mage.Sets/src/mage/sets/ravnica/CongregationAtDawn.java
index 6ca8d911a6d..555db0e6051 100644
--- a/Mage.Sets/src/mage/sets/ravnica/CongregationAtDawn.java
+++ b/Mage.Sets/src/mage/sets/ravnica/CongregationAtDawn.java
@@ -105,7 +105,7 @@ class CongregationAtDawnEffect extends OneShotEffect {
controller.revealCards(sourceObject.getName(), revealed, game);
controller.shuffleLibrary(game);
- TargetCard targetToLib = new TargetCard(Zone.PICK, new FilterCard(textTop));
+ TargetCard targetToLib = new TargetCard(Zone.LIBRARY, new FilterCard(textTop));
while (revealed.size() > 1 && controller.canRespond()) {
controller.choose(Outcome.Neutral, revealed, targetToLib, game);
diff --git a/Mage.Sets/src/mage/sets/ravnica/MindleechMass.java b/Mage.Sets/src/mage/sets/ravnica/MindleechMass.java
index 81db0ad98dc..3d83c832caa 100644
--- a/Mage.Sets/src/mage/sets/ravnica/MindleechMass.java
+++ b/Mage.Sets/src/mage/sets/ravnica/MindleechMass.java
@@ -103,7 +103,7 @@ class MindleechMassEffect extends OneShotEffect {
opponent.revealCards("Opponents hand", cardsInHand, game);
if (cardsInHand.size() > 0
&& cardsInHand.getCards(new FilterNonlandCard(), game).size() > 0) {
- TargetCard target = new TargetCard(1, Zone.PICK, new FilterNonlandCard());
+ TargetCard target = new TargetCard(1, Zone.HAND, new FilterNonlandCard());
if (you.chooseTarget(Outcome.PlayForFree, cardsInHand, target, source, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/ravnica/Mindmoil.java b/Mage.Sets/src/mage/sets/ravnica/Mindmoil.java
index f0669f79591..60133863812 100644
--- a/Mage.Sets/src/mage/sets/ravnica/Mindmoil.java
+++ b/Mage.Sets/src/mage/sets/ravnica/Mindmoil.java
@@ -28,22 +28,15 @@
package mage.sets.ravnica;
import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
-import mage.cards.Card;
import mage.cards.CardImpl;
-import mage.cards.Cards;
-import mage.cards.CardsImpl;
+import mage.constants.CardType;
import mage.constants.Outcome;
-import mage.constants.Zone;
-import mage.filter.FilterCard;
+import mage.constants.Rarity;
import mage.game.Game;
import mage.players.Player;
-import mage.target.TargetCard;
/**
*
@@ -86,25 +79,7 @@ class MindmoilEffect extends OneShotEffect {
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
int count = you.getHand().size();
- Cards cards = new CardsImpl();
- for (Card card : you.getHand().getCards(game)) {
- cards.add(card.getId());
- }
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
- while (you.canRespond() && cards.size() > 1) {
- you.choose(Outcome.Neutral, cards, target, game);
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
- target.clearChosen();
- }
- if (cards.size() == 1) {
- Card card = cards.get(cards.iterator().next(), game);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
- you.getHand().clear();
+ you.putCardsOnBottomOfLibrary(you.getHand(), game, source, true);
you.drawCards(count, game);
}
return true;
diff --git a/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java b/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java
index 7d00e7d53ab..4d3c0b2fa75 100644
--- a/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java
+++ b/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java
@@ -199,7 +199,6 @@ class JaceArchitectOfThoughtEffect2 extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
player.revealCards("Jace, Architect of Thought", cards, game);
@@ -217,7 +216,7 @@ class JaceArchitectOfThoughtEffect2 extends OneShotEffect {
opponent = game.getPlayer(opponents.iterator().next());
}
- TargetCard target = new TargetCard(0, cards.size(), Zone.PICK, new FilterCard("cards to put in the first pile"));
+ TargetCard target = new TargetCard(0, cards.size(), Zone.LIBRARY, new FilterCard("cards to put in the first pile"));
target.setRequired(false);
Cards pile1 = new CardsImpl();
if (opponent.choose(Outcome.Neutral, cards, target, game)) {
@@ -260,20 +259,7 @@ class JaceArchitectOfThoughtEffect2 extends OneShotEffect {
}
}
- TargetCard targetCard = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
- while (player.canRespond() && cardsToLibrary.size() > 1) {
- player.choose(Outcome.Neutral, cardsToLibrary, targetCard, game);
- Card card = cardsToLibrary.get(targetCard.getFirstTarget(), game);
- if (card != null) {
- cardsToLibrary.remove(card);
- player.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, false, false);
- }
- target.clearChosen();
- }
- if (cardsToLibrary.size() == 1) {
- Card card = cardsToLibrary.get(cardsToLibrary.iterator().next(), game);
- player.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, false, false);
- }
+ player.putCardsOnBottomOfLibrary(cardsToLibrary, game, source, true);
return true;
}
return false;
diff --git a/Mage.Sets/src/mage/sets/returntoravnica/JaradsOrders.java b/Mage.Sets/src/mage/sets/returntoravnica/JaradsOrders.java
index adc5aa137cd..89e8c945006 100644
--- a/Mage.Sets/src/mage/sets/returntoravnica/JaradsOrders.java
+++ b/Mage.Sets/src/mage/sets/returntoravnica/JaradsOrders.java
@@ -29,16 +29,15 @@ package mage.sets.returntoravnica;
import java.util.List;
import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
+import mage.constants.CardType;
import mage.constants.Outcome;
+import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
@@ -102,7 +101,7 @@ class JaradsOrdersEffect extends OneShotEffect {
}
controller.revealCards("Jarad's Orders", revealed, game);
if (target.getTargets().size() == 2) {
- TargetCard target2 = new TargetCard(Zone.PICK, filter);
+ TargetCard target2 = new TargetCard(Zone.LIBRARY, filter);
controller.choose(Outcome.Benefit, revealed, target2, game);
Card card = revealed.get(target2.getFirstTarget(), game);
controller.moveCards(card, Zone.LIBRARY, Zone.HAND, source, game);
diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/PerishTheThought.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/PerishTheThought.java
index 90f0368c91a..998441b36f9 100644
--- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/PerishTheThought.java
+++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/PerishTheThought.java
@@ -28,14 +28,13 @@
package mage.sets.riseoftheeldrazi;
import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
+import mage.constants.CardType;
import mage.constants.Outcome;
+import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
@@ -95,7 +94,7 @@ class PerishTheThoughtEffect extends OneShotEffect {
targetOpponent.revealCards("Perish the Thought", targetOpponent.getHand(), game);
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
- TargetCard target = new TargetCard(Zone.PICK, filter);
+ TargetCard target = new TargetCard(Zone.HAND, filter);
target.setNotTarget(true);
if (you.choose(Outcome.Neutral, targetOpponent.getHand(), target, game)) {
Card chosenCard = targetOpponent.getHand().get(target.getFirstTarget(), game);
diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/AshesOfTheFallen.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/AshesOfTheFallen.java
new file mode 100644
index 00000000000..682765f4a5f
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/AshesOfTheFallen.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.sets.saviorsofkamigawa;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.common.AsEntersBattlefieldAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ContinuousEffectImpl;
+import mage.abilities.effects.common.ChooseCreatureTypeEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Layer;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.SubLayer;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+/**
+ *
+ * @author emerald000
+ */
+public class AshesOfTheFallen extends CardImpl {
+
+ public AshesOfTheFallen(UUID ownerId) {
+ super(ownerId, 152, "Ashes of the Fallen", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{2}");
+ this.expansionSetCode = "SOK";
+
+ // As Ashes of the Fallen enters the battlefield, choose a creature type.
+ this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.Benefit)));
+
+ // Each creature card in your graveyard has the chosen creature type in addition to its other types.
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AshesOfTheFallenEffect()));
+ }
+
+ public AshesOfTheFallen(final AshesOfTheFallen card) {
+ super(card);
+ }
+
+ @Override
+ public AshesOfTheFallen copy() {
+ return new AshesOfTheFallen(this);
+ }
+}
+
+class AshesOfTheFallenEffect extends ContinuousEffectImpl {
+
+ AshesOfTheFallenEffect() {
+ super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
+ staticText = "Each creature card in your graveyard has the chosen creature type in addition to its other types";
+ }
+
+ AshesOfTheFallenEffect(final AshesOfTheFallenEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Permanent permanent = game.getPermanent(source.getSourceId());
+ if (controller != null && permanent != null) {
+ String subtype = (String) game.getState().getValue(permanent.getId() + "_type");
+ for (UUID cardId : controller.getGraveyard()) {
+ Card card = game.getCard(cardId);
+ if (card != null && card.getCardType().contains(CardType.CREATURE) && !card.getSubtype().contains(subtype)) {
+ card.getSubtype().add(subtype);
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public AshesOfTheFallenEffect copy() {
+ return new AshesOfTheFallenEffect(this);
+ }
+}
+
diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/CloneShell.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/CloneShell.java
index 6fb58914f1b..84665e99f4b 100644
--- a/Mage.Sets/src/mage/sets/scarsofmirrodin/CloneShell.java
+++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/CloneShell.java
@@ -100,14 +100,13 @@ class CloneShellEffect extends OneShotEffect {
for (int i = 0; i < count; i++) {
Card card = player.getLibrary().removeFromTop(game);
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
if (cards.size() == 0) {
return false;
}
- TargetCard target1 = new TargetCard(Zone.PICK, filter1);
+ TargetCard target1 = new TargetCard(Zone.LIBRARY, filter1);
if (player.choose(Outcome.Detriment, cards, target1, game)) {
Card card = cards.get(target1.getFirstTarget(), game);
if (card != null) {
@@ -123,7 +122,7 @@ class CloneShellEffect extends OneShotEffect {
}
if (cards.size() > 0) {
- TargetCard target2 = new TargetCard(Zone.PICK, filter2);
+ TargetCard target2 = new TargetCard(Zone.LIBRARY, filter2);
while (player.canRespond() && cards.size() > 1) {
player.choose(Outcome.Benefit, cards, target2, game);
Card card = cards.get(target2.getFirstTarget(), game);
diff --git a/Mage.Sets/src/mage/sets/seventhedition/AgonizingMemories.java b/Mage.Sets/src/mage/sets/seventhedition/AgonizingMemories.java
index b41be8998c3..aacf0ef4c18 100644
--- a/Mage.Sets/src/mage/sets/seventhedition/AgonizingMemories.java
+++ b/Mage.Sets/src/mage/sets/seventhedition/AgonizingMemories.java
@@ -28,7 +28,6 @@
package mage.sets.seventhedition;
import java.util.UUID;
-import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
@@ -99,7 +98,7 @@ class AgonizingMemoriesEffect extends OneShotEffect {
private void chooseCardInHandAndPutOnTopOfLibrary(Game game, Ability source, Player you, Player targetPlayer) {
if (targetPlayer.getHand().size() > 0) {
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the top of library (last chosen will be on top)"));
+ TargetCard target = new TargetCard(Zone.HAND, new FilterCard("card to put on the top of library (last chosen will be on top)"));
if (you.choose(Outcome.Benefit, targetPlayer.getHand(), target, game)) {
Card card = targetPlayer.getHand().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/seventhedition/AncestralMemories.java b/Mage.Sets/src/mage/sets/seventhedition/AncestralMemories.java
index 96263a28f54..32b515cc39f 100644
--- a/Mage.Sets/src/mage/sets/seventhedition/AncestralMemories.java
+++ b/Mage.Sets/src/mage/sets/seventhedition/AncestralMemories.java
@@ -96,14 +96,13 @@ class AncestralMemoriesEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
if (cards.size() > 0) {
player.lookAtCards("Ancestral Memories", cards, game);
- TargetCard target = new TargetCard(Math.min(2, cards.size()), Zone.PICK, new FilterCard("two cards to put in your hand"));
+ TargetCard target = new TargetCard(Math.min(2, cards.size()), Zone.LIBRARY, new FilterCard("two cards to put in your hand"));
if (player.choose(Outcome.Benefit, cards, target, game)) {
for (UUID targetId : (List)target.getTargets()) {
Card card = cards.get(targetId, game);
diff --git a/Mage.Sets/src/mage/sets/shadowmoor/RiversGrasp.java b/Mage.Sets/src/mage/sets/shadowmoor/RiversGrasp.java
index 5d6cc24269c..d266a182b81 100644
--- a/Mage.Sets/src/mage/sets/shadowmoor/RiversGrasp.java
+++ b/Mage.Sets/src/mage/sets/shadowmoor/RiversGrasp.java
@@ -118,7 +118,7 @@ class RiversGraspEffect extends OneShotEffect {
player.revealCards("River's Grasp", player.getHand(), game);
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- TargetCard target = new TargetCard(Zone.PICK, filter);
+ TargetCard target = new TargetCard(Zone.HAND, filter);
if (controller.choose(Outcome.Benefit, player.getHand(), target, game)) {
Card card = player.getHand().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/shadowmoor/SplittingHeadache.java b/Mage.Sets/src/mage/sets/shadowmoor/SplittingHeadache.java
index 6aaa0734757..313afbd80da 100644
--- a/Mage.Sets/src/mage/sets/shadowmoor/SplittingHeadache.java
+++ b/Mage.Sets/src/mage/sets/shadowmoor/SplittingHeadache.java
@@ -98,7 +98,7 @@ class SplittingHeadacheEffect extends OneShotEffect {
player.revealCards("Splitting Headache", player.getHand(), game);
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard());
+ TargetCard target = new TargetCard(Zone.HAND, new FilterCard());
if (you.choose(Outcome.Benefit, player.getHand(), target, game)) {
Card card = player.getHand().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/shardsofalara/GiftOfTheGargantuan.java b/Mage.Sets/src/mage/sets/shardsofalara/GiftOfTheGargantuan.java
index 6eb8c586f8f..d3c0799f02f 100644
--- a/Mage.Sets/src/mage/sets/shardsofalara/GiftOfTheGargantuan.java
+++ b/Mage.Sets/src/mage/sets/shardsofalara/GiftOfTheGargantuan.java
@@ -38,7 +38,6 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
-import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
import mage.filter.common.FilterLandCard;
import mage.game.Game;
@@ -101,7 +100,6 @@ class GiftOfTheGargantuanEffect extends OneShotEffect {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
if (card.getCardType().contains(CardType.CREATURE)) {
creatureCardFound = true;
}
@@ -115,7 +113,7 @@ class GiftOfTheGargantuanEffect extends OneShotEffect {
if ((creatureCardFound || landCardFound) && player.chooseUse(Outcome.DrawCard, "Do you wish to reveal a creature card and/or a land card and put them into your hand?", source, game)) {
Cards revealedCards = new CardsImpl();
- TargetCard target = new TargetCard(Zone.PICK, new FilterCreatureCard("creature card to reveal and put into your hand"));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCreatureCard("creature card to reveal and put into your hand"));
if (creatureCardFound && player.choose(Outcome.DrawCard, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
@@ -125,7 +123,7 @@ class GiftOfTheGargantuanEffect extends OneShotEffect {
}
}
- target = new TargetCard(Zone.PICK, new FilterLandCard("land card to reveal and put into your hand"));
+ target = new TargetCard(Zone.LIBRARY, new FilterLandCard("land card to reveal and put into your hand"));
if (landCardFound && player.choose(Outcome.DrawCard, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
@@ -139,22 +137,7 @@ class GiftOfTheGargantuanEffect extends OneShotEffect {
player.revealCards("Gift of the Gargantuan", revealedCards, game);
}
}
-
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
- while (player.canRespond() && cards.size() > 1) {
- player.choose(Outcome.Neutral, cards, target, game);
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
- target.clearChosen();
- }
- if (cards.size() == 1) {
- Card card = cards.get(cards.iterator().next(), game);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
-
+ player.putCardsOnBottomOfLibrary(cards, game, source, true);
return true;
}
}
diff --git a/Mage.Sets/src/mage/sets/stronghold/HibernationSliver.java b/Mage.Sets/src/mage/sets/stronghold/HibernationSliver.java
index 9421f6bcb79..11faedca0d4 100644
--- a/Mage.Sets/src/mage/sets/stronghold/HibernationSliver.java
+++ b/Mage.Sets/src/mage/sets/stronghold/HibernationSliver.java
@@ -61,7 +61,9 @@ public class HibernationSliver extends CardImpl {
Effect effect = new ReturnToHandSourceEffect(true);
effect.setText("Return this permanent to its owner's hand");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new PayLifeCost(2));
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(ability, Duration.WhileOnBattlefield, new FilterPermanent("Sliver", "All Slivers"), "All Slivers have \"Pay 2 life: Return this permanent to its owner's hand")));
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
+ new GainAbilityAllEffect(ability, Duration.WhileOnBattlefield,
+ new FilterPermanent("Sliver", "All Slivers"), "All Slivers have \"Pay 2 life: Return this permanent to its owner's hand")));
}
public HibernationSliver(final HibernationSliver card) {
diff --git a/Mage.Sets/src/mage/sets/tempest/Intuition.java b/Mage.Sets/src/mage/sets/tempest/Intuition.java
index b53b71eddcb..37c24daa36a 100644
--- a/Mage.Sets/src/mage/sets/tempest/Intuition.java
+++ b/Mage.Sets/src/mage/sets/tempest/Intuition.java
@@ -29,16 +29,15 @@ package mage.sets.tempest;
import java.util.List;
import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.effects.SearchEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
@@ -111,7 +110,7 @@ class IntuitionEffect extends SearchEffect {
}
controller.revealCards("Reveal", cards, game);
- TargetCard targetCard = new TargetCard(Zone.PICK, new FilterCard());
+ TargetCard targetCard = new TargetCard(Zone.LIBRARY, new FilterCard());
while(!opponent.choose(Outcome.Neutral, cards, targetCard, game)) {
if (!opponent.canRespond()) {
diff --git a/Mage.Sets/src/mage/sets/tenthedition/TellingTime.java b/Mage.Sets/src/mage/sets/tenthedition/TellingTime.java
index 7b143838c03..74923b800d5 100644
--- a/Mage.Sets/src/mage/sets/tenthedition/TellingTime.java
+++ b/Mage.Sets/src/mage/sets/tenthedition/TellingTime.java
@@ -28,17 +28,16 @@
package mage.sets.tenthedition;
import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Rarity;
-import mage.constants.Zone;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Library;
@@ -130,7 +129,7 @@ class TellingTimeEffect extends OneShotEffect {
return cards.getRandom(null);
}
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard(message));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard(message));
if (player.choose(Outcome.Benefit, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage.Sets/src/mage/sets/tenthedition/ThrullSurgeon.java b/Mage.Sets/src/mage/sets/tenthedition/ThrullSurgeon.java
index 0b1707279eb..5c789be767c 100644
--- a/Mage.Sets/src/mage/sets/tenthedition/ThrullSurgeon.java
+++ b/Mage.Sets/src/mage/sets/tenthedition/ThrullSurgeon.java
@@ -28,9 +28,6 @@
package mage.sets.tenthedition;
import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
@@ -39,7 +36,9 @@ import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
+import mage.constants.CardType;
import mage.constants.Outcome;
+import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
@@ -96,7 +95,7 @@ class ThrullSurgeonEffect extends OneShotEffect {
Player you = game.getPlayer(source.getControllerId());
if (targetPlayer != null && you != null) {
you.lookAtCards("Discard", targetPlayer.getHand(), game);
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard());
+ TargetCard target = new TargetCard(Zone.HAND, new FilterCard());
target.setNotTarget(true);
if (you.choose(Outcome.Benefit, targetPlayer.getHand(), target, game)) {
Card card = targetPlayer.getHand().get(target.getFirstTarget(), game);
diff --git a/Mage.Sets/src/mage/sets/theros/DiscipleOfPhenax.java b/Mage.Sets/src/mage/sets/theros/DiscipleOfPhenax.java
index a3d7b7a62ac..d7bac0bba90 100644
--- a/Mage.Sets/src/mage/sets/theros/DiscipleOfPhenax.java
+++ b/Mage.Sets/src/mage/sets/theros/DiscipleOfPhenax.java
@@ -128,7 +128,7 @@ class DiscipleOfPhenaxEffect extends OneShotEffect {
targetPlayer.revealCards("Disciple of Phenax", revealedCards, game);
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
- TargetCard yourChoice = new TargetCard(Zone.PICK, new FilterCard());
+ 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);
diff --git a/Mage.Sets/src/mage/sets/theros/SteamAugury.java b/Mage.Sets/src/mage/sets/theros/SteamAugury.java
index f73f15876f0..6e3cf2f9958 100644
--- a/Mage.Sets/src/mage/sets/theros/SteamAugury.java
+++ b/Mage.Sets/src/mage/sets/theros/SteamAugury.java
@@ -115,7 +115,7 @@ class SteamAuguryEffect extends OneShotEffect {
}
if (opponent != null) {
- TargetCard target = new TargetCard(0, cards.size(), Zone.PICK, new FilterCard("cards to put in the first pile"));
+ TargetCard target = new TargetCard(0, cards.size(), Zone.LIBRARY, new FilterCard("cards to put in the first pile"));
List pile1 = new ArrayList<>();
Cards pile1CardsIds = new CardsImpl();
target.setRequired(false);
diff --git a/Mage.Sets/src/mage/sets/urzaslegacy/HarmonicConvergence.java b/Mage.Sets/src/mage/sets/urzaslegacy/HarmonicConvergence.java
index fde1f0a2527..a5c5225868a 100644
--- a/Mage.Sets/src/mage/sets/urzaslegacy/HarmonicConvergence.java
+++ b/Mage.Sets/src/mage/sets/urzaslegacy/HarmonicConvergence.java
@@ -104,7 +104,7 @@ class HarmonicConvergenceEffect extends OneShotEffect {
list.add(permanent);
}
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on top of your library"));
+ TargetCard target = new TargetCard(Zone.BATTLEFIELD, new FilterCard("card to put on top of your library"));
for (UUID playerId : moveList.keySet()) {
Player player = game.getPlayer(playerId);
List list = moveList.get(playerId);
diff --git a/Mage.Sets/src/mage/sets/urzaslegacy/RavenFamiliar.java b/Mage.Sets/src/mage/sets/urzaslegacy/RavenFamiliar.java
index 881a72a1225..ef0d1e56950 100644
--- a/Mage.Sets/src/mage/sets/urzaslegacy/RavenFamiliar.java
+++ b/Mage.Sets/src/mage/sets/urzaslegacy/RavenFamiliar.java
@@ -108,12 +108,11 @@ public class RavenFamiliar extends CardImpl {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
player.lookAtCards("Raven Familiar", cards, game);
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put into your hand"));
+ TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into your hand"));
if (player.choose(Outcome.DrawCard, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
@@ -121,22 +120,7 @@ public class RavenFamiliar extends CardImpl {
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
}
}
-
- target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
- while (player.canRespond() && cards.size() > 1) {
- player.choose(Outcome.Neutral, cards, target, game);
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
- target.clearChosen();
- }
- if (cards.size() == 1) {
- Card card = cards.get(cards.iterator().next(), game);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
-
+ player.putCardsOnBottomOfLibrary(cards, game, source, true);
return true;
}
}
diff --git a/Mage.Sets/src/mage/sets/vintagemasters/KrovikanSorcerer.java b/Mage.Sets/src/mage/sets/vintagemasters/KrovikanSorcerer.java
index 6d966566194..d7f14c367b1 100644
--- a/Mage.Sets/src/mage/sets/vintagemasters/KrovikanSorcerer.java
+++ b/Mage.Sets/src/mage/sets/vintagemasters/KrovikanSorcerer.java
@@ -123,7 +123,7 @@ class KrovikanSorcererEffect extends OneShotEffect {
}
}
if (drawnCards.size() > 0) {
- TargetCard cardToDiscard = new TargetCard(Zone.PICK, new FilterCard("card to discard"));
+ TargetCard cardToDiscard = new TargetCard(Zone.HAND, new FilterCard("card to discard"));
cardToDiscard.setNotTarget(true);
if (player.choose(Outcome.Discard, drawnCards, cardToDiscard, game)) {
Card card = player.getHand().get(cardToDiscard.getFirstTarget(), game);
diff --git a/Mage.Sets/src/mage/sets/weatherlight/Doomsday.java b/Mage.Sets/src/mage/sets/weatherlight/Doomsday.java
index a48fff82ecd..f8fa1c6e467 100644
--- a/Mage.Sets/src/mage/sets/weatherlight/Doomsday.java
+++ b/Mage.Sets/src/mage/sets/weatherlight/Doomsday.java
@@ -96,7 +96,7 @@ class DoomsdayEffect extends OneShotEffect {
allCards.addAll(player.getLibrary().getCardList());
allCards.addAll(player.getGraveyard());
int number = Math.min(5, allCards.size());
- TargetCard target = new TargetCard(number, number, Zone.PICK, new FilterCard());
+ TargetCard target = new TargetCard(number, number, Zone.ALL, new FilterCard());
if (player.choose(Outcome.Benefit, allCards, target, game)){
// exile the rest
@@ -113,7 +113,7 @@ class DoomsdayEffect extends OneShotEffect {
}
//Put the chosen cards on top of your library in any order
- target = new TargetCard(Zone.PICK, new FilterCard("Card to put on top"));
+ target = new TargetCard(Zone.ALL, new FilterCard("Card to put on top"));
while (cards.size() > 1 && player.canRespond()) {
player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game);
diff --git a/Mage.Sets/src/mage/sets/zendikar/BalaGedThief.java b/Mage.Sets/src/mage/sets/zendikar/BalaGedThief.java
index c66289a522e..48274dfa013 100644
--- a/Mage.Sets/src/mage/sets/zendikar/BalaGedThief.java
+++ b/Mage.Sets/src/mage/sets/zendikar/BalaGedThief.java
@@ -117,7 +117,7 @@ class BalaGedThiefEffect extends OneShotEffect {
int count = Math.min(cardsInHand.size(), numberOfAllies);
- TargetCard target = new TargetCard(count, Zone.PICK, new FilterCard());
+ TargetCard target = new TargetCard(count, Zone.HAND, new FilterCard());
Cards revealedCards = new CardsImpl();
if (targetPlayer.choose(Outcome.DrawCard, cardsInHand, target, game)) {
@@ -130,7 +130,7 @@ class BalaGedThiefEffect extends OneShotEffect {
}
}
- TargetCard targetInHand = new TargetCard(Zone.PICK, new FilterCard("card to discard"));
+ TargetCard targetInHand = new TargetCard(Zone.HAND, new FilterCard("card to discard"));
if (!revealedCards.isEmpty()) {
targetPlayer.revealCards("Bala Ged Thief", revealedCards, game);
diff --git a/Mage.Sets/src/mage/sets/zendikar/MerfolkWayfinder.java b/Mage.Sets/src/mage/sets/zendikar/MerfolkWayfinder.java
index 04461008f7e..f87bd296ac1 100644
--- a/Mage.Sets/src/mage/sets/zendikar/MerfolkWayfinder.java
+++ b/Mage.Sets/src/mage/sets/zendikar/MerfolkWayfinder.java
@@ -41,10 +41,8 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
-import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
-import mage.target.TargetCard;
/**
*
@@ -109,27 +107,11 @@ class MerfolkWayfinderEffect extends OneShotEffect {
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
} else {
cards.add(card);
- game.setZone(card.getId(), Zone.PICK);
}
}
}
player.revealCards("Merfolk Wayfinder", cardsToReveal, game);
-
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
- while (player.canRespond() && cards.size() > 1) {
- player.choose(Outcome.Neutral, cards, target, game);
- Card card = cards.get(target.getFirstTarget(), game);
- if (card != null) {
- cards.remove(card);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
- target.clearChosen();
- }
- if (cards.size() == 1) {
- Card card = cards.get(cards.iterator().next(), game);
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
- }
-
+ player.putCardsOnBottomOfLibrary(cards, game, source, true);
return true;
}
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ChangelingTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ChangelingTest.java
index c2010548151..80ce765fa67 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ChangelingTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ChangelingTest.java
@@ -27,8 +27,11 @@
*/
package org.mage.test.cards.abilities.keywords;
+import mage.abilities.Ability;
import mage.constants.PhaseStep;
import mage.constants.Zone;
+import mage.game.permanent.Permanent;
+import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@@ -36,18 +39,17 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
*
* @author LevelX2
*/
-
public class ChangelingTest extends CardTestPlayerBase {
/**
- * Casting changelings with a Long-Forgotten Gohei in play reduces its casting cost by {1}.
+ * Casting changelings with a Long-Forgotten Gohei in play reduces its
+ * casting cost by {1}.
*/
-
@Test
public void testLongForgottenGohei() {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
addCard(Zone.HAND, playerA, "Woodland Changeling");
-
+
addCard(Zone.BATTLEFIELD, playerA, "Long-Forgotten Gohei");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Woodland Changeling");
@@ -58,6 +60,46 @@ public class ChangelingTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Woodland Changeling", 0); // Casting cost of spell is not reduced so not on the battlefield
assertHandCount(playerA, "Woodland Changeling", 1);
- }
+ }
-}
\ No newline at end of file
+ /**
+ * Another bug, was playing Slivers again. I had a Amoeboid Changeling, a
+ * Hibernation Sliver and a Prophet of Kruphix. In response to a boardwipe,
+ * I tapped my Changeling, giving my Prophet Changeling. However, it didn't
+ * gain any Sliver abilities despite having all creature types, including
+ * Sliver, so I couldn't save it with my Hibernation Sliver. I clicked the
+ * Prophet and nothing happened at all.
+ */
+ @Test
+ public void testGainingChangeling() {
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
+ // Untap all creatures and lands you control during each other player's untap step.
+ // You may cast creature cards as though they had flash.
+ addCard(Zone.HAND, playerA, "Prophet of Kruphix");// {3}{G}{U}
+ // Changeling
+ // {T}: Target creature gains all creature types until end of turn.
+ // {T}: Target creature loses all creature types until end of turn.
+ addCard(Zone.BATTLEFIELD, playerA, "Amoeboid Changeling");
+ // All Slivers have "Pay 2 life: Return this permanent to its owner's hand."
+ addCard(Zone.BATTLEFIELD, playerA, "Hibernation Sliver");
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Prophet of Kruphix");
+ activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Target creature gains", "Prophet of Kruphix");
+
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertTapped("Amoeboid Changeling", true);
+
+ Permanent prophet = getPermanent("Prophet of Kruphix", playerA);
+ boolean abilityFound = false;
+ for (Ability ability : prophet.getAbilities()) {
+ if (ability.getRule().startsWith("Pay 2 life")) {
+ abilityFound = true;
+ }
+ }
+ Assert.assertTrue("Prophet of Kruphix has to have the 'Pay 2 life: Return this permanent to its owner's hand.' ability, but has not.", abilityFound);
+
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/combat/CantAttackOrBlockAloneTest.java b/Mage.Tests/src/test/java/org/mage/test/combat/CantAttackOrBlockAloneTest.java
index a668c46beba..0a24dab7a21 100644
--- a/Mage.Tests/src/test/java/org/mage/test/combat/CantAttackOrBlockAloneTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/combat/CantAttackOrBlockAloneTest.java
@@ -48,6 +48,23 @@ public class CantAttackOrBlockAloneTest extends CardTestPlayerBase {
assertLife(playerA, 15);
}
+ /**
+ * Try to attack with two Flunkies
+ */
+ @Test
+ public void testCanAttackWithTwo() {
+ addCard(Zone.BATTLEFIELD, playerB, "Mogg Flunkies", 2); // 3/3
+
+ attack(2, playerB, "Mogg Flunkies");
+ attack(2, playerB, "Mogg Flunkies");
+
+ setStopAt(2, PhaseStep.END_TURN);
+ execute();
+
+ assertLife(playerA, 14);
+
+ }
+
/**
* Try to block alone
*/
diff --git a/Mage/src/main/java/mage/abilities/effects/RestrictionEffect.java b/Mage/src/main/java/mage/abilities/effects/RestrictionEffect.java
index 47f89ec6021..12bf04ef220 100644
--- a/Mage/src/main/java/mage/abilities/effects/RestrictionEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/RestrictionEffect.java
@@ -69,6 +69,10 @@ public abstract class RestrictionEffect extends ContinuousEffectImpl {
return true;
}
+ public boolean canAttackCheckAfter(int numberOfAttackers, Ability source, Game game) {
+ return true;
+ }
+
public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) {
return true;
}
diff --git a/Mage/src/main/java/mage/abilities/effects/common/CastCardFromOutsideTheGameEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CastCardFromOutsideTheGameEffect.java
index 5dbef2a742b..c8e1052d3a5 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/CastCardFromOutsideTheGameEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/CastCardFromOutsideTheGameEffect.java
@@ -27,6 +27,7 @@
*/
package mage.abilities.effects.common;
+import java.util.Set;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
@@ -39,8 +40,6 @@ import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
-import java.util.Set;
-
/**
* @author magenoxx_at_gmail.com
*/
@@ -48,7 +47,7 @@ public class CastCardFromOutsideTheGameEffect extends OneShotEffect {
private static final String choiceText = "Cast a card from outside the game?";
- private FilterCard filterCard;
+ private final FilterCard filterCard;
public CastCardFromOutsideTheGameEffect(FilterCard filter, String ruleText) {
super(Outcome.Benefit);
@@ -76,15 +75,17 @@ public class CastCardFromOutsideTheGameEffect extends OneShotEffect {
while (player.chooseUse(Outcome.Benefit, choiceText, source, game)) {
Cards cards = player.getSideboard();
if (cards.isEmpty()) {
- if (!game.isSimulation())
+ if (!game.isSimulation()) {
game.informPlayer(player, "You have no cards outside the game.");
+ }
return false;
}
Set filtered = cards.getCards(filterCard, source.getSourceId(), source.getControllerId(), game);
if (filtered.isEmpty()) {
- if (!game.isSimulation())
+ if (!game.isSimulation()) {
game.informPlayer(player, "You have no " + filterCard.getMessage() + " outside the game.");
+ }
return false;
}
@@ -93,7 +94,7 @@ public class CastCardFromOutsideTheGameEffect extends OneShotEffect {
filteredCards.add(card.getId());
}
- TargetCard target = new TargetCard(Zone.PICK, filterCard);
+ TargetCard target = new TargetCard(Zone.OUTSIDE, filterCard);
if (player.choose(Outcome.Benefit, filteredCards, target, game)) {
Card card = player.getSideboard().get(target.getFirstTarget(), game);
if (card != null) {
diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CanAttackOnlyAloneEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CanAttackOnlyAloneEffect.java
new file mode 100644
index 00000000000..2df2b790ad6
--- /dev/null
+++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CanAttackOnlyAloneEffect.java
@@ -0,0 +1,43 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package mage.abilities.effects.common.combat;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.RestrictionEffect;
+import mage.constants.Duration;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class CanAttackOnlyAloneEffect extends RestrictionEffect {
+
+ public CanAttackOnlyAloneEffect() {
+ super(Duration.WhileOnBattlefield);
+ staticText = "{this} can only attack alone";
+ }
+
+ public CanAttackOnlyAloneEffect(final CanAttackOnlyAloneEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CanAttackOnlyAloneEffect copy() {
+ return new CanAttackOnlyAloneEffect(this);
+ }
+
+ @Override
+ public boolean canAttackCheckAfter(int numberOfAttackers, Ability source, Game game) {
+ return numberOfAttackers == 1;
+ }
+
+ @Override
+ public boolean applies(Permanent permanent, Ability source, Game game) {
+ return source.getSourceId().equals(permanent.getId());
+ }
+}
diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackAloneEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackAloneEffect.java
new file mode 100644
index 00000000000..6d8cd6d610b
--- /dev/null
+++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackAloneEffect.java
@@ -0,0 +1,43 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package mage.abilities.effects.common.combat;
+
+import mage.abilities.Ability;
+import mage.abilities.effects.RestrictionEffect;
+import mage.constants.Duration;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class CantAttackAloneEffect extends RestrictionEffect {
+
+ public CantAttackAloneEffect() {
+ super(Duration.WhileOnBattlefield);
+ staticText = "{this} can't attack alone";
+ }
+
+ public CantAttackAloneEffect(final CantAttackAloneEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CantAttackAloneEffect copy() {
+ return new CantAttackAloneEffect(this);
+ }
+
+ @Override
+ public boolean canAttackCheckAfter(int numberOfAttackers, Ability source, Game game) {
+ return numberOfAttackers > 1;
+ }
+
+ @Override
+ public boolean applies(Permanent permanent, Ability source, Game game) {
+ return source.getSourceId().equals(permanent.getId());
+ }
+}
diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityTargetEffect.java
index 8117823221a..2532cd38a5b 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityTargetEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityTargetEffect.java
@@ -66,7 +66,11 @@ public class GainAbilityTargetEffect extends ContinuousEffectImpl {
}
public GainAbilityTargetEffect(Ability ability, Duration duration, String rule, boolean onCard) {
- super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA,
+ this(ability, duration, rule, onCard, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA);
+ }
+
+ public GainAbilityTargetEffect(Ability ability, Duration duration, String rule, boolean onCard, Layer layer, SubLayer subLayer) {
+ super(duration, layer, subLayer,
ability.getEffects().size() > 0 ? ability.getEffects().get(0).getOutcome() : Outcome.AddAbility);
this.ability = ability;
staticText = rule;
diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java
index 2513b9a9f5e..2fdb87193bf 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java
@@ -70,7 +70,7 @@ public class UntapAllDuringEachOtherPlayersUntapStepEffect extends ContinuousEff
applied = Boolean.FALSE;
}
if (!applied && layer.equals(Layer.RulesEffects)) {
- if (!game.getActivePlayerId().equals(source.getControllerId()) && game.getStep().getType() == PhaseStep.UNTAP) {
+ if (!source.getControllerId().equals(game.getActivePlayerId()) && game.getStep().getType() == PhaseStep.UNTAP) {
game.getState().setValue(source.getSourceId() + "applied", true);
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
boolean untap = true;
diff --git a/Mage/src/main/java/mage/abilities/keyword/CanAttackOnlyAloneAbility.java b/Mage/src/main/java/mage/abilities/keyword/CanAttackOnlyAloneAbility.java
index 55aa82e3905..f37cb247fed 100644
--- a/Mage/src/main/java/mage/abilities/keyword/CanAttackOnlyAloneAbility.java
+++ b/Mage/src/main/java/mage/abilities/keyword/CanAttackOnlyAloneAbility.java
@@ -1,65 +1,52 @@
/*
-* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are
-* permitted provided that the following conditions are met:
-*
-* 1. Redistributions of source code must retain the above copyright notice, this list of
-* conditions and the following disclaimer.
-*
-* 2. Redistributions in binary form must reproduce the above copyright notice, this list
-* of conditions and the following disclaimer in the documentation and/or other materials
-* provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
-* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* The views and conclusions contained in the software and documentation are those of the
-* authors and should not be interpreted as representing official policies, either expressed
-* or implied, of BetaSteward_at_googlemail.com.
-*/
-
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
package mage.abilities.keyword;
-import java.io.ObjectStreamException;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.combat.CanAttackOnlyAloneEffect;
import mage.constants.Zone;
-import mage.abilities.MageSingleton;
-import mage.abilities.StaticAbility;
/**
* @author LevelX2
*/
-public class CanAttackOnlyAloneAbility extends StaticAbility implements MageSingleton {
+public class CanAttackOnlyAloneAbility extends SimpleStaticAbility {
- private static final CanAttackOnlyAloneAbility fINSTANCE = new CanAttackOnlyAloneAbility();
-
- private Object readResolve() throws ObjectStreamException {
- return fINSTANCE;
+ public CanAttackOnlyAloneAbility() {
+ super(Zone.BATTLEFIELD, new CanAttackOnlyAloneEffect());
}
- public static CanAttackOnlyAloneAbility getInstance() {
- return fINSTANCE;
- }
-
- private CanAttackOnlyAloneAbility() {
- super(Zone.BATTLEFIELD, null);
- }
-
- @Override
- public String getRule() {
- return "{this} can only attack alone.";
+ private CanAttackOnlyAloneAbility(CanAttackOnlyAloneAbility ability) {
+ super(ability);
}
@Override
public CanAttackOnlyAloneAbility copy() {
- return fINSTANCE;
+ return new CanAttackOnlyAloneAbility(this);
}
}
diff --git a/Mage/src/main/java/mage/abilities/keyword/CantAttackAloneAbility.java b/Mage/src/main/java/mage/abilities/keyword/CantAttackAloneAbility.java
index a7b0d7ef72d..fecbd9dcdd6 100644
--- a/Mage/src/main/java/mage/abilities/keyword/CantAttackAloneAbility.java
+++ b/Mage/src/main/java/mage/abilities/keyword/CantAttackAloneAbility.java
@@ -1,66 +1,52 @@
/*
-* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are
-* permitted provided that the following conditions are met:
-*
-* 1. Redistributions of source code must retain the above copyright notice, this list of
-* conditions and the following disclaimer.
-*
-* 2. Redistributions in binary form must reproduce the above copyright notice, this list
-* of conditions and the following disclaimer in the documentation and/or other materials
-* provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
-* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* The views and conclusions contained in the software and documentation are those of the
-* authors and should not be interpreted as representing official policies, either expressed
-* or implied, of BetaSteward_at_googlemail.com.
-*/
-
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
package mage.abilities.keyword;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.combat.CantAttackAloneEffect;
import mage.constants.Zone;
-import mage.abilities.MageSingleton;
-import mage.abilities.StaticAbility;
-
-import java.io.ObjectStreamException;
/**
* @author magenoxx_at_googlemail.com
*/
-public class CantAttackAloneAbility extends StaticAbility implements MageSingleton {
+public class CantAttackAloneAbility extends SimpleStaticAbility {
- private static final CantAttackAloneAbility fINSTANCE = new CantAttackAloneAbility();
-
- private Object readResolve() throws ObjectStreamException {
- return fINSTANCE;
+ public CantAttackAloneAbility() {
+ super(Zone.BATTLEFIELD, new CantAttackAloneEffect());
}
- public static CantAttackAloneAbility getInstance() {
- return fINSTANCE;
- }
-
- private CantAttackAloneAbility() {
- super(Zone.BATTLEFIELD, null);
- }
-
- @Override
- public String getRule() {
- return "{this} can't attack alone.";
+ private CantAttackAloneAbility(CantAttackAloneAbility ability) {
+ super(ability);
}
@Override
public CantAttackAloneAbility copy() {
- return fINSTANCE;
+ return new CantAttackAloneAbility(this);
}
}
diff --git a/Mage/src/main/java/mage/cards/CardImpl.java b/Mage/src/main/java/mage/cards/CardImpl.java
index c57a99b9a5d..055b21c318c 100644
--- a/Mage/src/main/java/mage/cards/CardImpl.java
+++ b/Mage/src/main/java/mage/cards/CardImpl.java
@@ -546,8 +546,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
removed = true;
}
break;
-
- case PICK: // Pick should no longer be used
case BATTLEFIELD: // for sacrificing permanents or putting to library
removed = true;
break;
diff --git a/Mage/src/main/java/mage/cards/decks/DeckCardLists.java b/Mage/src/main/java/mage/cards/decks/DeckCardLists.java
index cb752cfafb5..7079d8996bc 100644
--- a/Mage/src/main/java/mage/cards/decks/DeckCardLists.java
+++ b/Mage/src/main/java/mage/cards/decks/DeckCardLists.java
@@ -1,31 +1,30 @@
/*
-* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are
-* permitted provided that the following conditions are met:
-*
-* 1. Redistributions of source code must retain the above copyright notice, this list of
-* conditions and the following disclaimer.
-*
-* 2. Redistributions in binary form must reproduce the above copyright notice, this list
-* of conditions and the following disclaimer in the documentation and/or other materials
-* provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
-* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* The views and conclusions contained in the software and documentation are those of the
-* authors and should not be interpreted as representing official policies, either expressed
-* or implied, of BetaSteward_at_googlemail.com.
-*/
-
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
package mage.cards.decks;
import java.io.Serializable;
@@ -40,8 +39,8 @@ public class DeckCardLists implements Serializable {
private String name;
private String author;
- private List cards = new ArrayList();
- private List sideboard = new ArrayList();
+ private List cards = new ArrayList<>();
+ private List sideboard = new ArrayList<>();
/**
* @return the cards
diff --git a/Mage/src/main/java/mage/constants/Zone.java b/Mage/src/main/java/mage/constants/Zone.java
index b5318c939ac..8114afa9e7b 100644
--- a/Mage/src/main/java/mage/constants/Zone.java
+++ b/Mage/src/main/java/mage/constants/Zone.java
@@ -6,7 +6,7 @@ package mage.constants;
*/
public enum Zone {
- HAND, GRAVEYARD, LIBRARY, BATTLEFIELD, STACK, EXILED, ALL, OUTSIDE, PICK, COMMAND;
+ HAND, GRAVEYARD, LIBRARY, BATTLEFIELD, STACK, EXILED, ALL, OUTSIDE, COMMAND;
public boolean match(Zone zone) {
return (this == zone || this == ALL || zone == ALL);
diff --git a/Mage/src/main/java/mage/game/combat/Combat.java b/Mage/src/main/java/mage/game/combat/Combat.java
index 7b041bdef57..aa6c20c20ff 100644
--- a/Mage/src/main/java/mage/game/combat/Combat.java
+++ b/Mage/src/main/java/mage/game/combat/Combat.java
@@ -36,11 +36,10 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
+import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.RequirementEffect;
import mage.abilities.effects.RestrictionEffect;
-import mage.abilities.keyword.CanAttackOnlyAloneAbility;
-import mage.abilities.keyword.CantAttackAloneAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.constants.CardType;
import mage.constants.Outcome;
@@ -58,12 +57,15 @@ import mage.target.common.TargetDefender;
import mage.util.CardUtil;
import mage.util.Copyable;
import mage.util.trace.TraceUtil;
+import org.apache.log4j.Logger;
/**
* @author BetaSteward_at_googlemail.com
*/
public class Combat implements Serializable, Copyable {
+ private static final Logger logger = Logger.getLogger(Combat.class);
+
private static FilterPlaneswalkerPermanent filterPlaneswalker = new FilterPlaneswalkerPermanent();
private static FilterCreatureForCombatBlock filterBlockers = new FilterCreatureForCombatBlock();
// There are effects that let creatures assigns combat damage equal to its toughness rather than its power
@@ -252,14 +254,18 @@ public class Combat implements Serializable, Copyable {
Player player = game.getPlayer(attackerId);
//20101001 - 508.1d
game.getCombat().checkAttackRequirements(player, game);
- if (!game.getPlayer(game.getActivePlayerId()).getAvailableAttackers(game).isEmpty()) {
- player.selectAttackers(game, attackerId);
- }
- if (game.isPaused() || game.gameOver(null) || game.executingRollback()) {
- return;
- }
- // because of possible undo during declare attackers it's neccassary to call here the methods with "game.getCombat()." to get the valid combat object!!!
- game.getCombat().checkAttackRestrictions(player, game);
+ boolean firstTime = true;
+ do {
+ if (!firstTime || !game.getPlayer(game.getActivePlayerId()).getAvailableAttackers(game).isEmpty()) {
+ player.selectAttackers(game, attackerId);
+ }
+ firstTime = false;
+ if (game.isPaused() || game.gameOver(null) || game.executingRollback()) {
+ return;
+ }
+ // because of possible undo during declare attackers it's neccassary to call here the methods with "game.getCombat()." to get the current combat object!!!
+ // I don't like it too - it has to be redesigned
+ } while (!game.getCombat().checkAttackRestrictions(player, game));
game.getCombat().resumeSelectAttackers(game);
}
}
@@ -337,50 +343,60 @@ public class Combat implements Serializable, Copyable {
}
}
- protected void checkAttackRestrictions(Player player, Game game) {
- int count = 0;
- for (CombatGroup group : groups) {
- count += group.getAttackers().size();
- }
-
- if (count > 1) {
- List tobeRemoved = new ArrayList<>();
+ /**
+ *
+ * @param player
+ * @param game
+ * @return true if the attack with that set of creatures and attacked
+ * players/planeswalkers is possible
+ */
+ protected boolean checkAttackRestrictions(Player player, Game game) {
+ boolean check = true;
+ int numberOfChecks = 0;
+ UUID attackerToRemove = null;
+ Check:
+ while (check) {
+ check = false;
+ numberOfChecks++;
+ int numberAttackers = 0;
for (CombatGroup group : groups) {
- for (UUID attackingCreatureId : group.getAttackers()) {
- Permanent attacker = game.getPermanent(attackingCreatureId);
- if (count > 1 && attacker != null && attacker.getAbilities().containsKey(CanAttackOnlyAloneAbility.getInstance().getId())) {
- if (!game.isSimulation()) {
- game.informPlayers(attacker.getLogName() + " can only attack alone. Removing it from combat.");
+ numberAttackers += group.getAttackers().size();
+ }
+ Player attackingPlayer = game.getPlayer(attackerId);
+ if (attackerToRemove != null) {
+ removeAttacker(attackerToRemove, game);
+ }
+ for (UUID attackingCreatureId : this.getAttackers()) {
+ Permanent attackingCreature = game.getPermanent(attackingCreatureId);
+ for (Map.Entry> entry : game.getContinuousEffects().getApplicableRestrictionEffects(attackingCreature, game).entrySet()) {
+ RestrictionEffect effect = entry.getKey();
+ for (Ability ability : entry.getValue()) {
+ if (!effect.canAttackCheckAfter(numberAttackers, ability, game)) {
+ MageObject sourceObject = ability.getSourceObject(game);
+ if (attackingPlayer.isHuman()) {
+ game.informPlayer(attackingPlayer, attackingCreature.getIdName() + " can't attack this way (" + (sourceObject == null ? "null" : sourceObject.getIdName()) + ")");
+ return false;
+ } else {
+ // remove attacking creatures for AI that are not allowed to attack
+ // can create possible not allowed attack scenarios, but not sure how to solve this
+ for (CombatGroup combatGroup : this.getGroups()) {
+ if (combatGroup.getAttackers().contains(attackingCreatureId)) {
+ attackerToRemove = attackingCreatureId;
+ }
+ }
+ check = true; // do the check again
+ if (numberOfChecks > 50) {
+ logger.error("Seems to be an AI declare attacker lock (reached 50 check iterations) " + (sourceObject == null ? "null" : sourceObject.getIdName()));
+ return true; // break the check
+ }
+ continue Check;
+ }
}
- tobeRemoved.add(attackingCreatureId);
- count--;
}
}
}
- for (UUID attackingCreatureId : tobeRemoved) {
- this.removeAttacker(attackingCreatureId, game);
- }
}
-
- if (count == 1) {
- List tobeRemoved = new ArrayList<>();
- for (CombatGroup group : groups) {
- for (UUID attackingCreatureId : group.getAttackers()) {
- Permanent attacker = game.getPermanent(attackingCreatureId);
- if (attacker != null && attacker.getAbilities().containsKey(CantAttackAloneAbility.getInstance().getId())) {
- if (!game.isSimulation()) {
- game.informPlayers(attacker.getLogName() + " can't attack alone. Removing it from combat.");
- }
- tobeRemoved.add(attackingCreatureId);
- }
- }
- }
- for (UUID attackingCreatureId : tobeRemoved) {
- this.removeAttacker(attackingCreatureId, game);
- }
-
- }
-
+ return true;
}
public void selectBlockers(Game game) {
diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java
index 1082a21b51a..28753d5a2ef 100644
--- a/Mage/src/main/java/mage/players/PlayerImpl.java
+++ b/Mage/src/main/java/mage/players/PlayerImpl.java
@@ -862,7 +862,7 @@ public abstract class PlayerImpl implements Player, Serializable {
moveObjectToLibrary(objectId, source == null ? null : source.getSourceId(), game, false, false);
}
} else {
- TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library (last one chosen will be bottommost)"));
+ TargetCard target = new TargetCard(Zone.ALL, new FilterCard("card to put on the bottom of your library (last one chosen will be bottommost)"));
target.setRequired(true);
while (isInGame() && cards.size() > 1) {
this.choose(Outcome.Neutral, cards, target, game);
@@ -3344,11 +3344,7 @@ public abstract class PlayerImpl implements Player, Serializable {
StringBuilder sb = new StringBuilder(this.getLogName())
.append(" puts ").append(withName ? card.getLogName() : "a card").append(" ");
if (fromZone != null) {
- if (fromZone.equals(Zone.PICK)) {
- sb.append("a picked card ");
- } else {
- sb.append("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ");
- }
+ sb.append("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ");
}
sb.append("to the ").append(toTop ? "top" : "bottom");
if (card.getOwnerId().equals(getId())) {