Merge origin/master

This commit is contained in:
fireshoes 2015-08-30 01:39:16 -05:00
commit 2f3a3e89ec
106 changed files with 5605 additions and 1024 deletions

View file

@ -1,46 +1,39 @@
/*
* 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.
*/
/*
* ConnectDialog.java
*
* Created on 20-Jan-2010, 9:37:07 PM
*/
package mage.client.dialog;
import mage.client.MageFrame;
import mage.client.util.Config;
import mage.remote.Connection;
import org.apache.log4j.Logger;
import javax.swing.*;
import java.awt.*;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
@ -63,10 +56,17 @@ import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import mage.client.MageFrame;
import static mage.client.dialog.PreferencesDialog.KEY_CONNECTION_URL_SERVER_LIST;
import static mage.client.dialog.PreferencesDialog.KEY_CONNECT_AUTO_CONNECT;
import static mage.client.dialog.PreferencesDialog.KEY_CONNECT_FLAG;
import mage.client.util.Config;
import mage.client.util.gui.countryBox.CountryItemEditor;
import mage.remote.Connection;
import mage.remote.Connection.ProxyType;
import org.apache.log4j.Logger;
/**
* @author BetaSteward_at_googlemail.com
@ -101,11 +101,11 @@ public class ConnectDialog extends MageDialog {
this.txtUserName.setText(MageFrame.getPreferences().get("userName", ""));
this.chkAutoConnect.setSelected(Boolean.parseBoolean(MageFrame.getPreferences().get(KEY_CONNECT_AUTO_CONNECT, "false")));
this.chkForceUpdateDB.setSelected(false); // has always to be set manually to force comparison
String selectedFlag = MageFrame.getPreferences().get(KEY_CONNECT_FLAG, "world");
// set the selected country/flag
for (int i = 0; i < cbFlag.getItemCount(); i++) {
String[] name = (String[])cbFlag.getItemAt(i);
String[] name = (String[]) cbFlag.getItemAt(i);
if (name[1].equals(selectedFlag)) {
cbFlag.setSelectedIndex(i);
break;
@ -124,10 +124,9 @@ public class ConnectDialog extends MageDialog {
}
/**
* This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
@ -293,7 +292,7 @@ public class ConnectDialog extends MageDialog {
private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed
MageFrame.getPreferences().put("autoConnect", Boolean.toString(chkAutoConnect.isSelected()));
MageFrame.getPreferences().put(KEY_CONNECT_FLAG, ((CountryItemEditor)cbFlag.getEditor()).getImageItem());
MageFrame.getPreferences().put(KEY_CONNECT_FLAG, ((CountryItemEditor) cbFlag.getEditor()).getImageItem());
if (task != null && !task.isDone()) {
task.cancel(true);
} else {
@ -329,7 +328,7 @@ public class ConnectDialog extends MageDialog {
connection.setPort(Integer.valueOf(this.txtPort.getText().trim()));
connection.setUsername(this.txtUserName.getText().trim());
connection.setForceDBComparison(this.chkForceUpdateDB.isSelected());
MageFrame.getPreferences().put(KEY_CONNECT_FLAG, ((CountryItemEditor)cbFlag.getEditor()).getImageItem());
MageFrame.getPreferences().put(KEY_CONNECT_FLAG, ((CountryItemEditor) cbFlag.getEditor()).getImageItem());
ProxyType configProxyType = Connection.ProxyType.valueByText(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_TYPE, "None"));
@ -354,8 +353,8 @@ public class ConnectDialog extends MageDialog {
}
// pref settings
MageFrame.getInstance().setUserPrefsToConnection(connection);
MageFrame.getInstance().setUserPrefsToConnection(connection);
logger.debug("connecting: " + connection.getProxyType() + " " + connection.getProxyHost() + " " + connection.getProxyPort());
task = new ConnectTask();
task.execute();
@ -385,7 +384,7 @@ public class ConnectDialog extends MageDialog {
get(CONNECTION_TIMEOUT_MS, TimeUnit.MILLISECONDS);
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
if (result) {
lblStatus.setText("");
lblStatus.setText("");
connected();
MageFrame.getInstance().showGames(false);
} else {
@ -412,7 +411,6 @@ public class ConnectDialog extends MageDialog {
this.hideDialog();
}
private void keyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_keyTyped
char c = evt.getKeyChar();
if (!Character.isDigit(c)) {
@ -428,8 +426,12 @@ public class ConnectDialog extends MageDialog {
private void findPublicServerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
BufferedReader in = null;
try {
URL serverListURL = new URL(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CONNECTION_URL_SERVER_LIST, "http://xmage.de/files/server-list.txt"));
String serverUrl = PreferencesDialog.getCachedValue(KEY_CONNECTION_URL_SERVER_LIST, "http://xmage.de/files/server-list.txt");
if (serverUrl.contains("xmage.info/files/")) {
serverUrl = serverUrl.replace("xmage.info/files/", "xmage.de/files/"); // replace old URL if still saved
PreferencesDialog.saveValue(KEY_CONNECTION_URL_SERVER_LIST, serverUrl);
}
URL serverListURL = new URL(serverUrl);
Connection.ProxyType configProxyType = Connection.ProxyType.valueByText(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_TYPE, "None"));
Proxy p = null;
@ -465,12 +467,12 @@ public class ConnectDialog extends MageDialog {
boolean URLNotFound = false;
try {
in = new BufferedReader(new InputStreamReader(serverListURL.openConnection(p).getInputStream()));
} catch (SocketTimeoutException |FileNotFoundException | UnknownHostException ex ) {
} catch (SocketTimeoutException | FileNotFoundException | UnknownHostException ex) {
logger.warn("Could not read serverlist from: " + serverListURL.toString());
File f = new File("serverlist.txt");
if (f.exists() && !f.isDirectory()) {
logger.info("Using buffered serverlist: serverlist.txt");
URLNotFound = true;
URLNotFound = true;
in = new BufferedReader(new FileReader("serverlist.txt"));
}
}
@ -518,7 +520,7 @@ public class ConnectDialog extends MageDialog {
JOptionPane.showMessageDialog(null, "Wrong server data format.");
}
}
} catch (Exception ex) {
logger.error(ex, ex);
} finally {
@ -539,7 +541,6 @@ public class ConnectDialog extends MageDialog {
// TODO add your handling code here:
}//GEN-LAST:event_chkForceUpdateDBActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnCancel;
private javax.swing.JButton btnConnect;

View file

@ -47,7 +47,9 @@ import mage.client.components.MageTextArea;
import mage.client.dialog.MageDialog;
import mage.client.util.audio.AudioManager;
import mage.client.util.gui.ArrowBuilder;
import mage.constants.Constants;
import static mage.constants.Constants.Option.ORIGINAL_ID;
import static mage.constants.Constants.Option.SECOND_MESSAGE;
import static mage.constants.Constants.Option.SPECIAL_BUTTON;
import mage.constants.PlayerAction;
import mage.remote.Session;
import org.apache.log4j.Logger;
@ -85,6 +87,7 @@ public class FeedbackPanel extends javax.swing.JPanel {
public void init(UUID gameId) {
this.gameId = gameId;
session = MageFrame.getSession();
helper.init(gameId);
}
public void getFeedback(FeedbackMode mode, String message, boolean special, Map<String, Serializable> options, int messageId) {
@ -95,61 +98,42 @@ public class FeedbackPanel extends javax.swing.JPanel {
}
this.lastMessageId = messageId;
}
this.lblMessage.setText(message);
this.helper.setMessage(message);
this.helper.setBasicMessage(message);
this.helper.setOriginalId(null); // reference to the feedback causing ability
String lblText = addAdditionalText(message, options);
this.helper.setTextArea(lblText);
this.lblMessage.setText(lblText);
this.mode = mode;
switch (this.mode) {
case INFORM:
this.btnLeft.setVisible(false);
this.btnRight.setVisible(false);
this.helper.setState("", false, "", false);
setButtonState("", "", mode);
break;
case QUESTION:
this.btnLeft.setVisible(true);
this.btnLeft.setText("Yes");
this.btnRight.setVisible(true);
this.btnRight.setText("No");
this.helper.setState("Yes", true, "No", true);
setButtonState("Yes", "No", mode);
if (options != null && options.containsKey(ORIGINAL_ID)) {
this.helper.setOriginalId((UUID) options.get(ORIGINAL_ID));
}
break;
case CONFIRM:
this.btnLeft.setVisible(true);
this.btnLeft.setText("OK");
this.btnRight.setVisible(true);
this.btnRight.setText("Cancel");
this.helper.setState("Ok", true, "Cancel", true);
setButtonState("OK", "Cancel", mode);
break;
case CANCEL:
this.btnLeft.setVisible(false);
this.btnRight.setVisible(true);
this.btnRight.setText("Cancel");
this.helper.setState("", false, "Cancel", true);
setButtonState("", "Cancel", mode);
this.helper.setUndoEnabled(false);
break;
case SELECT:
this.btnLeft.setVisible(false);
this.btnRight.setVisible(true);
this.btnRight.setText("Done");
this.helper.setState("", false, "Done", true);
setButtonState("", "Done", mode);
break;
case END:
this.btnLeft.setVisible(false);
this.btnRight.setVisible(true);
this.btnRight.setText("Close game");
this.helper.setState("", false, "Close game", true);
setButtonState("", "Close game", mode);
ArrowBuilder.getBuilder().removeAllArrows(gameId);
endWithTimeout();
break;
}
if (options != null && options.containsKey(Constants.Option.SPECIAL_BUTTON)) {
String specialText = (String) options.get(Constants.Option.SPECIAL_BUTTON);
this.btnSpecial.setVisible(true);
this.btnSpecial.setText(specialText);
this.helper.setSpecial(specialText, true);
if (options != null && options.containsKey(SPECIAL_BUTTON)) {
this.setSpecial((String) options.get(SPECIAL_BUTTON), true);
} else {
this.btnSpecial.setVisible(special);
this.btnSpecial.setText("Special");
this.helper.setSpecial("Special", special);
this.setSpecial("Special", special);
}
requestFocusIfPossible();
@ -162,6 +146,32 @@ public class FeedbackPanel extends javax.swing.JPanel {
this.helper.setVisible(true);
}
private void setButtonState(String leftText, String rightText, FeedbackMode mode) {
btnLeft.setVisible(!leftText.isEmpty());
btnLeft.setText(leftText);
btnRight.setVisible(!rightText.isEmpty());
btnRight.setText(rightText);
this.helper.setState(leftText, !leftText.isEmpty(), rightText, !rightText.isEmpty(), mode);
}
private String addAdditionalText(String message, Map<String, Serializable> options) {
if (options != null && options.containsKey(SECOND_MESSAGE)) {
return message + getSmallText((String) options.get(SECOND_MESSAGE));
} else {
return message;
}
}
protected String getSmallText(String text) {
return "<div style='font-size:11pt'>" + text + "</div>";
}
private void setSpecial(String text, boolean visible) {
this.btnSpecial.setText(text);
this.btnSpecial.setVisible(visible);
this.helper.setSpecial(text, visible);
}
/**
* Close game window by pressing OK button after 8 seconds
*/

View file

@ -1998,7 +1998,7 @@ public final class GamePanel extends javax.swing.JPanel {
}
}
if (event.getEventName().equals("action-consumed")) {
dialog.hideDialog();
dialog.removeDialog();
}
}
};
@ -2017,24 +2017,31 @@ public final class GamePanel extends javax.swing.JPanel {
switch (e.getActionCommand()) {
case CMD_AUTO_ORDER_FIRST:
session.sendPlayerAction(TRIGGER_AUTO_ORDER_ABILITY_FIRST, gameId, abilityId);
session.sendPlayerUUID(gameId, abilityId);
break;
case CMD_AUTO_ORDER_LAST:
session.sendPlayerAction(TRIGGER_AUTO_ORDER_ABILITY_LAST, gameId, abilityId);
session.sendPlayerUUID(gameId, null); // Don't use this but refresh the displayed abilities
break;
case CMD_AUTO_ORDER_NAME_FIRST:
if (abilityRuleText != null) {
session.sendPlayerAction(TRIGGER_AUTO_ORDER_NAME_FIRST, gameId, abilityRuleText);
session.sendPlayerUUID(gameId, abilityId);
}
break;
case CMD_AUTO_ORDER_NAME_LAST:
if (abilityRuleText != null) {
session.sendPlayerAction(TRIGGER_AUTO_ORDER_NAME_LAST, gameId, abilityRuleText);
session.sendPlayerUUID(gameId, null); // Don't use this but refresh the displayed abilities
}
break;
case CMD_AUTO_ORDER_RESET_ALL:
session.sendPlayerAction(TRIGGER_AUTO_ORDER_RESET_ALL, gameId, null);
break;
}
for (ShowCardsDialog dialog : pickTarget) {
dialog.removeDialog();
}
}
private void initPopupMenuTriggerOrder() {

View file

@ -28,17 +28,34 @@
package mage.client.game;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.UUID;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import mage.client.MageFrame;
import mage.client.components.MageTextArea;
import mage.client.game.FeedbackPanel.FeedbackMode;
import static mage.client.game.FeedbackPanel.FeedbackMode.QUESTION;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_ID_NO;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_ID_YES;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_TEXT_NO;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_TEXT_YES;
import mage.remote.Session;
/**
* Panel with buttons that copy the state of feedback panel.
@ -64,12 +81,34 @@ public class HelperPanel extends JPanel {
private final int defaultDismissTimeout = ToolTipManager.sharedInstance().getDismissDelay();
private final Object tooltipBackground = UIManager.get("info");
private static final String CMD_AUTO_ANSWER_ID_YES = "cmdAutoAnswerIdYes";
private static final String CMD_AUTO_ANSWER_ID_NO = "cmdAutoAnswerIdNo";
private static final String CMD_AUTO_ANSWER_NAME_YES = "cmdAutoAnswerNameYes";
private static final String CMD_AUTO_ANSWER_NAME_NO = "cmdAutoAnswerNameNo";
private static final String CMD_AUTO_ANSWER_RESET_ALL = "cmdAutoAnswerResetAll";
// popup menu for set automatic answers
private JPopupMenu popupMenuAskYes;
private JPopupMenu popupMenuAskNo;
// originalId of feedback causing ability
private UUID originalId;
private String message;
private UUID gameId;
private Session session;
public HelperPanel() {
initComponents();
}
private void initComponents() {
public void init(UUID gameId) {
this.gameId = gameId;
session = MageFrame.getSession();
}
private void initComponents() {
initPopupMenuTriggerOrder();
setBackground(new Color(0, 0, 0, 100));
//setLayout(new GridBagLayout());
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
@ -108,72 +147,44 @@ public class HelperPanel extends JPanel {
btnUndo.setVisible(false);
container.add(btnUndo);
btnLeft.addActionListener(new java.awt.event.ActionListener() {
MouseListener checkPopupAdapter = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent me) {
checkPopupMenu(me);
}
@Override
public void mouseReleased(MouseEvent me) {
checkPopupMenu(me);
}
};
btnLeft.addMouseListener(checkPopupAdapter);
btnLeft.addActionListener(new ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
if (linkLeft != null) {
{
Thread worker = new Thread() {
@Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setState("", false, "", false);
setSpecial("", false);
linkLeft.doClick();
}
});
}
};
worker.start();
}
clickButton(linkLeft);
}
}
});
btnRight.addActionListener(new java.awt.event.ActionListener() {
btnRight.addMouseListener(checkPopupAdapter);
btnRight.addActionListener(new ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
if (linkRight != null) {
Thread worker = new Thread() {
@Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setState("", false, "", false);
setSpecial("", false);
linkRight.doClick();
}
});
}
};
worker.start();
clickButton(linkRight);
}
}
});
btnSpecial.addActionListener(new java.awt.event.ActionListener() {
btnSpecial.addActionListener(new ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
if (linkSpecial != null) {
{
Thread worker = new Thread() {
@Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setState("", false, "", false);
setSpecial("", false);
linkSpecial.doClick();
}
});
}
};
worker.start();
}
clickButton(linkSpecial);
}
}
});
@ -200,7 +211,7 @@ public class HelperPanel extends JPanel {
}
});
// sets a darker background and higher simiss time fpr tooltip in the feedback / helper panel
// sets a darker background and higher simiss time fur tooltip in the feedback / helper panel
textArea.addMouseListener(new MouseAdapter() {
@Override
@ -217,15 +228,50 @@ public class HelperPanel extends JPanel {
});
}
public void setState(String txtLeft, boolean leftVisible, String txtRight, boolean rightVisible) {
private void checkPopupMenu(MouseEvent me) {
if (me.isPopupTrigger()
&& originalId != null) { // only Yes/No requests from abilities can be automated
JButton source = (JButton) me.getSource();
if (source.getActionCommand().startsWith(QUESTION.toString())) {
showPopupMenu(me.getComponent(), source.getActionCommand());
me.consume();
}
}
}
private void clickButton(final JButton button) {
Thread worker = new Thread() {
@Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setState("", false, "", false, null);
setSpecial("", false);
button.doClick();
}
});
}
};
worker.start();
}
public void setState(String txtLeft, boolean leftVisible, String txtRight, boolean rightVisible, FeedbackMode mode) {
this.btnLeft.setVisible(leftVisible);
if (!txtLeft.isEmpty()) {
this.btnLeft.setText(txtLeft);
if (mode != null) {
this.btnLeft.setActionCommand(mode.toString() + txtLeft);
}
}
this.btnRight.setVisible(rightVisible);
if (!txtRight.isEmpty()) {
this.btnRight.setText(txtRight);
if (mode != null) {
this.btnRight.setActionCommand(mode.toString() + txtRight);
}
}
}
public void setSpecial(String txtSpecial, boolean specialVisible) {
@ -251,25 +297,116 @@ public class HelperPanel extends JPanel {
this.linkUndo = undo;
}
public void setMessage(String message) {
// if (message.startsWith("Use alternative cost")) {
// message = "Use alternative cost?";
// } else if (message.contains("Use ")) {
// if (message.length() < this.getWidth() / 10) {
// message = getSmallText(message);
// } else {
// message = "Use ability?" + getSmallText(message.substring(0, this.getWidth() / 10));
// }
// }
textArea.setText(message, this.getWidth());
public void setOriginalId(UUID originalId) {
this.originalId = originalId;
}
protected String getSmallText(String text) {
return "<div style='font-size:11pt'>" + text + "</div>";
public void setBasicMessage(String message) {
this.message = message;
this.textArea.setText(message, this.getWidth());
}
public void setTextArea(String message) {
this.textArea.setText(message, this.getWidth());
}
@Override
public void requestFocus() {
this.btnRight.requestFocus();
}
private void initPopupMenuTriggerOrder() {
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
handleAutoAnswerPopupMenuEvent(e);
}
};
popupMenuAskYes = new JPopupMenu();
popupMenuAskNo = new JPopupMenu();
// String tooltipText = "";
JMenuItem menuItem;
menuItem = new JMenuItem("Always Yes for the same text and ability");
menuItem.setActionCommand(CMD_AUTO_ANSWER_ID_YES);
menuItem.addActionListener(actionListener);
menuItem.setToolTipText("<HTML>If the same question from the same ability would<br/>be asked again, it's automatically answered with <b>Yes</b>.");
popupMenuAskYes.add(menuItem);
menuItem = new JMenuItem("Always No for the same text and ability");
menuItem.setActionCommand(CMD_AUTO_ANSWER_ID_NO);
menuItem.setToolTipText("<HTML>If the same question from the same ability would<br/>be asked again, it's automatically answered with <b>No</b>.");
menuItem.addActionListener(actionListener);
popupMenuAskNo.add(menuItem);
menuItem = new JMenuItem("Always Yes for the same text");
menuItem.setActionCommand(CMD_AUTO_ANSWER_NAME_YES);
menuItem.setToolTipText("<HTML>If the same question would be asked again (regardless from which source),<br/> it's automatically answered with <b>Yes</b>.");
menuItem.addActionListener(actionListener);
popupMenuAskYes.add(menuItem);
menuItem = new JMenuItem("Always No for the same text");
menuItem.setActionCommand(CMD_AUTO_ANSWER_NAME_NO);
menuItem.setToolTipText("<HTML>If the same question would be asked again (regardless from which source),<br/> it's automatically answered with <b>No</b>.");
menuItem.addActionListener(actionListener);
popupMenuAskNo.add(menuItem);
menuItem = new JMenuItem("Delete all automatic Yes/No settings");
menuItem.setActionCommand(CMD_AUTO_ANSWER_RESET_ALL);
menuItem.addActionListener(actionListener);
popupMenuAskYes.add(menuItem);
menuItem = new JMenuItem("Delete all automatic Yes/No settings");
menuItem.setActionCommand(CMD_AUTO_ANSWER_RESET_ALL);
menuItem.addActionListener(actionListener);
popupMenuAskNo.add(menuItem);
}
public void handleAutoAnswerPopupMenuEvent(ActionEvent e) {
switch (e.getActionCommand()) {
case CMD_AUTO_ANSWER_ID_YES:
session.sendPlayerAction(REQUEST_AUTO_ANSWER_ID_YES, gameId, originalId.toString() + "#" + message);
clickButton(btnLeft);
break;
case CMD_AUTO_ANSWER_ID_NO:
session.sendPlayerAction(REQUEST_AUTO_ANSWER_ID_NO, gameId, originalId.toString() + "#" + message);
clickButton(btnRight);
break;
case CMD_AUTO_ANSWER_NAME_YES:
session.sendPlayerAction(REQUEST_AUTO_ANSWER_TEXT_YES, gameId, message);
clickButton(btnLeft);
break;
case CMD_AUTO_ANSWER_NAME_NO:
session.sendPlayerAction(REQUEST_AUTO_ANSWER_TEXT_NO, gameId, message);
clickButton(btnRight);
break;
case CMD_AUTO_ANSWER_RESET_ALL:
session.sendPlayerAction(REQUEST_AUTO_ANSWER_RESET_ALL, gameId, null);
break;
}
}
private void showPopupMenu(Component callingComponent, String actionCommand) {
// Get the location of the point 'on the screen'
Point p = callingComponent.getLocationOnScreen();
// Show the JPopupMenu via program
// Parameter desc
// ----------------
// this - represents current frame
// 0,0 is the co ordinate where the popup
// is shown
JPopupMenu menu;
if (actionCommand.endsWith("Yes")) {
menu = popupMenuAskYes;
} else {
menu = popupMenuAskNo;
}
menu.show(this, 0, 0);
// Now set the location of the JPopupMenu
// This location is relative to the screen
menu.setLocation(p.x, p.y + callingComponent.getHeight());
}
}

View file

@ -290,6 +290,18 @@ public class PlayAreaPanel extends javax.swing.JPanel {
}
});
menuItem = new JMenuItem("Use requests - reset automatic answers");
menuItem.setMnemonic(KeyEvent.VK_T);
menuItem.setToolTipText("Deletes all defined automatic answers for Yes/No usage requests.");
automaticConfirmsMenu.add(menuItem);
// Reset the replacement effcts that were auto selected for the game
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
gamePanel.getSession().sendPlayerAction(PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL, gameId, null);
}
});
JMenu handCardsMenu = new JMenu("Cards on hand");
handCardsMenu.setMnemonic(KeyEvent.VK_H);
popupMenu.add(handCardsMenu);

View file

@ -135,10 +135,10 @@ public class MageActionCallback implements ActionCallback {
ArrowUtil.drawArrowsForPairedCards(data, parentPoint);
ArrowUtil.drawArrowsForEnchantPlayers(data, parentPoint);
showPopup(data, parentComponent, parentPoint);
showTooltipPopup(data, parentComponent, parentPoint);
}
private void showPopup(final TransferData data, final Component parentComponent, final Point parentPoint) {
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")) {

View file

@ -11,11 +11,11 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Arrow extends JPanel {
private static final long serialVersionUID = -4631054277822828303L;
private int startX;
@ -27,21 +27,25 @@ public class Arrow extends JPanel {
private Composite composite;
private Color color = Color.red;
public Arrow () {
public Arrow() {
setOpaque(false);
setOpacity(0.6f);
}
protected void paintComponent (Graphics g) {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
float ex = endX - startX;
float ey = endY - startY;
if (ex == 0 && ey == 0) return;
float length = (float)Math.sqrt(ex * ex + ey * ey);
float bendPercent = (float)Math.asin(ey / length);
if (endX > startX) bendPercent = -bendPercent;
if (ex == 0 && ey == 0) {
return;
}
float length = (float) Math.sqrt(ex * ex + ey * ey);
float bendPercent = (float) Math.asin(ey / length);
if (endX > startX) {
bendPercent = -bendPercent;
}
Area arrow = getArrow(length, bendPercent);
Graphics2D g2d = (Graphics2D)g;
Graphics2D g2d = (Graphics2D) g;
g2d.translate(startX, startY);
g2d.rotate(Math.atan2(ey, ex));
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
@ -52,16 +56,16 @@ public class Arrow extends JPanel {
g2d.draw(arrow);
}
private Area getArrow (float length, float bendPercent) {
private Area getArrow(float length, float bendPercent) {
float p1x = 0, p1y = 0;
float p2x = length, p2y = 0;
float cx = length / 2, cy = length / 8f * bendPercent;
float adjSize, ex, ey, abs_e;
adjSize = (float)(bodyWidth / 2 / Math.sqrt(2));
adjSize = (float) (bodyWidth / 2 / Math.sqrt(2));
ex = p2x - cx;
ey = p2y - cy;
abs_e = (float)Math.sqrt(ex * ex + ey * ey);
abs_e = (float) Math.sqrt(ex * ex + ey * ey);
ex /= abs_e;
ey /= abs_e;
GeneralPath bodyPath = new GeneralPath();
@ -71,10 +75,10 @@ public class Arrow extends JPanel {
bodyPath.quadTo(cx, cy, p2x - (ey + ex) * adjSize, p2y + (ex - ey) * adjSize);
bodyPath.closePath();
adjSize = (float)(headSize / Math.sqrt(2));
adjSize = (float) (headSize / Math.sqrt(2));
ex = p2x - cx;
ey = p2y - cy;
abs_e = (float)Math.sqrt(ex * ex + ey * ey);
abs_e = (float) Math.sqrt(ex * ex + ey * ey);
ex /= abs_e;
ey /= abs_e;
GeneralPath headPath = new GeneralPath();
@ -88,23 +92,23 @@ public class Arrow extends JPanel {
return area;
}
public int getBodyWidth () {
public int getBodyWidth() {
return bodyWidth;
}
public void setBodyWidth (int bodyWidth) {
public void setBodyWidth(int bodyWidth) {
this.bodyWidth = bodyWidth;
}
public float getHeadSize () {
public float getHeadSize() {
return headSize;
}
public void setHeadSize (float headSize) {
public void setHeadSize(float headSize) {
this.headSize = headSize;
}
public void setArrowLocation (int startX, int startY, int endX, int endY) {
public void setArrowLocation(int startX, int startY, int endX, int endY) {
this.startX = startX;
this.startY = startY;
this.endX = endX;
@ -112,7 +116,7 @@ public class Arrow extends JPanel {
repaint();
}
public void setOpacity (float opacity) {
public void setOpacity(float opacity) {
composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity);
}
@ -120,7 +124,7 @@ public class Arrow extends JPanel {
this.color = color;
}
public static void main (String[] args) {
public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
@ -130,11 +134,13 @@ public class Arrow extends JPanel {
frame.setResizable(false);
frame.setVisible(true);
frame.getContentPane().addMouseMotionListener(new MouseMotionListener() {
public void mouseMoved (MouseEvent e) {
@Override
public void mouseMoved(MouseEvent e) {
arrow.setArrowLocation(320, 240, e.getX(), e.getY());
}
public void mouseDragged (MouseEvent e) {
@Override
public void mouseDragged(MouseEvent e) {
}
});
}

View file

@ -64,6 +64,6 @@ ddd=gvl
unh=uh
dde=pvc
# Remove setname as soon as the images can be downloaded
ignore.urls=TOK,MM2,V15,BFZ,DDP
ignore.urls=TOK,V15,DDP
# sets ordered by release time (newest goes first)
token.lookup.order=DDP,BFZ,FVD,FVE,FVL,FVR,V12,V13,V14,V15,TPR,MPRP,DD3,DDO,ORI,MM2,PTC,DTK,FRF,KTK,M15,VMA,CNS,JOU,BNG,THS,DDL,M14,MMA,DGM,GTC,RTR,M13,AVR,DDI,DKA,ISD,M12,NPH,MBS,SOM,M11,ROE,DDE,WWK,ZEN,M10,GVL,ARB,DVD,CFX,JVC,ALA,EVE,SHM,EVG,MOR,LRW,10E,CLS,CHK,GRC

View file

@ -83,6 +83,10 @@ public final class Constants {
public static final String POSSIBLE_ATTACKERS = "possibleAttackers";
public static final String SPECIAL_BUTTON = "specialButton";
// used to control automatic answers of optional effects
public static final String ORIGINAL_ID = "originalId";
public static final String SECOND_MESSAGE = "secondMessage";
public static final String HINT_TEXT = "hintText";
}

View file

@ -1,16 +1,16 @@
/*
* Copyright 2011 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
@ -20,7 +20,7 @@
* 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.
@ -38,8 +38,8 @@ public class MageVersionException extends MageException {
private final MageVersion serverVersion;
public MageVersionException(MageVersion clientVersion, MageVersion serverVersion) {
super("Wrong client version " + clientVersion + ", expecting version " + serverVersion + ". \r\n\r\nPlease download needed version from http://XMage.info or http://www.slightlymagic.net/forum/viewforum.php?f=70");
public MageVersionException(MageVersion clientVersion, MageVersion serverVersion) {
super("Wrong client version " + clientVersion + ", expecting version " + serverVersion + ". \r\n\r\nPlease download needed version from http://XMage.de or http://www.slightlymagic.net/forum/viewforum.php?f=70");
this.serverVersion = serverVersion;
}

View file

@ -63,6 +63,7 @@ import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.PhaseStep;
import mage.constants.PlayerAction;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL;
import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL;
import mage.constants.RangeOfInfluence;
import mage.constants.Zone;
@ -89,6 +90,7 @@ import mage.target.common.TargetCreatureOrPlayer;
import mage.target.common.TargetDefender;
import mage.util.GameLog;
import mage.util.ManaUtil;
import mage.util.MessageToClient;
import org.apache.log4j.Logger;
/**
@ -105,7 +107,7 @@ public class HumanPlayer extends PlayerImpl {
protected static FilterBlockingCreature filterBlock = new FilterBlockingCreature();
protected final Choice replacementEffectChoice;
private static final Logger log = Logger.getLogger(HumanPlayer.class);
private static final Logger logger = Logger.getLogger(HumanPlayer.class);
protected HashSet<String> autoSelectReplacementEffects = new HashSet<>();
protected ManaCost currentlyUnpaidMana;
@ -115,6 +117,9 @@ public class HumanPlayer extends PlayerImpl {
protected Set<String> triggerAutoOrderNameFirst = new HashSet<>();
protected Set<String> triggerAutoOrderNameLast = new HashSet<>();
protected Map<String, Boolean> requestAutoAnswerId = new HashMap<>();
protected Map<String, Boolean> requestAutoAnswerText = new HashMap<>();
public HumanPlayer(String name, RangeOfInfluence range, int skill) {
super(name, range);
replacementEffectChoice = new ChoiceImpl(true);
@ -131,53 +136,30 @@ public class HumanPlayer extends PlayerImpl {
protected void waitForResponse(Game game) {
response.clear();
log.debug("Waiting response from player: " + getId());
logger.debug("Waiting response from player: " + getId());
game.resumeTimer(getTurnControlledBy());
synchronized (response) {
try {
response.wait();
log.debug("Got response from player: " + getId());
logger.debug("Got response from player: " + getId());
} catch (InterruptedException ex) {
ex.printStackTrace();
logger.error("Response error for player " + getName() + " gameId: " + game.getId(), ex);
} finally {
game.pauseTimer(getTurnControlledBy());
}
}
}
protected void waitForBooleanResponse(Game game) {
do {
waitForResponse(game);
} while (response.getBoolean() == null && !abort);
}
protected void waitForUUIDResponse(Game game) {
do {
waitForResponse(game);
} while (response.getUUID() == null && !abort);
}
protected void waitForStringResponse(Game game) {
do {
waitForResponse(game);
} while (response.getString() == null && !abort);
}
protected void waitForIntegerResponse(Game game) {
do {
waitForResponse(game);
} while (response.getInteger() == null && !abort);
}
@Override
public boolean chooseMulligan(Game game) {
updateGameStatePriority("chooseMulligan", game);
int nextHandSize = game.mulliganDownTo(playerId);
game.fireAskPlayerEvent(playerId, new StringBuilder("Mulligan ")
.append(getHand().size() > nextHandSize ? "down to " : "for free, draw ")
.append(nextHandSize)
.append(nextHandSize == 1 ? " card?" : " cards?").toString());
waitForBooleanResponse(game);
do {
game.fireAskPlayerEvent(playerId, new MessageToClient("Mulligan "
+ (getHand().size() > nextHandSize ? "down to " : "for free, draw ")
+ nextHandSize + (nextHandSize == 1 ? " card?" : " cards?")), null);
waitForResponse(game);
} while (response.getBoolean() == null && !abort);
if (!abort) {
return response.getBoolean();
}
@ -186,15 +168,43 @@ public class HumanPlayer extends PlayerImpl {
@Override
public boolean chooseUse(Outcome outcome, String message, Ability source, Game game) {
if (source != null) {
Boolean answer = requestAutoAnswerId.get(source.getOriginalId() + "#" + message);
if (answer != null) {
return answer;
} else {
answer = requestAutoAnswerText.get(message);
if (answer != null) {
return answer;
}
}
}
updateGameStatePriority("chooseUse", game);
game.fireAskPlayerEvent(playerId, addSecondLineWithObjectName(message, source == null ? null : source.getSourceId(), game));
waitForBooleanResponse(game);
do {
game.fireAskPlayerEvent(playerId, new MessageToClient(message, getRelatedObjectName(source, game)), source);
waitForResponse(game);
} while (response.getBoolean() == null && !abort);
if (!abort) {
return response.getBoolean();
}
return false;
}
private String getRelatedObjectName(Ability source, Game game) {
if (source != null) {
return getRelatedObjectName(source.getSourceId(), game);
}
return null;
}
private String getRelatedObjectName(UUID sourceId, Game game) {
MageObject mageObject = game.getObject(sourceId);
if (mageObject != null) {
return mageObject.getLogName();
}
return null;
}
private String addSecondLineWithObjectName(String message, UUID sourceId, Game game) {
if (sourceId != null) {
MageObject mageObject = game.getPermanent(sourceId);
@ -232,7 +242,7 @@ public class HumanPlayer extends PlayerImpl {
while (!abort) {
game.fireChooseChoiceEvent(playerId, replacementEffectChoice);
waitForResponse(game);
log.debug("Choose effect: " + response.getString());
logger.debug("Choose effect: " + response.getString());
if (response.getString() != null) {
if (response.getString().startsWith("#")) {
autoSelectReplacementEffects.add(response.getString().substring(1));
@ -304,7 +314,7 @@ public class HumanPlayer extends PlayerImpl {
List<UUID> chosen = target.getTargets();
options.put("chosen", (Serializable) chosen);
game.fireSelectTargetEvent(getId(), addSecondLineWithObjectName(target.getMessage(), sourceId, game), targetIds, required, getOptions(target, options));
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(), getRelatedObjectName(sourceId, game)), targetIds, required, getOptions(target, options));
waitForResponse(game);
if (response.getUUID() != null) {
if (!targetIds.contains(response.getUUID())) {
@ -370,7 +380,7 @@ public class HumanPlayer extends PlayerImpl {
required = false;
}
game.fireSelectTargetEvent(getId(), addSecondLineWithObjectName(target.getMessage(), source == null ? null : source.getSourceId(), game), possibleTargets, required, getOptions(target, null));
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)), possibleTargets, required, getOptions(target, null));
waitForResponse(game);
if (response.getUUID() != null) {
if (target.getTargets().contains(response.getUUID())) {
@ -438,7 +448,7 @@ public class HumanPlayer extends PlayerImpl {
options.put("choosable", (Serializable) choosable);
}
game.fireSelectTargetEvent(playerId, target.getMessage(), cards, required, options);
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage()), cards, required, options);
waitForResponse(game);
if (response.getUUID() != null) {
if (target.canTarget(response.getUUID(), cards, game)) {
@ -492,7 +502,7 @@ public class HumanPlayer extends PlayerImpl {
if (!choosable.isEmpty()) {
options.put("choosable", (Serializable) choosable);
}
game.fireSelectTargetEvent(playerId, addSecondLineWithObjectName(target.getMessage(), source == null ? null : source.getSourceId(), game), cards, required, options);
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)), cards, required, options);
waitForResponse(game);
if (response.getUUID() != null) {
if (target.getTargets().contains(response.getUUID())) { // if already included remove it
@ -521,7 +531,7 @@ public class HumanPlayer extends PlayerImpl {
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
updateGameStatePriority("chooseTargetAmount", game);
while (!abort) {
game.fireSelectTargetEvent(playerId, addSecondLineWithObjectName(target.getMessage() + "\n Amount remaining:" + target.getAmountRemaining(), source == null ? null : source.getSourceId(), game),
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage() + "\n Amount remaining:" + target.getAmountRemaining(), getRelatedObjectName(source, game)),
target.possibleTargets(source == null ? null : source.getSourceId(), playerId, game),
target.isRequired(source),
getOptions(target, null));
@ -675,35 +685,34 @@ public class HumanPlayer extends PlayerImpl {
@Override
public TriggeredAbility chooseTriggeredAbility(List<TriggeredAbility> abilities, Game game) {
// try to set trigger auto order
List<TriggeredAbility> abilitiesWithNoOrderSet = new ArrayList<>();
TriggeredAbility abilityOrderLast = null;
for (TriggeredAbility ability : abilities) {
if (triggerAutoOrderAbilityFirst.contains(ability.getOriginalId())) {
return ability;
}
if (triggerAutoOrderNameFirst.contains(ability.getRule())) {
return ability;
}
if (triggerAutoOrderAbilityLast.contains(ability.getOriginalId())) {
abilityOrderLast = ability;
continue;
}
if (triggerAutoOrderNameLast.contains(ability.getRule())) {
abilityOrderLast = ability;
continue;
}
abilitiesWithNoOrderSet.add(ability);
}
if (abilitiesWithNoOrderSet.isEmpty()) {
return abilityOrderLast;
}
if (abilitiesWithNoOrderSet.size() == 1) {
return abilitiesWithNoOrderSet.iterator().next();
}
updateGameStatePriority("chooseTriggeredAbility", game);
while (!abort) {
// try to set trigger auto order
List<TriggeredAbility> abilitiesWithNoOrderSet = new ArrayList<>();
TriggeredAbility abilityOrderLast = null;
for (TriggeredAbility ability : abilities) {
if (triggerAutoOrderAbilityFirst.contains(ability.getOriginalId())) {
return ability;
}
if (triggerAutoOrderNameFirst.contains(ability.getRule())) {
return ability;
}
if (triggerAutoOrderAbilityLast.contains(ability.getOriginalId())) {
abilityOrderLast = ability;
continue;
}
if (triggerAutoOrderNameLast.contains(ability.getRule())) {
abilityOrderLast = ability;
continue;
}
abilitiesWithNoOrderSet.add(ability);
}
if (abilitiesWithNoOrderSet.isEmpty()) {
return abilityOrderLast;
}
if (abilitiesWithNoOrderSet.size() == 1) {
return abilitiesWithNoOrderSet.iterator().next();
}
updateGameStatePriority("chooseTriggeredAbility", game);
game.fireSelectTargetTriggeredAbilityEvent(playerId, "Pick triggered ability (goes to the stack first)", abilitiesWithNoOrderSet);
waitForResponse(game);
if (response.getUUID() != null) {
@ -779,8 +788,10 @@ public class HumanPlayer extends PlayerImpl {
public int announceXMana(int min, int max, String message, Game game, Ability ability) {
int xValue = 0;
updateGameStatePriority("announceXMana", game);
game.fireGetAmountEvent(playerId, message, min, max);
waitForIntegerResponse(game);
do {
game.fireGetAmountEvent(playerId, message, min, max);
waitForResponse(game);
} while (response.getInteger() == null && !abort);
if (response != null && response.getInteger() != null) {
xValue = response.getInteger();
}
@ -791,8 +802,10 @@ public class HumanPlayer extends PlayerImpl {
public int announceXCost(int min, int max, String message, Game game, Ability ability, VariableCost variableCost) {
int xValue = 0;
updateGameStatePriority("announceXCost", game);
game.fireGetAmountEvent(playerId, message, min, max);
waitForIntegerResponse(game);
do {
game.fireGetAmountEvent(playerId, message, min, max);
waitForResponse(game);
} while (response.getInteger() == null && !abort);
if (response != null && response.getInteger() != null) {
xValue = response.getInteger();
}
@ -1043,7 +1056,8 @@ public class HumanPlayer extends PlayerImpl {
protected void selectCombatGroup(UUID defenderId, UUID blockerId, Game game) {
updateGameStatePriority("selectCombatGroup", game);
TargetAttackingCreature target = new TargetAttackingCreature();
game.fireSelectTargetEvent(playerId, addSecondLineWithObjectName("Select attacker to block", blockerId, game), target.possibleTargets(null, playerId, game), false, getOptions(target, null));
game.fireSelectTargetEvent(playerId, new MessageToClient("Select attacker to block", getRelatedObjectName(blockerId, game)),
target.possibleTargets(null, playerId, game), false, getOptions(target, null));
waitForResponse(game);
if (response.getBoolean() != null) {
// do nothing
@ -1090,8 +1104,10 @@ public class HumanPlayer extends PlayerImpl {
@Override
public int getAmount(int min, int max, String message, Game game) {
updateGameStatePriority("getAmount", game);
game.fireGetAmountEvent(playerId, message, min, max);
waitForIntegerResponse(game);
do {
game.fireGetAmountEvent(playerId, message, min, max);
waitForResponse(game);
} while (response.getInteger() == null && !abort);
if (response != null && response.getInteger() != null) {
return response.getInteger();
} else {
@ -1178,11 +1194,7 @@ public class HumanPlayer extends PlayerImpl {
if (!ability.getSourceId().equals(getCastSourceIdWithAlternateMana()) && ability.getManaCostsToPay().convertedManaCost() > 0) {
return true;
}
if (ability instanceof ManaAbility) {
return true;
}
// if ability has no mana costs you have to pick it from ability picker
return false;
return ability instanceof ManaAbility;
}
return true;
}
@ -1257,8 +1269,10 @@ public class HumanPlayer extends PlayerImpl {
@Override
public boolean choosePile(Outcome outcome, String message, List<? extends Card> pile1, List<? extends Card> pile2, Game game) {
updateGameStatePriority("choosePile", game);
game.fireChoosePileEvent(playerId, message, pile1, pile2);
waitForBooleanResponse(game);
do {
game.fireChoosePileEvent(playerId, message, pile1, pile2);
waitForResponse(game);
} while (response.getBoolean() == null && !abort);
if (!abort) {
return response.getBoolean();
}
@ -1270,7 +1284,7 @@ public class HumanPlayer extends PlayerImpl {
synchronized (response) {
response.setString(responseString);
response.notify();
log.debug("Got response string from player: " + getId());
logger.debug("Got response string from player: " + getId());
}
}
@ -1280,7 +1294,7 @@ public class HumanPlayer extends PlayerImpl {
response.setManaType(manaType);
response.setResponseManaTypePlayerId(manaTypePlayerId);
response.notify();
log.debug("Got response mana type from player: " + getId());
logger.debug("Got response mana type from player: " + getId());
}
}
@ -1289,7 +1303,7 @@ public class HumanPlayer extends PlayerImpl {
synchronized (response) {
response.setUUID(responseUUID);
response.notify();
log.debug("Got response UUID from player: " + getId());
logger.debug("Got response UUID from player: " + getId());
}
}
@ -1298,7 +1312,7 @@ public class HumanPlayer extends PlayerImpl {
synchronized (response) {
response.setBoolean(responseBoolean);
response.notify();
log.debug("Got response boolean from player: " + getId());
logger.debug("Got response boolean from player: " + getId());
}
}
@ -1307,7 +1321,7 @@ public class HumanPlayer extends PlayerImpl {
synchronized (response) {
response.setInteger(responseInteger);
response.notify();
log.debug("Got response integer from player: " + getId());
logger.debug("Got response integer from player: " + getId());
}
}
@ -1316,7 +1330,7 @@ public class HumanPlayer extends PlayerImpl {
abort = true;
synchronized (response) {
response.notify();
log.debug("Got cancel action from player: " + getId());
logger.debug("Got cancel action from player: " + getId());
}
}
@ -1325,7 +1339,7 @@ public class HumanPlayer extends PlayerImpl {
synchronized (response) {
response.setInteger(0);
response.notify();
log.debug("Got skip action from player: " + getId());
logger.debug("Got skip action from player: " + getId());
}
}
@ -1336,7 +1350,7 @@ public class HumanPlayer extends PlayerImpl {
protected void updateGameStatePriority(String methodName, Game game) {
if (game.getState().getPriorityPlayerId() != null) { // don't do it if priority was set to null before (e.g. discard in cleanaup)
log.debug("Setting game priority to " + getId() + " [" + methodName + "]");
logger.debug("Setting game priority to " + getId() + " [" + methodName + "]");
game.getState().setPriorityPlayerId(getId());
}
}
@ -1354,11 +1368,43 @@ public class HumanPlayer extends PlayerImpl {
case TRIGGER_AUTO_ORDER_RESET_ALL:
setTriggerAutoOrder(playerAction, game, data);
break;
case REQUEST_AUTO_ANSWER_ID_NO:
case REQUEST_AUTO_ANSWER_ID_YES:
case REQUEST_AUTO_ANSWER_TEXT_NO:
case REQUEST_AUTO_ANSWER_TEXT_YES:
case REQUEST_AUTO_ANSWER_RESET_ALL:
setRequestAutoAnswer(playerAction, game, data);
break;
default:
super.sendPlayerAction(playerAction, game, data);
}
}
private void setRequestAutoAnswer(PlayerAction playerAction, Game game, Object data) {
if (playerAction.equals(REQUEST_AUTO_ANSWER_RESET_ALL)) {
requestAutoAnswerId.clear();
requestAutoAnswerText.clear();
return;
}
if (data instanceof String) {
String key = (String) data;
switch (playerAction) {
case REQUEST_AUTO_ANSWER_ID_NO:
requestAutoAnswerId.put(key, false);
break;
case REQUEST_AUTO_ANSWER_TEXT_NO:
requestAutoAnswerText.put(key, false);
break;
case REQUEST_AUTO_ANSWER_ID_YES:
requestAutoAnswerId.put(key, true);
break;
case REQUEST_AUTO_ANSWER_TEXT_YES:
requestAutoAnswerText.put(key, true);
break;
}
}
}
private void setTriggerAutoOrder(PlayerAction playerAction, Game game, Object data) {
if (playerAction.equals(TRIGGER_AUTO_ORDER_RESET_ALL)) {
triggerAutoOrderAbilityFirst.clear();

View file

@ -228,7 +228,7 @@ public class GameController implements GameCallback {
try {
switch (event.getQueryType()) {
case ASK:
ask(event.getPlayerId(), event.getMessage());
ask(event.getPlayerId(), event.getMessage(), event.getOptions());
break;
case PICK_TARGET:
target(event.getPlayerId(), event.getMessage(), event.getCards(), event.getPerms(), event.getTargets(), event.isRequired(), event.getOptions());
@ -774,11 +774,11 @@ public class GameController implements GameCallback {
// TODO: inform watchers about game end and who won
}
private synchronized void ask(UUID playerId, final String question) throws MageException {
private synchronized void ask(UUID playerId, final String question, final Map<String, Serializable> options) throws MageException {
perform(playerId, new Command() {
@Override
public void execute(UUID playerId) {
getGameSession(playerId).ask(question);
getGameSession(playerId).ask(question, options);
}
});

View file

@ -78,11 +78,11 @@ public class GameSessionPlayer extends GameSessionWatcher {
super.CleanUp();
}
public void ask(final String question) {
public void ask(final String question, final Map<String, Serializable> options) {
if (!killed) {
User user = UserManager.getInstance().getUser(userId);
if (user != null) {
user.fireCallback(new ClientCallback("gameAsk", game.getId(), new GameClientMessage(getGameView(), question)));
user.fireCallback(new ClientCallback("gameAsk", game.getId(), new GameClientMessage(getGameView(), question, options)));
}
}
}

View file

@ -0,0 +1,54 @@
/*
* 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.arabiannights;
import java.util.UUID;
import mage.constants.Rarity;
/**
*
* @author jeffwadsworth
*/
public class SorceressQueen extends mage.sets.revisededition.SorceressQueen {
public SorceressQueen(UUID ownerId) {
super(ownerId);
this.cardNumber = 13;
this.expansionSetCode = "ARN";
this.rarity = Rarity.UNCOMMON;
}
public SorceressQueen(final SorceressQueen card) {
super(card);
}
@Override
public SorceressQueen copy() {
return new SorceressQueen(this);
}
}

View file

@ -0,0 +1,92 @@
/*
* 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.battleforzendikar;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition.CountType;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.DamagePlayersEffect;
import mage.abilities.keyword.DevoidAbility;
import mage.abilities.keyword.IngestAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.ColorlessPredicate;
import mage.filter.predicate.permanent.AnotherPredicate;
/**
*
* @author LevelX2
*/
public class DominatorDrone extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("another colorless creature");
static {
filter.add(new AnotherPredicate());
filter.add(new ColorlessPredicate());
}
public DominatorDrone(UUID ownerId) {
super(ownerId, 997, "Dominator Drone", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.expansionSetCode = "BFZ";
this.subtype.add("Eldrazi");
this.subtype.add("Drone");
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// Devoid
this.addAbility(new DevoidAbility(this.color));
// Ingest (Whenever this creature deals combat damage to a player, that player exiles the top card of his or her library.)
this.addAbility(new IngestAbility());
// When Dominator Drone enters the battlefield, if you control another colorless creature, each opponent loses 2 life.
TriggeredAbility triggeredAbility = new EntersBattlefieldTriggeredAbility(new DamagePlayersEffect(2, TargetController.OPPONENT));
this.addAbility(new ConditionalTriggeredAbility(
triggeredAbility,
new PermanentsOnTheBattlefieldCondition(filter, CountType.MORE_THAN, 0),
"When {this} enters the battlefield, if you control another colorless creature, each opponent loses 2 life."));
}
public DominatorDrone(final DominatorDrone card) {
super(card);
}
@Override
public DominatorDrone copy() {
return new DominatorDrone(this);
}
}

View file

@ -0,0 +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.
*/
package mage.sets.battleforzendikar;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public class ForerunnerOfSlaughter extends mage.sets.zendikarvseldrazi.ForerunnerOfSlaughter {
public ForerunnerOfSlaughter(UUID ownerId) {
super(ownerId);
this.cardNumber = 998;
this.expansionSetCode = "BFZ";
}
public ForerunnerOfSlaughter(final ForerunnerOfSlaughter card) {
super(card);
}
@Override
public ForerunnerOfSlaughter copy() {
return new ForerunnerOfSlaughter(this);
}
}

View file

@ -31,11 +31,15 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
@ -45,13 +49,14 @@ import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author fireshoes
*/
public class GuardianOfTazeem extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls");
static {
@ -67,7 +72,7 @@ public class GuardianOfTazeem extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// <i>Landfall</i> - Whenever a land enters the battlefield under you control, tap target creature an opponent controls. If that land is an Island, that creature doesn't untap during its controller's next untap step.
Ability ability = new GuardianOfTazeemTriggeredAbility();
ability.addTarget(new TargetCreaturePermanent(filter));
@ -87,7 +92,8 @@ public class GuardianOfTazeem extends CardImpl {
class GuardianOfTazeemTriggeredAbility extends TriggeredAbilityImpl {
public GuardianOfTazeemTriggeredAbility() {
super(Zone.BATTLEFIELD, null, false);
super(Zone.BATTLEFIELD, new TapTargetEffect(), false);
addEffect(new GuardianOfTazeemEffect());
}
public GuardianOfTazeemTriggeredAbility(final GuardianOfTazeemTriggeredAbility ability) {
@ -107,10 +113,13 @@ class GuardianOfTazeemTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && permanent.getCardType().contains(CardType.LAND) && permanent.getControllerId().equals(this.controllerId)) {
addEffect(new TapTargetEffect());
if (permanent.hasSubtype("Island")) {
addEffect(new DontUntapInControllersNextUntapStepTargetEffect("that creature"));
if (permanent != null
&& permanent.getCardType().contains(CardType.LAND)
&& permanent.getControllerId().equals(getControllerId())) {
for (Effect effect : getEffects()) {
if (effect instanceof GuardianOfTazeemEffect) {
effect.setTargetPointer(new FixedTarget(permanent, game));
}
}
return true;
}
@ -119,6 +128,37 @@ class GuardianOfTazeemTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
return "<i>Landfall</i> - Whenever a land enters the battlefield under your control, tap target creature an opponent controls. If that land is an Island, that creature doesn't untap during its controller's next untap step.";
return "<i>Landfall</i> - Whenever a land enters the battlefield under your control, " + super.getRule();
}
}
class GuardianOfTazeemEffect extends OneShotEffect {
public GuardianOfTazeemEffect() {
super(Outcome.Benefit);
this.staticText = "If that land is an Island, that creature doesn't untap during its controller's next untap step";
}
public GuardianOfTazeemEffect(final GuardianOfTazeemEffect effect) {
super(effect);
}
@Override
public GuardianOfTazeemEffect copy() {
return new GuardianOfTazeemEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent land = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source));
Permanent targetCreature = game.getPermanent(source.getFirstTarget());
if (land != null && targetCreature != null) {
if (land.hasSubtype("Island")) {
ContinuousEffect effect = new DontUntapInControllersNextUntapStepTargetEffect("that creature");
effect.setTargetPointer(new FixedTarget(targetCreature, game));
game.addEffect(effect, source);
}
}
return true;
}
}

View file

@ -0,0 +1,64 @@
/*
* 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.exodus;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksAloneTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class RecklessOgre extends CardImpl {
public RecklessOgre(UUID ownerId) {
super(ownerId, 98, "Reckless Ogre", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{R}");
this.expansionSetCode = "EXO";
this.subtype.add("Ogre");
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// Whenever Reckless Ogre attacks alone, it gets +3/+0 until end of turn.
this.addAbility(new AttacksAloneTriggeredAbility(new BoostSourceEffect(3, 0, Duration.EndOfTurn)));
}
public RecklessOgre(final RecklessOgre card) {
super(card);
}
@Override
public RecklessOgre copy() {
return new RecklessOgre(this);
}
}

View file

@ -0,0 +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.
*/
package mage.sets.fifthedition;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public class SorceressQueen extends mage.sets.revisededition.SorceressQueen {
public SorceressQueen(UUID ownerId) {
super(ownerId);
this.cardNumber = 56;
this.expansionSetCode = "5ED";
}
public SorceressQueen(final SorceressQueen card) {
super(card);
}
@Override
public SorceressQueen copy() {
return new SorceressQueen(this);
}
}

View file

@ -27,10 +27,11 @@
*/
package mage.sets.fifthedition;
import java.util.HashMap;
import java.util.Map;
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;
@ -49,7 +50,6 @@ public class WindsOfChange extends CardImpl {
super(ownerId, 275, "Winds of Change", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{R}");
this.expansionSetCode = "5ED";
// Each player shuffles the cards from his or her hand into his or her library, then draws that many cards.
this.getSpellAbility().addEffect(new WindsOfChangeEffect());
}
@ -84,19 +84,19 @@ class WindsOfChangeEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
for (UUID playerId : controller.getInRange()) {
Map<UUID, Integer> permanentsCount = new HashMap<>();
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
int cardsHand = player.getHand().size();
if (cardsHand > 0){
for (Card card: player.getHand().getCards(game)) {
player.removeFromHand(card, game);
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
}
game.informPlayers(player.getLogName() + " shuffles the cards from his or her hand into his or her library");
player.shuffleLibrary(game);
player.drawCards(cardsHand, game);
}
permanentsCount.put(playerId, player.getHand().size());
player.moveCards(player.getHand(), Zone.HAND, Zone.LIBRARY, source, game);
player.shuffleLibrary(game);
}
}
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null && permanentsCount.containsKey(playerId)) {
player.drawCards(permanentsCount.get(playerId), game);
}
}
return true;

View file

@ -0,0 +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.
*/
package mage.sets.fourthedition;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public class Conversion extends mage.sets.limitedalpha.Conversion {
public Conversion(UUID ownerId) {
super(ownerId);
this.cardNumber = 269;
this.expansionSetCode = "4ED";
}
public Conversion(final Conversion card) {
super(card);
}
@Override
public Conversion copy() {
return new Conversion(this);
}
}

View file

@ -0,0 +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.
*/
package mage.sets.fourthedition;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public class CosmicHorror extends mage.sets.legends.CosmicHorror {
public CosmicHorror(UUID ownerId) {
super(ownerId);
this.cardNumber = 10;
this.expansionSetCode = "4ED";
}
public CosmicHorror(final CosmicHorror card) {
super(card);
}
@Override
public CosmicHorror copy() {
return new CosmicHorror(this);
}
}

View file

@ -0,0 +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.
*/
package mage.sets.fourthedition;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public class SorceressQueen extends mage.sets.revisededition.SorceressQueen {
public SorceressQueen(UUID ownerId) {
super(ownerId);
this.cardNumber = 46;
this.expansionSetCode = "4ED";
}
public SorceressQueen(final SorceressQueen card) {
super(card);
}
@Override
public SorceressQueen copy() {
return new SorceressQueen(this);
}
}

View file

@ -28,6 +28,12 @@
package mage.sets.futuresight;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.mana.RedManaAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Layer;
@ -35,12 +41,6 @@ import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.SubLayer;
import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.mana.RedManaAbility;
import mage.cards.CardImpl;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SupertypePredicate;
@ -53,6 +53,12 @@ import mage.game.permanent.Permanent;
*/
public class MagusOfTheMoon extends CardImpl {
private static final FilterLandPermanent filter = new FilterLandPermanent();
static {
filter.add(Predicates.not(new SupertypePredicate("Basic")));
}
public MagusOfTheMoon(UUID ownerId) {
super(ownerId, 101, "Magus of the Moon", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{R}");
this.expansionSetCode = "FUT";
@ -74,53 +80,49 @@ public class MagusOfTheMoon extends CardImpl {
public MagusOfTheMoon copy() {
return new MagusOfTheMoon(this);
}
}
class MagusOfTheMoonEffect extends ContinuousEffectImpl {
class MagusOfTheMoonEffect extends ContinuousEffectImpl {
private static final FilterLandPermanent filter = new FilterLandPermanent();
static {
filter.add(Predicates.not(new SupertypePredicate("Basic")));
}
MagusOfTheMoonEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
this.staticText = "Nonbasic lands are Mountains";
}
MagusOfTheMoonEffect(final MagusOfTheMoonEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public MagusOfTheMoonEffect copy() {
return new MagusOfTheMoonEffect(this);
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
for (Permanent land: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
switch (layer) {
case AbilityAddingRemovingEffects_6:
land.removeAllAbilities(source.getSourceId(), game);
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
break;
case TypeChangingEffects_4:
land.getSubtype().clear();
land.getSubtype().add("Mountain");
break;
}
MagusOfTheMoonEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
this.staticText = "Nonbasic lands are Mountains";
}
MagusOfTheMoonEffect(final MagusOfTheMoonEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public MagusOfTheMoonEffect copy() {
return new MagusOfTheMoonEffect(this);
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
for (Permanent land : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
switch (layer) {
case AbilityAddingRemovingEffects_6:
land.removeAllAbilities(source.getSourceId(), game);
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
break;
case TypeChangingEffects_4:
land.getSubtype().clear();
land.getSubtype().add("Mountain");
break;
}
}
return true;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4;
}
return true;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4;
}
}

View file

@ -72,59 +72,59 @@ public class YixlidJailer extends CardImpl {
public YixlidJailer copy() {
return new YixlidJailer(this);
}
}
class YixlidJailerEffect extends ContinuousEffectImpl {
class YixlidJailerEffect extends ContinuousEffectImpl {
YixlidJailerEffect() {
super(Duration.WhileOnBattlefield, Outcome.LoseAbility);
staticText = "Cards in graveyards lose all abilities.";
}
YixlidJailerEffect() {
super(Duration.WhileOnBattlefield, Outcome.LoseAbility);
staticText = "Cards in graveyards lose all abilities.";
}
YixlidJailerEffect(final YixlidJailerEffect effect) {
super(effect);
}
YixlidJailerEffect(final YixlidJailerEffect effect) {
super(effect);
}
@Override
public YixlidJailerEffect copy() {
return new YixlidJailerEffect(this);
}
@Override
public YixlidJailerEffect copy() {
return new YixlidJailerEffect(this);
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
if (layer == Layer.AbilityAddingRemovingEffects_6) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
for (UUID playerId : controller.getInRange()) {
Player player = game.getPlayer(playerId);
if (player != null) {
for (Card card : player.getGraveyard().getCards(game)) {
if (card != null) {
card.getAbilities(game).clear(); // Will the abilities ever come back????
// TODO: Fix that (LevelX2)
// game.getContinuousEffects().removeGainedEffectsForSource(card.getId());
// game.getState().resetTriggersForSourceId(card.getId());
Abilities abilities = game.getState().getAllOtherAbilities(card.getId());
if (abilities != null) {
abilities.clear();
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
if (layer == Layer.AbilityAddingRemovingEffects_6) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
for (UUID playerId : controller.getInRange()) {
Player player = game.getPlayer(playerId);
if (player != null) {
for (Card card : player.getGraveyard().getCards(game)) {
if (card != null) {
card.getAbilities(game).clear(); // Will the abilities ever come back????
// TODO: Fix that (LevelX2)
// game.getContinuousEffects().removeGainedEffectsForSource(card.getId());
// game.getState().resetTriggersForSourceId(card.getId());
Abilities abilities = game.getState().getAllOtherAbilities(card.getId());
if (abilities != null) {
abilities.clear();
}
}
}
}
}
return true;
}
return true;
}
return false;
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6;
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6;
}
}
}

View file

@ -0,0 +1,168 @@
/*
* 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.iceage;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.SourceOnBattlefieldControlUnchangedCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author jeffwadsworth
*/
public class MeriekeRiBerit extends CardImpl {
public MeriekeRiBerit(UUID ownerId) {
super(ownerId, 375, "Merieke Ri Berit", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{W}{U}{B}");
this.expansionSetCode = "ICE";
this.supertype.add("Legendary");
this.subtype.add("Human");
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Merieke Ri Berit doesn't untap during your untap step.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepSourceEffect()));
// {tap}: Gain control of target creature for as long as you control Merieke Ri Berit. When Merieke Ri Berit leaves the battlefield or becomes untapped, destroy that creature. It can't be regenerated.
ConditionalContinuousEffect MeriekeRiBeritGainControlEffect = new ConditionalContinuousEffect(
new GainControlTargetEffect(Duration.Custom),
new SourceOnBattlefieldControlUnchangedCondition(),
"Gain control of target creature for as long as you control {this}");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, MeriekeRiBeritGainControlEffect, new TapSourceCost());
ability.addTarget(new TargetPermanent(new FilterCreaturePermanent("target creature")));
ability.addEffect(new MeriekeRiBeritCreateDelayedTriggerEffect());
this.addAbility(ability);
}
public MeriekeRiBerit(final MeriekeRiBerit card) {
super(card);
}
@Override
public MeriekeRiBerit copy() {
return new MeriekeRiBerit(this);
}
}
class MeriekeRiBeritCreateDelayedTriggerEffect extends OneShotEffect {
public MeriekeRiBeritCreateDelayedTriggerEffect() {
super(Outcome.Detriment);
this.staticText = "When {this} leaves the battlefield or becomes untapped, destroy that creature. It can't be regenerated.";
}
public MeriekeRiBeritCreateDelayedTriggerEffect(final MeriekeRiBeritCreateDelayedTriggerEffect effect) {
super(effect);
}
@Override
public MeriekeRiBeritCreateDelayedTriggerEffect copy() {
return new MeriekeRiBeritCreateDelayedTriggerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent controlledCreature = game.getPermanent(source.getFirstTarget());
if (controlledCreature != null) {
DelayedTriggeredAbility delayedAbility = new MeriekeRiBeritDelayedTriggeredAbility();
delayedAbility.getEffects().get(0).setTargetPointer(new FixedTarget(controlledCreature.getId()));
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
delayedAbility.init(game);
game.addDelayedTriggeredAbility(delayedAbility);
return true;
}
return false;
}
}
class MeriekeRiBeritDelayedTriggeredAbility extends DelayedTriggeredAbility {
MeriekeRiBeritDelayedTriggeredAbility() {
super(new DestroyTargetEffect(true), Duration.EndOfGame, true);
}
MeriekeRiBeritDelayedTriggeredAbility(MeriekeRiBeritDelayedTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.ZONE_CHANGE
|| event.getType() == EventType.UNTAPPED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getSourceId() != null) {
if (GameEvent.EventType.ZONE_CHANGE.equals(event.getType())
&& event.getTargetId().equals(getSourceId())) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
return zEvent.getFromZone().equals(Zone.BATTLEFIELD);
}
}
return GameEvent.EventType.UNTAPPED.equals(event.getType())
&& event.getTargetId() != null && event.getTargetId().equals(getSourceId());
}
@Override
public MeriekeRiBeritDelayedTriggeredAbility copy() {
return new MeriekeRiBeritDelayedTriggeredAbility(this);
}
@Override
public String getRule() {
return "When {this} leaves the battlefield or becomes untapped, destroy that creature. It can't be regenerated.";
}
}

View file

@ -0,0 +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.
*/
package mage.sets.invasion;
import java.util.UUID;
/**
*
* @author LoneFox
*/
public class RogueKavu extends mage.sets.ninthedition.RogueKavu {
public RogueKavu(UUID ownerId) {
super(ownerId);
this.cardNumber = 160;
this.expansionSetCode = "INV";
}
public RogueKavu(final RogueKavu card) {
super(card);
}
@Override
public RogueKavu copy() {
return new RogueKavu(this);
}
}

View file

@ -0,0 +1,119 @@
/*
* 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.legends;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
*
* @author jeffwadsworth
*/
public class CosmicHorror extends CardImpl {
public CosmicHorror(UUID ownerId) {
super(ownerId, 6, "Cosmic Horror", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{B}{B}{B}");
this.expansionSetCode = "LEG";
this.subtype.add("Horror");
this.power = new MageInt(7);
this.toughness = new MageInt(7);
// First strike
this.addAbility(FirstStrikeAbility.getInstance());
// At the beginning of your upkeep, destroy Cosmic Horror unless you pay {3}{B}{B}{B}. If Cosmic Horror is destroyed this way, it deals 7 damage to you.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CosmicHorrorEffect(new ManaCostsImpl("{3}{B}{B}{B}")), TargetController.YOU, false));
}
public CosmicHorror(final CosmicHorror card) {
super(card);
}
@Override
public CosmicHorror copy() {
return new CosmicHorror(this);
}
}
class CosmicHorrorEffect extends OneShotEffect {
protected Cost cost;
public CosmicHorrorEffect(Cost cost) {
super(Outcome.DestroyPermanent);
this.cost = cost;
staticText = "destroy {this} unless you pay {3}{B}{B}{B}. If {this} is destroyed this way it deals 7 damage to you";
}
public CosmicHorrorEffect(final CosmicHorrorEffect effect) {
super(effect);
this.cost = effect.cost.copy();
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent cosmicHorror = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (controller != null && cosmicHorror != null) {
StringBuilder sb = new StringBuilder(cost.getText()).append("?");
if (!sb.toString().toLowerCase().startsWith("exile ") && !sb.toString().toLowerCase().startsWith("return ")) {
sb.insert(0, "Pay ");
}
if (controller.chooseUse(Outcome.Benefit, sb.toString(), source, game)) {
cost.clearPaid();
if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) {
return true;
}
}
if (cosmicHorror.destroy(source.getSourceId(), game, false)) {
controller.damage(7, source.getSourceId(), game, false, true);
return true;
}
}
return false;
}
@Override
public CosmicHorrorEffect copy() {
return new CosmicHorrorEffect(this);
}
}

View file

@ -0,0 +1,148 @@
/*
* 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.limitedalpha;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.mana.WhiteManaAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Layer;
import static mage.constants.Layer.AbilityAddingRemovingEffects_6;
import static mage.constants.Layer.TypeChangingEffects_4;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.SubLayer;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterLandPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.sets.futuresight.MagusOfTheMoon;
/**
*
* @author LevelX2
*/
public class Conversion extends CardImpl {
private static final FilterLandPermanent filter = new FilterLandPermanent("Mountain", "Mountains");
public Conversion(UUID ownerId) {
super(ownerId, 199, "Conversion", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
this.expansionSetCode = "LEA";
// At the beginning of your upkeep, sacrifice Conversion unless you pay {W}{W}.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl("{W}{W}")), TargetController.YOU, false));
// All Mountains are Plains.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConversionEffect()));
}
public Conversion(final Conversion card) {
super(card);
}
@Override
public Conversion copy() {
return new Conversion(this);
}
class ConversionEffect extends ContinuousEffectImpl {
ConversionEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
this.staticText = "All Mountains are Plains";
}
ConversionEffect(final ConversionEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public ConversionEffect copy() {
return new ConversionEffect(this);
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
for (Permanent land : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
switch (layer) {
case AbilityAddingRemovingEffects_6:
land.removeAllAbilities(source.getSourceId(), game);
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
break;
case TypeChangingEffects_4:
land.getSubtype().clear();
land.getSubtype().add("Plains");
break;
}
}
return true;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4;
}
@Override
public Set<UUID> isDependentTo(List<ContinuousEffect> allEffectsInLayer) {
// the dependent classes needs to be an enclosed class for dependent check of continuous effects
Set<UUID> dependentTo = null;
for (ContinuousEffect effect : allEffectsInLayer) {
// http://www.mtgsalvation.com/forums/magic-fundamentals/magic-rulings/magic-rulings-archives/286046-conversion-magus-of-the-moon
if (MagusOfTheMoon.class.equals(effect.getClass().getEnclosingClass())) {
if (dependentTo == null) {
dependentTo = new HashSet<>();
}
dependentTo.add(effect.getId());
}
}
return dependentTo;
}
}
}

View file

@ -0,0 +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.
*/
package mage.sets.limitedalpha;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public class VesuvanDoppelganger extends mage.sets.unlimitededition.VesuvanDoppelganger {
public VesuvanDoppelganger(UUID ownerId) {
super(ownerId);
this.cardNumber = 88;
this.expansionSetCode = "LEA";
}
public VesuvanDoppelganger(final VesuvanDoppelganger card) {
super(card);
}
@Override
public VesuvanDoppelganger copy() {
return new VesuvanDoppelganger(this);
}
}

View file

@ -0,0 +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.
*/
package mage.sets.limitedbeta;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public class Conversion extends mage.sets.limitedalpha.Conversion {
public Conversion(UUID ownerId) {
super(ownerId);
this.cardNumber = 201;
this.expansionSetCode = "LEB";
}
public Conversion(final Conversion card) {
super(card);
}
@Override
public Conversion copy() {
return new Conversion(this);
}
}

View file

@ -0,0 +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.
*/
package mage.sets.limitedbeta;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public class VesuvanDoppelganger extends mage.sets.unlimitededition.VesuvanDoppelganger {
public VesuvanDoppelganger(UUID ownerId) {
super(ownerId);
this.cardNumber = 88;
this.expansionSetCode = "LEB";
}
public VesuvanDoppelganger(final VesuvanDoppelganger card) {
super(card);
}
@Override
public VesuvanDoppelganger copy() {
return new VesuvanDoppelganger(this);
}
}

View file

@ -27,25 +27,25 @@
*/
package mage.sets.magic2010;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.LinkedHashSet;
import java.util.Map;
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.MageObject;
import mage.abilities.Ability;
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.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.players.PlayerList;
/**
*
@ -57,7 +57,6 @@ public class WarpWorld extends CardImpl {
super(ownerId, 163, "Warp World", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{5}{R}{R}{R}");
this.expansionSetCode = "M10";
// Each player shuffles all permanents he or she owns into his or her library, then reveals that many cards from the top of his or her library. Each player puts all artifact, creature, and land cards revealed this way onto the battlefield, then does the same for enchantment cards, then puts all cards revealed this way that weren't put onto the battlefield on the bottom of his or her library.
this.getSpellAbility().addEffect(new WarpWorldEffect());
}
@ -90,105 +89,99 @@ class WarpWorldEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Map<UUID, List<Permanent>> permanentsOwned = new HashMap<>();
MageObject sourceObject = source.getSourceObject(game);
if (sourceObject == null) {
return false;
}
Map<UUID, Set<Card>> permanentsOwned = new HashMap<>();
Collection<Permanent> permanents = game.getBattlefield().getAllPermanents();
for (Permanent permanent : permanents) {
List<Permanent> list = permanentsOwned.get(permanent.getOwnerId());
if (list == null) {
list = new ArrayList<>();
Set<Card> set = permanentsOwned.get(permanent.getOwnerId());
if (set == null) {
set = new LinkedHashSet<>();
}
list.add(permanent);
permanentsOwned.put(permanent.getOwnerId(), list);
set.add(permanent);
permanentsOwned.put(permanent.getOwnerId(), set);
}
// shuffle permanents into owner's library
Map<UUID, Integer> permanentsCount = new HashMap<>();
PlayerList playerList = game.getPlayerList();
playerList.setCurrent(game.getActivePlayerId());
Player player = game.getPlayer(game.getActivePlayerId());
do {
List<Permanent> list = permanentsOwned.remove(player.getId());
Integer count = 0;
if (list != null) {
count = list.size();
for (Permanent permanent : list) {
permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
Set<Card> set = permanentsOwned.remove(playerId);
Integer count = 0;
if (set != null) {
count = set.size();
player.moveCards(set, Zone.BATTLEFIELD, Zone.LIBRARY, source, game);
}
if (count > 0) {
player.shuffleLibrary(game);
}
permanentsCount.put(playerId, count);
}
}
if (count > 0) {
player.shuffleLibrary(game);
}
permanentsCount.put(player.getId(), count);
player = playerList.getNext(game);
} while (!player.getId().equals(game.getActivePlayerId()));
game.applyEffects(); // so effects from creatures that were on the battlefield won't trigger from draw or later put into play
Map<UUID, CardsImpl> cardsRevealed = new HashMap<>();
// draw cards and reveal them
playerList.setCurrent(game.getActivePlayerId());
player = game.getPlayer(game.getActivePlayerId());
do {
Integer count = Math.min(permanentsCount.get(player.getId()), player.getLibrary().size());
CardsImpl cards = new CardsImpl();
for (int i = 0; i < count; i++) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
Integer count = Math.min(permanentsCount.get(player.getId()), player.getLibrary().size());
CardsImpl cards = new CardsImpl();
for (int i = 0; i < count; i++) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
}
}
player.revealCards(sourceObject.getIdName() + " (" + player.getName() + ")", cards, game);
cardsRevealed.put(player.getId(), cards);
}
player.revealCards("Warp World " + player.getName(), cards, game);
cardsRevealed.put(player.getId(), cards);
player = playerList.getNext(game);
} while (!player.getId().equals(game.getActivePlayerId()));
}
// put artifacts, creaturs and lands onto the battlefield
playerList.setCurrent(game.getActivePlayerId());
player = game.getPlayer(game.getActivePlayerId());
do {
CardsImpl cards = cardsRevealed.get(player.getId());
for (Card card : cards.getCards(game)) {
if (card != null && (card.getCardType().contains(CardType.ARTIFACT)
|| card.getCardType().contains(CardType.CREATURE)
|| card.getCardType().contains(CardType.LAND))) {
card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), player.getId());
cards.remove(card);
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
CardsImpl cards = cardsRevealed.get(player.getId());
for (Card card : cards.getCards(game)) {
if (card != null && (card.getCardType().contains(CardType.ARTIFACT)
|| card.getCardType().contains(CardType.CREATURE)
|| card.getCardType().contains(CardType.LAND))) {
card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), player.getId());
cards.remove(card);
}
}
}
player = playerList.getNext(game);
} while (!player.getId().equals(game.getActivePlayerId()));
}
// put enchantments onto the battlefield
playerList.setCurrent(game.getActivePlayerId());
player = game.getPlayer(game.getActivePlayerId());
do {
CardsImpl cards = cardsRevealed.get(player.getId());
for (Card card : cards.getCards(game)) {
if (card != null && card.getCardType().contains(CardType.ENCHANTMENT)) {
card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), player.getId());
cards.remove(card);
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
CardsImpl cards = cardsRevealed.get(player.getId());
for (Card card : cards.getCards(game)) {
if (card != null && card.getCardType().contains(CardType.ENCHANTMENT)) {
card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), player.getId());
cards.remove(card);
}
}
}
player = playerList.getNext(game);
} while (!player.getId().equals(game.getActivePlayerId()));
}
// put the rest of the cards on buttom of the library
playerList.setCurrent(game.getActivePlayerId());
player = game.getPlayer(game.getActivePlayerId());
do {
CardsImpl cards = cardsRevealed.get(player.getId());
player.putCardsOnBottomOfLibrary(cards, game, source, false);
player = playerList.getNext(game);
} while (!player.getId().equals(game.getActivePlayerId()));
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
CardsImpl cards = cardsRevealed.get(player.getId());
player.putCardsOnBottomOfLibrary(cards, game, source, false);
}
}
return true;
}
}

View file

@ -29,7 +29,7 @@ package mage.sets.magic2013;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.AttacksAloneTriggeredAbility;
import mage.abilities.effects.common.SacrificeEffect;
import mage.abilities.keyword.ExaltedAbility;
import mage.abilities.keyword.FlyingAbility;
@ -37,12 +37,7 @@ import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.target.targetpointer.FixedTarget;
import mage.filter.common.FilterControlledCreaturePermanent;
/**
*
@ -64,7 +59,8 @@ public class NefaroxOverlordOfGrixis extends CardImpl {
// Exalted
this.addAbility(new ExaltedAbility());
// Whenever Nefarox, Overlord of Grixis attacks alone, defending player sacrifices a creature.
this.addAbility(new NefaroxOverlordOfGrixisTriggeredAbility());
this.addAbility(new AttacksAloneTriggeredAbility(new SacrificeEffect(
new FilterControlledCreaturePermanent("a creature"), 1, "defending player")));
}
public NefaroxOverlordOfGrixis(final NefaroxOverlordOfGrixis card) {
@ -76,52 +72,3 @@ public class NefaroxOverlordOfGrixis extends CardImpl {
return new NefaroxOverlordOfGrixis(this);
}
}
class NefaroxOverlordOfGrixisTriggeredAbility extends TriggeredAbilityImpl {
private static final FilterControlledPermanent filter;
static {
filter = new FilterControlledPermanent(" a creature");
filter.add(new CardTypePredicate(CardType.CREATURE));
}
public NefaroxOverlordOfGrixisTriggeredAbility() {
super(Zone.BATTLEFIELD, new SacrificeEffect(filter, 1, "defending player"));
}
public NefaroxOverlordOfGrixisTriggeredAbility(final NefaroxOverlordOfGrixisTriggeredAbility ability) {
super(ability);
}
@Override
public NefaroxOverlordOfGrixisTriggeredAbility copy() {
return new NefaroxOverlordOfGrixisTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.DECLARED_ATTACKERS;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.getActivePlayerId().equals(this.controllerId) ) {
UUID nefarox = this.getSourceId();
if (nefarox != null) {
if (game.getCombat().attacksAlone() && nefarox == game.getCombat().getAttackers().get(0)) {
UUID defender = game.getCombat().getDefenderId(nefarox);
this.getEffects().get(0).setTargetPointer(new FixedTarget(defender));
return true;
}
}
}
return false;
}
@Override
public String getRule() {
return "Whenever {this} attacks alone, defending player sacrifices a creature.";
}
}

View file

@ -48,7 +48,7 @@ import mage.game.permanent.token.ElfToken;
* @author fireshoes
*/
public class DwynensElite extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("another Elf");
static {
@ -69,7 +69,7 @@ public class DwynensElite extends CardImpl {
this.addAbility(new ConditionalTriggeredAbility(
triggeredAbility,
new PermanentsOnTheBattlefieldCondition(filter, CountType.MORE_THAN, 0),
"When {this} enters the battlefield, if you control another Elf, put a 1/1 green Elf Warrior creature token onto the battlefield"));
"When {this} enters the battlefield, if you control another Elf, put a 1/1 green Elf Warrior creature token onto the battlefield."));
}
public DwynensElite(final DwynensElite card) {

View file

@ -57,7 +57,6 @@ import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.filter.predicate.mageobject.SupertypePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
import mage.game.command.Emblem;
import mage.target.common.TargetCardInYourGraveyard;
@ -84,7 +83,6 @@ public class LilianaDefiantNecromancer extends CardImpl {
this.color.setBlack(true);
this.nightCard = true;
// this.canTransform = true;
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false));
@ -97,7 +95,7 @@ public class LilianaDefiantNecromancer extends CardImpl {
ability.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(ability);
//-8: You get an emblem with "Whenever a creature you control dies, return it to the battlefield under your control at the beginning of the next end step.";
//-8: You get an emblem with "Whenever a creature dies, return it to the battlefield under your control at the beginning of the next end step.";
this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new LilianaDefiantNecromancerEmblem()), -8));
}
@ -130,11 +128,7 @@ public class LilianaDefiantNecromancer extends CardImpl {
class LilianaDefiantNecromancerEmblem extends Emblem {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature you control");
static {
filter.add(new ControllerPredicate(TargetController.YOU));
}
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature");
// You get an emblem with "Whenever a creature you control dies, return it to the battlefield under your control at the beginning of the next end step."
public LilianaDefiantNecromancerEmblem() {

View file

@ -45,13 +45,13 @@ import mage.filter.predicate.mageobject.AbilityPredicate;
* @author LevelX2
*/
public class SeismicElemental extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures without flying");
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures without flying");
static {
filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
}
public SeismicElemental(UUID ownerId) {
super(ownerId, 161, "Seismic Elemental", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{R}{R}");
this.expansionSetCode = "ORI";

View file

@ -117,10 +117,12 @@ class TheGreatAuroraEffect extends OneShotEffect {
for (Permanent permanent : list) {
player.moveCardToLibraryWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD, true, true);
}
player.getLibrary().shuffle();
player.shuffleLibrary(game);
}
}
game.applyEffects(); // so effects from creatures that were on the battlefield won't trigger from draw or put into play
// Draw cards
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);

View file

@ -0,0 +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.
*/
package mage.sets.mastersedition;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public class VesuvanDoppelganger extends mage.sets.unlimitededition.VesuvanDoppelganger {
public VesuvanDoppelganger(UUID ownerId) {
super(ownerId);
this.cardNumber = 54;
this.expansionSetCode = "MED";
}
public VesuvanDoppelganger(final VesuvanDoppelganger card) {
super(card);
}
@Override
public VesuvanDoppelganger copy() {
return new VesuvanDoppelganger(this);
}
}

View file

@ -0,0 +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.
*/
package mage.sets.masterseditionii;
import java.util.UUID;
/**
*
* @author LoneFox
*/
public class AngelOfFury extends mage.sets.portalsecondage.AngelOfFury {
public AngelOfFury(UUID ownerId) {
super(ownerId);
this.cardNumber = 2;
this.expansionSetCode = "ME2";
}
public AngelOfFury(final AngelOfFury card) {
super(card);
}
@Override
public AngelOfFury copy() {
return new AngelOfFury(this);
}
}

View file

@ -0,0 +1,62 @@
/*
* 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.masterseditionii;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DamageAsThoughNotBlockedAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class WolfPack extends CardImpl {
public WolfPack(UUID ownerId) {
super(ownerId, 187, "Wolf Pack", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{6}{G}{G}");
this.expansionSetCode = "ME2";
this.subtype.add("Wolf");
this.power = new MageInt(7);
this.toughness = new MageInt(6);
// You may have Wolf Pack assign its combat damage as though it weren't blocked.
this.addAbility(DamageAsThoughNotBlockedAbility.getInstance());
}
public WolfPack(final WolfPack card) {
super(card);
}
@Override
public WolfPack copy() {
return new WolfPack(this);
}
}

View file

@ -0,0 +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.
*/
package mage.sets.masterseditioniii;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public class CosmicHorror extends mage.sets.legends.CosmicHorror {
public CosmicHorror(UUID ownerId) {
super(ownerId);
this.cardNumber = 61;
this.expansionSetCode = "ME3";
}
public CosmicHorror(final CosmicHorror card) {
super(card);
}
@Override
public CosmicHorror copy() {
return new CosmicHorror(this);
}
}

View file

@ -0,0 +1,60 @@
/*
* 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.masterseditioniii;
import java.util.UUID;
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LoneFox
*/
public class ForcedRetreat extends CardImpl {
public ForcedRetreat(UUID ownerId) {
super(ownerId, 37, "Forced Retreat", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{2}{U}");
this.expansionSetCode = "ME3";
// Put target creature on top of its owner's library.
this.getSpellAbility().addEffect(new PutOnLibraryTargetEffect(true));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
public ForcedRetreat(final ForcedRetreat card) {
super(card);
}
@Override
public ForcedRetreat copy() {
return new ForcedRetreat(this);
}
}

View file

@ -0,0 +1,69 @@
/*
* 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.masterseditioniii;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.effects.common.ShuffleIntoLibrarySourceEffect;
import mage.abilities.keyword.HorsemanshipAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class GuanYuSaintedWarrior extends CardImpl {
public GuanYuSaintedWarrior(UUID ownerId) {
super(ownerId, 12, "Guan Yu, Sainted Warrior", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{W}{W}");
this.expansionSetCode = "ME3";
this.supertype.add("Legendary");
this.subtype.add("Human");
this.subtype.add("Soldier");
this.subtype.add("Warrior");
this.power = new MageInt(3);
this.toughness = new MageInt(5);
// Horsemanship
this.addAbility(HorsemanshipAbility.getInstance());
// When Guan Yu, Sainted Warrior is put into your graveyard from the battlefield, you may shuffle Guan Yu into your library.
this.addAbility(new DiesTriggeredAbility(new ShuffleIntoLibrarySourceEffect(), true));
}
public GuanYuSaintedWarrior(final GuanYuSaintedWarrior card) {
super(card);
}
@Override
public GuanYuSaintedWarrior copy() {
return new GuanYuSaintedWarrior(this);
}
}

View file

@ -0,0 +1,54 @@
/*
* 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.masterseditioniii;
import java.util.UUID;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class SlashingTiger extends mage.sets.portalthreekingdoms.SlashingTiger {
public SlashingTiger(UUID ownerId) {
super(ownerId);
this.cardNumber = 133;
this.expansionSetCode = "ME3";
this.rarity = Rarity.COMMON;
}
public SlashingTiger(final SlashingTiger card) {
super(card);
}
@Override
public SlashingTiger copy() {
return new SlashingTiger(this);
}
}

View file

@ -0,0 +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.
*/
package mage.sets.masterseditioniii;
import java.util.UUID;
/**
*
* @author LoneFox
*/
public class WeiNightRaiders extends mage.sets.portalthreekingdoms.WeiNightRaiders {
public WeiNightRaiders(UUID ownerId) {
super(ownerId);
this.cardNumber = 81;
this.expansionSetCode = "ME3";
}
public WeiNightRaiders(final WeiNightRaiders card) {
super(card);
}
@Override
public WeiNightRaiders copy() {
return new WeiNightRaiders(this);
}
}

View file

@ -0,0 +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.
*/
package mage.sets.masterseditioniii;
import java.util.UUID;
/**
*
* @author LoneFox
*/
public class ZodiacDragon extends mage.sets.portalthreekingdoms.ZodiacDragon {
public ZodiacDragon(UUID ownerId) {
super(ownerId);
this.cardNumber = 112;
this.expansionSetCode = "ME3";
}
public ZodiacDragon(final ZodiacDragon card) {
super(card);
}
@Override
public ZodiacDragon copy() {
return new ZodiacDragon(this);
}
}

View file

@ -0,0 +1,54 @@
/*
* 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.masterseditioniv;
import java.util.UUID;
import mage.constants.Rarity;
/**
*
* @author LevelX2
*/
public class Conversion extends mage.sets.limitedalpha.Conversion {
public Conversion(UUID ownerId) {
super(ownerId);
this.cardNumber = 9;
this.expansionSetCode = "ME4";
this.rarity = Rarity.RARE;
}
public Conversion(final Conversion card) {
super(card);
}
@Override
public Conversion copy() {
return new Conversion(this);
}
}

View file

@ -0,0 +1,75 @@
/*
* 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.morningtide;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksAloneTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class LunkErrant extends CardImpl {
public LunkErrant(UUID ownerId) {
super(ownerId, 94, "Lunk Errant", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{5}{R}");
this.expansionSetCode = "MOR";
this.subtype.add("Giant");
this.subtype.add("Warrior");
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Whenever Lunk Errant attacks alone, it gets +1/+1 and gains trample until end of turn.
Effect effect = new BoostSourceEffect(1, 1, Duration.EndOfTurn);
effect.setText("it gets +1/+1");
Ability ability = new AttacksAloneTriggeredAbility(effect);
effect = new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn);
effect.setText("and gains trample until end of turn");
ability.addEffect(effect);
this.addAbility(ability);
}
public LunkErrant(final LunkErrant card) {
super(card);
}
@Override
public LunkErrant copy() {
return new LunkErrant(this);
}
}

View file

@ -0,0 +1,64 @@
/*
* 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.ninthedition;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksAloneTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class RogueKavu extends CardImpl {
public RogueKavu(UUID ownerId) {
super(ownerId, 213, "Rogue Kavu", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.expansionSetCode = "9ED";
this.subtype.add("Kavu");
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Whenever Rogue Kavu attacks alone, it gets +2/+0 until end of turn.
this.addAbility(new AttacksAloneTriggeredAbility(new BoostSourceEffect(2, 0, Duration.EndOfTurn)));
}
public RogueKavu(final RogueKavu card) {
super(card);
}
@Override
public RogueKavu copy() {
return new RogueKavu(this);
}
}

View file

@ -50,7 +50,6 @@ public class Oblation extends CardImpl {
super(ownerId, 46, "Oblation", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{2}{W}");
this.expansionSetCode = "ONS";
// The owner of target nonland permanent shuffles it into his or her library, then draws two cards.
this.getSpellAbility().addEffect(new OblationEffect());
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
@ -67,21 +66,21 @@ public class Oblation extends CardImpl {
}
class OblationEffect extends OneShotEffect {
OblationEffect() {
super(Outcome.Removal);
this.staticText = "The owner of target nonland permanent shuffles it into his or her library, then draws two cards";
}
OblationEffect(final OblationEffect effect) {
super(effect);
}
@Override
public OblationEffect copy() {
return new OblationEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
@ -90,6 +89,9 @@ class OblationEffect extends OneShotEffect {
if (player != null) {
player.moveCardToLibraryWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD, true, true);
player.shuffleLibrary(game);
game.applyEffects(); // so effects from creatures that were on the battlefield won't trigger from draw
player.drawCards(2, game);
return true;
}

View file

@ -0,0 +1,66 @@
/*
* 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.portalsecondage;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.effects.common.ShuffleIntoLibrarySourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class AngelOfFury extends CardImpl {
public AngelOfFury(UUID ownerId) {
super(ownerId, 127, "Angel of Fury", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{W}{W}");
this.expansionSetCode = "PO2";
this.subtype.add("Angel");
this.power = new MageInt(3);
this.toughness = new MageInt(5);
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Angel of Fury is put into your graveyard from the battlefield, you may shuffle it into your library.
this.addAbility(new DiesTriggeredAbility(new ShuffleIntoLibrarySourceEffect(), true));
}
public AngelOfFury(final AngelOfFury card) {
super(card);
}
@Override
public AngelOfFury copy() {
return new AngelOfFury(this);
}
}

View file

@ -0,0 +1,60 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.target.common.TargetCardInYourGraveyard;
/**
*
* @author LoneFox
*/
public class FalseMourning extends CardImpl {
public FalseMourning(UUID ownerId) {
super(ownerId, 134, "False Mourning", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{G}");
this.expansionSetCode = "PTK";
// Put target card from your graveyard on top of your library.
this.getSpellAbility().addEffect(new PutOnLibraryTargetEffect(true));
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard());
}
public FalseMourning(final FalseMourning card) {
super(card);
}
@Override
public FalseMourning copy() {
return new FalseMourning(this);
}
}

View file

@ -0,0 +1,68 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.TapTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LoneFox
*/
public class FlankingTroops extends CardImpl {
public FlankingTroops(UUID ownerId) {
super(ownerId, 5, "Flanking Troops", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{W}{W}");
this.expansionSetCode = "PTK";
this.subtype.add("Human");
this.subtype.add("Soldier");
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever Flanking Troops attacks, you may tap target creature.
Ability ability = new AttacksTriggeredAbility(new TapTargetEffect(), true);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public FlankingTroops(final FlankingTroops card) {
super(card);
}
@Override
public FlankingTroops copy() {
return new FlankingTroops(this);
}
}

View file

@ -0,0 +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.
*/
package mage.sets.portalthreekingdoms;
import java.util.UUID;
/**
*
* @author LoneFox
*/
public class ForcedRetreat extends mage.sets.masterseditioniii.ForcedRetreat {
public ForcedRetreat(UUID ownerId) {
super(ownerId);
this.cardNumber = 44;
this.expansionSetCode = "PTK";
}
public ForcedRetreat(final ForcedRetreat card) {
super(card);
}
@Override
public ForcedRetreat copy() {
return new ForcedRetreat(this);
}
}

View file

@ -0,0 +1,54 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class GuanYuSaintedWarrior extends mage.sets.masterseditioniii.GuanYuSaintedWarrior {
public GuanYuSaintedWarrior(UUID ownerId) {
super(ownerId);
this.cardNumber = 6;
this.expansionSetCode = "PTK";
this.rarity = Rarity.RARE;
}
public GuanYuSaintedWarrior(final GuanYuSaintedWarrior card) {
super(card);
}
@Override
public GuanYuSaintedWarrior copy() {
return new GuanYuSaintedWarrior(this);
}
}

View file

@ -0,0 +1,73 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksAloneTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect;
import mage.abilities.keyword.HorsemanshipAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class MaChaoWesternWarrior extends CardImpl {
public MaChaoWesternWarrior(UUID ownerId) {
super(ownerId, 116, "Ma Chao, Western Warrior", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{R}{R}");
this.expansionSetCode = "PTK";
this.supertype.add("Legendary");
this.subtype.add("Human");
this.subtype.add("Soldier");
this.subtype.add("Warrior");
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Horsemanship
this.addAbility(HorsemanshipAbility.getInstance());
// Whenever Ma Chao, Western Warrior attacks alone, it can't be blocked this combat.
Effect effect = new CantBeBlockedSourceEffect(Duration.EndOfCombat);
effect.setText("it can't be blocked this combat");
this.addAbility(new AttacksAloneTriggeredAbility(effect));
}
public MaChaoWesternWarrior(final MaChaoWesternWarrior card) {
super(card);
}
@Override
public MaChaoWesternWarrior copy() {
return new MaChaoWesternWarrior(this);
}
}

View file

@ -0,0 +1,68 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.target.common.TargetCardInYourGraveyard;
/**
*
* @author LoneFox
*/
public class SagesKnowledge extends CardImpl {
public static final FilterCard filter = new FilterCard("sorcery card from your graveyard");
static {
filter.add(new CardTypePredicate(CardType.SORCERY));
}
public SagesKnowledge(UUID ownerId) {
super(ownerId, 52, "Sage's Knowledge", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{2}{U}");
this.expansionSetCode = "PTK";
// Return target sorcery card from your graveyard to your hand.
this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect());
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(filter));
}
public SagesKnowledge(final SagesKnowledge card) {
super(card);
}
@Override
public SagesKnowledge copy() {
return new SagesKnowledge(this);
}
}

View file

@ -0,0 +1,65 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.BlocksTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class ShuDefender extends CardImpl {
public ShuDefender(UUID ownerId) {
super(ownerId, 20, "Shu Defender", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.expansionSetCode = "PTK";
this.subtype.add("Human");
this.subtype.add("Soldier");
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever Shu Defender blocks, it gets +0/+2 until end of turn.
this.addAbility(new BlocksTriggeredAbility(new BoostSourceEffect(0, 2, Duration.EndOfTurn), false));
}
public ShuDefender(final ShuDefender card) {
super(card);
}
@Override
public ShuDefender copy() {
return new ShuDefender(this);
}
}

View file

@ -0,0 +1,64 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.BecomesBlockedTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class SlashingTiger extends CardImpl {
public SlashingTiger(UUID ownerId) {
super(ownerId, 145, "Slashing Tiger", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{G}{G}");
this.expansionSetCode = "PTK";
this.subtype.add("Cat");
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Whenever Slashing Tiger becomes blocked, it gets +2/+2 until end of turn.
this.addAbility(new BecomesBlockedTriggeredAbility(new BoostSourceEffect(2, 2, Duration.EndOfTurn), false));
}
public SlashingTiger(final SlashingTiger card) {
super(card);
}
@Override
public SlashingTiger copy() {
return new SlashingTiger(this);
}
}

View file

@ -0,0 +1,74 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleEvasionAbility;
import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
import mage.abilities.keyword.HorsemanshipAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate;
/**
*
* @author LoneFox
*/
public class TaoistMystic extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with horsemanship");
static {
filter.add(new AbilityPredicate(HorsemanshipAbility.class));
}
public TaoistMystic(UUID ownerId) {
super(ownerId, 151, "Taoist Mystic", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{G}");
this.expansionSetCode = "PTK";
this.subtype.add("Human");
this.subtype.add("Mystic");
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Taoist Mystic can't be blocked by creatures with horsemanship.
this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield)));
}
public TaoistMystic(final TaoistMystic card) {
super(card);
}
@Override
public TaoistMystic copy() {
return new TaoistMystic(this);
}
}

View file

@ -0,0 +1,64 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.BecomesBlockedTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class TrainedCheetah extends CardImpl {
public TrainedCheetah(UUID ownerId) {
super(ownerId, 154, "Trained Cheetah", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{G}");
this.expansionSetCode = "PTK";
this.subtype.add("Cat");
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever Trained Cheetah becomes blocked, it gets +1/+1 until end of turn.
this.addAbility(new BecomesBlockedTriggeredAbility(new BoostSourceEffect(1, 1, Duration.EndOfTurn), false));
}
public TrainedCheetah(final TrainedCheetah card) {
super(card);
}
@Override
public TrainedCheetah copy() {
return new TrainedCheetah(this);
}
}

View file

@ -0,0 +1,65 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class WeiAmbushForce extends CardImpl {
public WeiAmbushForce(UUID ownerId) {
super(ownerId, 85, "Wei Ambush Force", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.expansionSetCode = "PTK";
this.subtype.add("Human");
this.subtype.add("Soldier");
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Whenever Wei Ambush Force attacks, it gets +2/+0 until end of turn.
this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(2, 0, Duration.EndOfTurn), false));
}
public WeiAmbushForce(final WeiAmbushForce card) {
super(card);
}
@Override
public WeiAmbushForce copy() {
return new WeiAmbushForce(this);
}
}

View file

@ -0,0 +1,67 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DealsDamageToOpponentTriggeredAbility;
import mage.abilities.effects.common.discard.DiscardTargetEffect;
import mage.abilities.keyword.HorsemanshipAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class WeiNightRaiders extends CardImpl {
public WeiNightRaiders(UUID ownerId) {
super(ownerId, 89, "Wei Night Raiders", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{B}{B}");
this.expansionSetCode = "PTK";
this.subtype.add("Human");
this.subtype.add("Soldier");
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Horsemanship
this.addAbility(HorsemanshipAbility.getInstance());
// Whenever Wei Night Raiders deals damage to an opponent, that player discards a card.
this.addAbility(new DealsDamageToOpponentTriggeredAbility(new DiscardTargetEffect(1), false));
}
public WeiNightRaiders(final WeiNightRaiders card) {
super(card);
}
@Override
public WeiNightRaiders copy() {
return new WeiNightRaiders(this);
}
}

View file

@ -0,0 +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.
*/
package mage.sets.portalthreekingdoms;
import java.util.UUID;
/**
*
* @author LoneFox
*/
public class WolfPack extends mage.sets.masterseditionii.WolfPack {
public WolfPack(UUID ownerId) {
super(ownerId);
this.cardNumber = 158;
this.expansionSetCode = "PTK";
}
public WolfPack(final WolfPack card) {
super(card);
}
@Override
public WolfPack copy() {
return new WolfPack(this);
}
}

View file

@ -0,0 +1,75 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.LookAtTargetPlayerHandEffect;
import mage.abilities.keyword.HorsemanshipAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.target.common.TargetOpponent;
/**
*
* @author LoneFox
*/
public class WuScout extends CardImpl {
public WuScout(UUID ownerId) {
super(ownerId, 62, "Wu Scout", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.expansionSetCode = "PTK";
this.subtype.add("Human");
this.subtype.add("Soldier");
this.subtype.add("Scout");
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Horsemanship
this.addAbility(HorsemanshipAbility.getInstance());
// When Wu Scout enters the battlefield, look at target opponent's hand.
Effect effect = new LookAtTargetPlayerHandEffect();
effect.setText("look at target opponent's hand");
Ability ability = new EntersBattlefieldTriggeredAbility(effect, false);
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
}
public WuScout(final WuScout card) {
super(card);
}
@Override
public WuScout copy() {
return new WuScout(this);
}
}

View file

@ -0,0 +1,68 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksAloneTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class YuanShaosInfantry extends CardImpl {
public YuanShaosInfantry(UUID ownerId) {
super(ownerId, 129, "Yuan Shao's Infantry", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{R}");
this.expansionSetCode = "PTK";
this.subtype.add("Human");
this.subtype.add("Soldier");
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever Yuan Shao's Infantry attacks alone, Yuan Shao's Infantry can't be blocked this combat.
Effect effect = new CantBeBlockedSourceEffect(Duration.EndOfCombat);
effect.setText("it can't be blocked this combat");
this.addAbility(new AttacksAloneTriggeredAbility(effect));
}
public YuanShaosInfantry(final YuanShaosInfantry card) {
super(card);
}
@Override
public YuanShaosInfantry copy() {
return new YuanShaosInfantry(this);
}
}

View file

@ -0,0 +1,71 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.keyword.HorsemanshipAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.filter.common.FilterCreaturePermanent;
/**
*
* @author LoneFox
*/
public class ZhangHeWeiGeneral extends CardImpl {
public ZhangHeWeiGeneral(UUID ownerId) {
super(ownerId, 95, "Zhang He, Wei General", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
this.expansionSetCode = "PTK";
this.supertype.add("Legendary");
this.subtype.add("Human");
this.subtype.add("Soldier");
this.power = new MageInt(4);
this.toughness = new MageInt(2);
// Horsemanship
this.addAbility(HorsemanshipAbility.getInstance());
// Whenever Zhang He, Wei General attacks, each other creature you control gets +1/+0 until end of turn.
this.addAbility(new AttacksTriggeredAbility(new BoostControlledEffect(1, 0, Duration.EndOfTurn,
new FilterCreaturePermanent(), true), false));
}
public ZhangHeWeiGeneral(final ZhangHeWeiGeneral card) {
super(card);
}
@Override
public ZhangHeWeiGeneral copy() {
return new ZhangHeWeiGeneral(this);
}
}

View file

@ -0,0 +1,65 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DealsDamageToOpponentTriggeredAbility;
import mage.abilities.effects.common.discard.DiscardTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class ZhangLiaoHeroOfHefei extends CardImpl {
public ZhangLiaoHeroOfHefei(UUID ownerId) {
super(ownerId, 96, "Zhang Liao, Hero of Hefei", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{B}{B}");
this.expansionSetCode = "PTK";
this.supertype.add("Legendary");
this.subtype.add("Human");
this.subtype.add("Soldier");
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Whenever Zhang Liao, Hero of Hefei deals damage to an opponent, that opponent discards a card.
this.addAbility(new DealsDamageToOpponentTriggeredAbility(new DiscardTargetEffect(1), false));
}
public ZhangLiaoHeroOfHefei(final ZhangLiaoHeroOfHefei card) {
super(card);
}
@Override
public ZhangLiaoHeroOfHefei copy() {
return new ZhangLiaoHeroOfHefei(this);
}
}

View file

@ -0,0 +1,70 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.BlocksTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.HorsemanshipAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class ZhaoZilongTigerGeneral extends CardImpl {
public ZhaoZilongTigerGeneral(UUID ownerId) {
super(ownerId, 33, "Zhao Zilong, Tiger General", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{W}{W}");
this.expansionSetCode = "PTK";
this.supertype.add("Legendary");
this.subtype.add("Human");
this.subtype.add("Soldier");
this.subtype.add("Warrior");
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Horsemanship
this.addAbility(HorsemanshipAbility.getInstance());
// Whenever Zhao Zilong, Tiger General blocks, it gets +1/+1 until end of turn.
this.addAbility(new BlocksTriggeredAbility(new BoostSourceEffect(1, 1, Duration.EndOfTurn), false));
}
public ZhaoZilongTigerGeneral(final ZhaoZilongTigerGeneral card) {
super(card);
}
@Override
public ZhaoZilongTigerGeneral copy() {
return new ZhaoZilongTigerGeneral(this);
}
}

View file

@ -0,0 +1,63 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.effects.common.ReturnToHandSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author LoneFox
*/
public class ZodiacDragon extends CardImpl {
public ZodiacDragon(UUID ownerId) {
super(ownerId, 131, "Zodiac Dragon", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{7}{R}{R}");
this.expansionSetCode = "PTK";
this.subtype.add("Dragon");
this.power = new MageInt(8);
this.toughness = new MageInt(8);
// When Zodiac Dragon is put into your graveyard from the battlefield, you may return it to your hand.
this.addAbility(new DiesTriggeredAbility(new ReturnToHandSourceEffect(), true));
}
public ZodiacDragon(final ZodiacDragon card) {
super(card);
}
@Override
public ZodiacDragon copy() {
return new ZodiacDragon(this);
}
}

View file

@ -0,0 +1,78 @@
/*
* 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.portalthreekingdoms;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleEvasionAbility;
import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
import mage.abilities.keyword.HexproofAbility;
import mage.abilities.keyword.HorsemanshipAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate;
/**
*
* @author LoneFox
*/
public class ZuoCiTheMockingSage extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with horsemanship");
static {
filter.add(new AbilityPredicate(HorsemanshipAbility.class));
}
public ZuoCiTheMockingSage(UUID ownerId) {
super(ownerId, 165, "Zuo Ci, the Mocking Sage", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{G}{G}");
this.expansionSetCode = "PTK";
this.supertype.add("Legendary");
this.subtype.add("Human");
this.subtype.add("Advisor");
this.power = new MageInt(1);
this.toughness = new MageInt(2);
// Hexproof
this.addAbility(HexproofAbility.getInstance());
// Zuo Ci, the Mocking Sage can't be blocked by creatures with horsemanship.
this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield)));
}
public ZuoCiTheMockingSage(final ZuoCiTheMockingSage card) {
super(card);
}
@Override
public ZuoCiTheMockingSage copy() {
return new ZuoCiTheMockingSage(this);
}
}

View file

@ -0,0 +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.
*/
package mage.sets.revisededition;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public class Conversion extends mage.sets.limitedalpha.Conversion {
public Conversion(UUID ownerId) {
super(ownerId);
this.cardNumber = 198;
this.expansionSetCode = "3ED";
}
public Conversion(final Conversion card) {
super(card);
}
@Override
public Conversion copy() {
return new Conversion(this);
}
}

View file

@ -0,0 +1,80 @@
/*
* 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.revisededition;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.continuous.SetPowerToughnessTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author jeffwadsworth
*/
public class SorceressQueen extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("target creature other than {this}");
static {
filter.add(new AnotherPredicate());
}
public SorceressQueen(UUID ownerId) {
super(ownerId, 39, "Sorceress Queen", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{B}{B}");
this.expansionSetCode = "3ED";
this.subtype.add("Human");
this.subtype.add("Wizard");
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// {tap}: Target creature other than Sorceress Queen becomes 0/2 until end of turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SetPowerToughnessTargetEffect(0, 2, Duration.EndOfTurn), new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent(filter));
this.addAbility(ability);
}
public SorceressQueen(final SorceressQueen card) {
super(card);
}
@Override
public SorceressQueen copy() {
return new SorceressQueen(this);
}
}

View file

@ -0,0 +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.
*/
package mage.sets.revisededition;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public class VesuvanDoppelganger extends mage.sets.unlimitededition.VesuvanDoppelganger {
public VesuvanDoppelganger(UUID ownerId) {
super(ownerId);
this.cardNumber = 88;
this.expansionSetCode = "3ED";
}
public VesuvanDoppelganger(final VesuvanDoppelganger card) {
super(card);
}
@Override
public VesuvanDoppelganger copy() {
return new VesuvanDoppelganger(this);
}
}

View file

@ -101,6 +101,9 @@ class MoltenPsycheEffect extends OneShotEffect {
player.shuffleLibrary(game);
}
}
game.applyEffects(); // so effects from creatures that were on the battlefield won't trigger from draw action
for (UUID playerId : cardsToDraw.keySet()) {
Player player = game.getPlayer(playerId);
if (player != null) {

View file

@ -1,16 +1,16 @@
/*
* Copyright 2011 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
@ -20,14 +20,25 @@
* 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.scarsofmirrodin;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Layer;
@ -35,16 +46,10 @@ import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.SubLayer;
import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.StaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.sets.futuresight.YixlidJailer;
/**
*
@ -60,7 +65,8 @@ public class NecroticOoze extends CardImpl {
this.power = new MageInt(4);
this.toughness = new MageInt(3);
this.addAbility(new NecroticOozeAbility());
// As long as Necrotic Ooze is on the battlefield, it has all activated abilities of all creature cards in all graveyards
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new NecroticOozeEffect()));
}
public NecroticOoze(final NecroticOoze card) {
@ -72,48 +78,27 @@ public class NecroticOoze extends CardImpl {
return new NecroticOoze(this);
}
}
class NecroticOozeEffect extends ContinuousEffectImpl {
class NecroticOozeAbility extends StaticAbility {
public NecroticOozeEffect() {
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
staticText = "As long as {this} is on the battlefield, it has all activated abilities of all creature cards in all graveyards";
}
public NecroticOozeAbility() {
super(Zone.BATTLEFIELD, new NecroticOozeEffect());
}
public NecroticOozeEffect(final NecroticOozeEffect effect) {
super(effect);
}
public NecroticOozeAbility(final NecroticOozeAbility ability) {
super(ability);
}
@Override
public NecroticOozeAbility copy() {
return new NecroticOozeAbility(this);
}
}
class NecroticOozeEffect extends ContinuousEffectImpl {
public NecroticOozeEffect() {
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
staticText = "As long as {this} is on the battlefield, it has all activated abilities of all creature cards in all graveyards";
}
public NecroticOozeEffect(final NecroticOozeEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
@Override
public boolean apply(Game game, Ability source) {
Permanent perm = game.getPermanent(source.getSourceId());
if (perm != null) {
for (UUID playerId: controller.getInRange()) {
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
for (Card card: player.getGraveyard().getCards(game)) {
for (Card card : player.getGraveyard().getCards(game)) {
if (card.getCardType().contains(CardType.CREATURE)) {
for (Ability ability: card.getAbilities()) {
for (Ability ability : card.getAbilities()) {
if (ability instanceof ActivatedAbility) {
perm.addAbility(ability, game);
}
@ -122,15 +107,31 @@ class NecroticOozeEffect extends ContinuousEffectImpl {
}
}
}
return true;
}
return true;
return false;
}
@Override
public NecroticOozeEffect copy() {
return new NecroticOozeEffect(this);
}
@Override
public Set<UUID> isDependentTo(List<ContinuousEffect> allEffectsInLayer) {
// the dependent classes needs to be an enclosed class for dependent check of continuous effects
Set<UUID> dependentTo = null;
for (ContinuousEffect effect : allEffectsInLayer) {
// http://www.mtgsalvation.com/forums/magic-fundamentals/magic-rulings/magic-rulings-archives/285211-yixlid-jailer-vs-necrotic-ooze
if (YixlidJailer.class.equals(effect.getClass().getEnclosingClass())) {
if (dependentTo == null) {
dependentTo = new HashSet<>();
}
dependentTo.add(effect.getId());
}
}
return dependentTo;
}
return false;
}
@Override
public NecroticOozeEffect copy() {
return new NecroticOozeEffect(this);
}
}
}

View file

@ -54,7 +54,6 @@ public class EnchantedEvening extends CardImpl {
super(ownerId, 140, "Enchanted Evening", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{3}{W/U}{W/U}");
this.expansionSetCode = "SHM";
// All permanents are enchantments in addition to their other types.
Effect effect = new EnchangedEveningEffect(CardType.ENCHANTMENT, Duration.WhileOnBattlefield, new FilterPermanent());
effect.setText("All permanents are enchantments in addition to their other types");
@ -70,37 +69,38 @@ public class EnchantedEvening extends CardImpl {
public EnchantedEvening copy() {
return new EnchantedEvening(this);
}
}
class EnchangedEveningEffect extends ContinuousEffectImpl {
// need to be enclosed class for dependent check of continuous effects
class EnchangedEveningEffect extends ContinuousEffectImpl {
private final CardType addedCardType;
private final FilterPermanent filter;
private final CardType addedCardType;
private final FilterPermanent filter;
public EnchangedEveningEffect(CardType addedCardType, Duration duration, FilterPermanent filter) {
super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
this.addedCardType = addedCardType;
this.filter = filter;
}
public EnchangedEveningEffect(final EnchangedEveningEffect effect) {
super(effect);
this.addedCardType = effect.addedCardType;
this.filter = effect.filter;
}
@Override
public boolean apply(Game game, Ability source) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, game)) {
if (permanent != null && !permanent.getCardType().contains(addedCardType)) {
permanent.getCardType().add(addedCardType);
}
public EnchangedEveningEffect(CardType addedCardType, Duration duration, FilterPermanent filter) {
super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
this.addedCardType = addedCardType;
this.filter = filter;
}
return true;
}
@Override
public EnchangedEveningEffect copy() {
return new EnchangedEveningEffect(this);
public EnchangedEveningEffect(final EnchangedEveningEffect effect) {
super(effect);
this.addedCardType = effect.addedCardType;
this.filter = effect.filter;
}
@Override
public boolean apply(Game game, Ability source) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, game)) {
if (permanent != null && !permanent.getCardType().contains(addedCardType)) {
permanent.getCardType().add(addedCardType);
}
}
return true;
}
@Override
public EnchangedEveningEffect copy() {
return new EnchangedEveningEffect(this);
}
}
}

View file

@ -25,20 +25,17 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.tenthedition;
import java.util.UUID;
import mage.abilities.TriggeredAbilityImpl;
import mage.ObjectColor;
import mage.abilities.common.SpellCastAllTriggeredAbility;
import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.stack.Spell;
import mage.filter.FilterSpell;
import mage.filter.predicate.mageobject.ColorPredicate;
/**
*
@ -46,10 +43,18 @@ import mage.game.stack.Spell;
*/
public class AngelsFeather extends CardImpl {
private final static FilterSpell filter = new FilterSpell("a white spell");
static {
filter.add(new ColorPredicate(ObjectColor.WHITE));
}
public AngelsFeather(UUID ownerId) {
super(ownerId, 311, "Angel's Feather", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{2}");
this.expansionSetCode = "10E";
this.addAbility(new AngelsFeatherAbility());
// Whenever a player casts a white spell, you may gain 1 life.
this.addAbility(new SpellCastAllTriggeredAbility(new GainLifeEffect(1), filter, true));
}
public AngelsFeather(final AngelsFeather card) {
@ -62,36 +67,3 @@ public class AngelsFeather extends CardImpl {
}
}
class AngelsFeatherAbility extends TriggeredAbilityImpl {
public AngelsFeatherAbility() {
super(Zone.BATTLEFIELD, new GainLifeEffect(1), true);
}
public AngelsFeatherAbility(final AngelsFeatherAbility ability) {
super(ability);
}
@Override
public AngelsFeatherAbility copy() {
return new AngelsFeatherAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.SPELL_CAST;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Spell spell = game.getStack().getSpell(event.getTargetId());
return spell != null && spell.getColor(game).isWhite();
}
@Override
public String getRule() {
return "Whenever a player casts a white spell, you may gain 1 life.";
}
}

View file

@ -0,0 +1,54 @@
/*
* 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.timeshifted;
import java.util.UUID;
import mage.constants.Rarity;
/**
*
* @author jeffwadsworth
*/
public class MeriekeRiBerit extends mage.sets.iceage.MeriekeRiBerit {
public MeriekeRiBerit(UUID ownerId) {
super(ownerId);
this.cardNumber = 95;
this.expansionSetCode = "TSB";
this.rarity = Rarity.SPECIAL;
}
public MeriekeRiBerit(final MeriekeRiBerit card) {
super(card);
}
@Override
public MeriekeRiBerit copy() {
return new MeriekeRiBerit(this);
}
}

View file

@ -0,0 +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.
*/
package mage.sets.unlimitededition;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public class Conversion extends mage.sets.limitedalpha.Conversion {
public Conversion(UUID ownerId) {
super(ownerId);
this.cardNumber = 200;
this.expansionSetCode = "2ED";
}
public Conversion(final Conversion card) {
super(card);
}
@Override
public Conversion copy() {
return new Conversion(this);
}
}

View file

@ -0,0 +1,130 @@
/*
* 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.unlimitededition;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.EntersBattlefieldEffect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.util.functions.ApplyToPermanent;
/**
*
* @author jeffwadsworth
*/
public class VesuvanDoppelganger extends CardImpl {
private static final String rule = "You may have {this} enter the battlefield as a copy of any creature on the battlefield except it doesn't copy that creature's color and it gains \"At the beginning of your upkeep, you may have this creature become a copy of target creature except it doesn't copy that creature's color. If you do, this creature gains this ability.\"";
public VesuvanDoppelganger(UUID ownerId) {
super(ownerId, 88, "Vesuvan Doppelganger", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
this.expansionSetCode = "2ED";
this.subtype.add("Shapeshifter");
this.power = new MageInt(0);
this.toughness = new MageInt(0);
// You may have Vesuvan Doppelganger enter the battlefield as a copy of any creature on the battlefield except it doesn't copy that creature's color and it gains "At the beginning of your upkeep, you may have this creature become a copy of target creature except it doesn't copy that creature's color. If you do, this creature gains this ability."
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect(new VesuvanDoppelgangerCopyEffect(), rule, true));
this.addAbility(ability);
}
public VesuvanDoppelganger(final VesuvanDoppelganger card) {
super(card);
}
@Override
public VesuvanDoppelganger copy() {
return new VesuvanDoppelganger(this);
}
}
class VesuvanDoppelgangerCopyEffect extends OneShotEffect {
private static final String rule2 = "At the beginning of your upkeep, you may have this creature become a copy of target creature except it doesn't copy that creature's color. If you do, this creature gains this ability.";
public VesuvanDoppelgangerCopyEffect() {
super(Outcome.Copy);
}
public VesuvanDoppelgangerCopyEffect(final VesuvanDoppelgangerCopyEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
final Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (controller != null && sourcePermanent != null) {
Target target = new TargetPermanent(new FilterCreaturePermanent("target creature (you copy from)"));
target.setRequired(true);
if (source instanceof SimpleStaticAbility) {
target = new TargetPermanent(new FilterCreaturePermanent("creature (you copy from)"));
target.setRequired(false);
target.setNotTarget(true);
}
if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
controller.choose(Outcome.Copy, target, source.getSourceId(), game);
Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget());
if (copyFromPermanent != null) {
game.copyPermanent(copyFromPermanent, sourcePermanent, source, new ApplyToPermanent() {
@Override
public Boolean apply(Game game, Permanent permanent) {
permanent.getColor(game).setColor(sourcePermanent.getColor(game));
permanent.getAbilities().add(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
new VesuvanDoppelgangerCopyEffect(), TargetController.YOU, true, false, rule2));
return true;
}
});
return true;
}
}
}
return false;
}
@Override
public VesuvanDoppelgangerCopyEffect copy() {
return new VesuvanDoppelgangerCopyEffect(this);
}
}

View file

@ -27,9 +27,13 @@
*/
package mage.sets.urzasdestiny;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.CardImpl;
import mage.constants.CardType;
@ -47,6 +51,7 @@ import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.sets.shadowmoor.EnchantedEvening;
/**
*
@ -58,7 +63,6 @@ public class Opalescence extends CardImpl {
super(ownerId, 13, "Opalescence", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
this.expansionSetCode = "UDS";
// Each other non-Aura enchantment is a creature with power and toughness each equal to its converted mana cost. It's still an enchantment.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new OpalescenceEffect()));
@ -72,19 +76,21 @@ public class Opalescence extends CardImpl {
public Opalescence copy() {
return new Opalescence(this);
}
}
class OpalescenceEffect extends ContinuousEffectImpl {
private static final FilterEnchantmentPermanent filter = new FilterEnchantmentPermanent("Each other non-Aura enchantment");
static {
filter.add(Predicates.not(new SubtypePredicate("Aura")));
filter.add(new AnotherPredicate());
}
public OpalescenceEffect() {
super(Duration.WhileOnBattlefield, Outcome.BecomeCreature);
staticText = "Each other non-Aura enchantment is a creature with power and toughness each equal to its converted mana cost";
staticText = "Each other non-Aura enchantment is a creature in addition to its other types and has base power and base toughness each equal to its converted mana cost";
}
public OpalescenceEffect(final OpalescenceEffect effect) {
@ -125,10 +131,22 @@ class OpalescenceEffect extends ContinuousEffectImpl {
return false;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.PTChangingEffects_7 || layer == Layer.TypeChangingEffects_4;
}
@Override
public Set<UUID> isDependentTo(List<ContinuousEffect> allEffectsInLayer) {
Set<UUID> dependentTo = null;
for (ContinuousEffect effect : allEffectsInLayer) {
if (EnchantedEvening.class.equals(effect.getClass().getEnclosingClass())) {
if (dependentTo == null) {
dependentTo = new HashSet<>();
}
dependentTo.add(effect.getId());
}
}
return dependentTo;
}
}

View file

@ -0,0 +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.
*/
package mage.sets.zendikarvseldrazi;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public class DominatorDrone extends mage.sets.battleforzendikar.DominatorDrone {
public DominatorDrone(UUID ownerId) {
super(ownerId);
this.cardNumber = 51;
this.expansionSetCode = "DDP";
}
public DominatorDrone(final DominatorDrone card) {
super(card);
}
@Override
public DominatorDrone copy() {
return new DominatorDrone(this);
}
}

View file

@ -0,0 +1,84 @@
/*
* 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.zendikarvseldrazi;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.DevoidAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ColorlessPredicate;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LevelX2
*/
public class ForerunnerOfSlaughter extends CardImpl {
private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("colorless creature");
static {
filter.add(new ColorlessPredicate());
}
public ForerunnerOfSlaughter(UUID ownerId) {
super(ownerId, 64, "Forerunner of Slaughter", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{B}{R}");
this.expansionSetCode = "DDP";
this.subtype.add("Eldrazi");
this.subtype.add("Drone");
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// Devoid (This card has no color.)
this.addAbility(new DevoidAbility(this.color));
// {1}: Target colorless creature gains haste until end of turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn), new GenericManaCost(1));
ability.addTarget(new TargetCreaturePermanent(filter));
this.addAbility(ability);
}
public ForerunnerOfSlaughter(final ForerunnerOfSlaughter card) {
super(card);
}
@Override
public ForerunnerOfSlaughter copy() {
return new ForerunnerOfSlaughter(this);
}
}

View file

@ -100,6 +100,35 @@ public class CastCreaturesTest extends CardTestPlayerBaseAI {
assertPermanentCount(playerA, "Blazing Specter", 1);
}
@Test
public void testSimpleCast5() {
addCard(Zone.HAND, playerA, "Plains", 2);
addCard(Zone.HAND, playerA, "Mountain", 1);
addCard(Zone.HAND, playerA, "Silvercoat Lion", 3);
addCard(Zone.HAND, playerA, "Soul Warden");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Plains", 1);
assertPermanentCount(playerA, "Soul Warden", 1);
}
@Test
public void testSimpleCast6() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.HAND, playerA, "Plains", 2);
addCard(Zone.HAND, playerA, "Mountain", 2);
addCard(Zone.HAND, playerA, "Silvercoat Lion", 1);
addCard(Zone.HAND, playerA, "Pillarfield Ox", 1);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Plains", 1);
assertPermanentCount(playerA, "Silvercoat Lion", 1);
}
@Test
public void testCast4Creature() {
addCard(Zone.LIBRARY, playerA, "Swamp", 1);

View file

@ -63,7 +63,7 @@ public class TargetsAreChosenTest extends CardTestPlayerBaseAI {
/**
* Check that the AI does not cast Rack and Ruin if it would destroy the
* owly creature on the battlefield owned by the AI
* only creature on the battlefield owned by the AI
*/
@Test
public void testRackAndRuin2() {
@ -196,7 +196,7 @@ public class TargetsAreChosenTest extends CardTestPlayerBaseAI {
}
/**
* Test that AI counters creatire spell
* Test that AI counters creature spell
*/
@Test
@Ignore // counter spells don't seem to be cast by AI
@ -222,4 +222,13 @@ public class TargetsAreChosenTest extends CardTestPlayerBaseAI {
}
/**
* Target selection from EntersTheBattlefield is not varied in the AI
* calculation, so value is only calculated for the one selected target set.
*
* E.g. If AI casts an Eyeblight Assassin and opponent has a 3/1 and a 2/2,
* the AI should target the 3/1.
*
* Add test to check such situations
*/
}

View file

@ -0,0 +1,176 @@
/*
* 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 org.mage.test.cards.continuous;
import mage.abilities.Ability;
import mage.constants.AbilityType;
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;
/**
*
* @author LevelX2
*/
public class DependentEffectsTest extends CardTestPlayerBase {
/**
* Opalescence plus Enchanted Evening are still not wiping any lands.
*/
@Test
public void testLandsAreDestroyed() {
// Each other non-Aura enchantment is a creature in addition to its other types and has base power and base toughness each equal to its converted mana cost.
addCard(Zone.HAND, playerA, "Opalescence", 1); // {2}{W}{W}
addCard(Zone.BATTLEFIELD, playerA, "Plains", 9);
addCard(Zone.BATTLEFIELD, playerA, "War Horn", 1);
// All permanents are enchantments in addition to their other types.
addCard(Zone.HAND, playerA, "Enchanted Evening"); // {3}{W/U}{W/U}
addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Opalescence");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Enchanted Evening");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPowerToughness(playerA, "Enchanted Evening", 5, 5);
assertPowerToughness(playerA, "War Horn", 3, 3);
assertPermanentCount(playerA, "Island", 0);
assertPermanentCount(playerB, "Plains", 0);
}
/**
* Opalescense is dependent on Enchanted Evening, so it will be applied
* after it regardless of timestamp.
*
* Tokens can also have mana costs, and as a consequence of that, converted
* mana costs. A token created with Rite of Replication would have the mana
* cost of the creature it targeted. Most tokens do not have mana costs
* though.
*
* Tokens with no mana costs would be 0/0, as you said, and would indeed be
* put into owner's graveyard next time State Based Actionas are performed.
* Tokens with mana costs would naturally have whatever power and toughness
* their CMC indicated.
*/
@Test
public void testTokensAreDestroyed() {
// Each other non-Aura enchantment is a creature in addition to its other types and has base power and base toughness each equal to its converted mana cost.
addCard(Zone.BATTLEFIELD, playerA, "Opalescence", 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 9);
// Kicker {5}
// Put a token that's a copy of target creature onto the battlefield. If Rite of Replication was kicked, put five of those tokens onto the battlefield instead.
addCard(Zone.HAND, playerA, "Rite of Replication", 1); // This token can have a cmc
// All permanents are enchantments in addition to their other types.
addCard(Zone.HAND, playerA, "Enchanted Evening"); // {3}{W/U}{W/U}
addCard(Zone.BATTLEFIELD, playerB, "Cobblebrute", 1); // 5/2 cmc = 4
addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
// Put two 1/1 white Soldier creature tokens onto the battlefield.
addCard(Zone.HAND, playerB, "Raise the Alarm"); // Instant {1}{W}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rite of Replication", "Cobblebrute");
setChoice(playerA, "No"); // no kicker
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Raise the Alarm");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Enchanted Evening");
setStopAt(1, PhaseStep.END_TURN);
execute();
assertGraveyardCount(playerA, "Rite of Replication", 1);
assertGraveyardCount(playerB, "Raise the Alarm", 1);
assertPowerToughness(playerA, "Enchanted Evening", 5, 5);
assertPowerToughness(playerB, "Cobblebrute", 4, 4);
assertPowerToughness(playerA, "Cobblebrute", 4, 4);
assertPermanentCount(playerB, "Soldier", 0);
assertPermanentCount(playerA, "Island", 0);
assertPermanentCount(playerB, "Plains", 0);
}
@Test
public void testYixlidJailerAndNecroticOozeBasic() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
// As long as Necrotic Ooze is on the battlefield, it has all activated abilities of all creature cards in all graveyards
addCard(Zone.BATTLEFIELD, playerA, "Necrotic Ooze", 1);
// {2}{1},{T}: Tap target creature.
addCard(Zone.GRAVEYARD, playerA, "Akroan Jailer", 1);
// {T}: Target attacking creature gets +1/+1 until end of turn.
addCard(Zone.GRAVEYARD, playerB, "Anointer of Champions", 1);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
Permanent necroticOoze = getPermanent("Necrotic Ooze", playerA);
int numberOfActivatedAbilities = 0;
for (Ability ability : necroticOoze.getAbilities(currentGame)) {
if (ability.getAbilityType().equals(AbilityType.ACTIVATED)) {
numberOfActivatedAbilities++;
}
}
Assert.assertEquals("Two abilities for Necrotic Ooze", 2, numberOfActivatedAbilities);
}
@Test
public void testYixlidJailerAndNecroticOozeLooseAll() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
// As long as Necrotic Ooze is on the battlefield, it has all activated abilities of all creature cards in all graveyards
addCard(Zone.BATTLEFIELD, playerA, "Necrotic Ooze", 1);
// {2}{1},{T}: Tap target creature.
addCard(Zone.GRAVEYARD, playerA, "Akroan Jailer", 1);
// {T}: Target attacking creature gets +1/+1 until end of turn.
addCard(Zone.GRAVEYARD, playerB, "Anointer of Champions", 1);
// Cards in graveyards lose all abilities.
addCard(Zone.HAND, playerA, "Yixlid Jailer", 1); // Creature - {1}{B}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Yixlid Jailer");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Yixlid Jailer", 1);
Permanent necroticOoze = getPermanent("Necrotic Ooze", playerA);
int numberOfActivatedAbilities = 0;
for (Ability ability : necroticOoze.getAbilities(currentGame)) {
if (ability.getAbilityType().equals(AbilityType.ACTIVATED)) {
numberOfActivatedAbilities++;
}
}
Assert.assertEquals("All abilities from cards in graveyard are removed - so no abilities for Necrotic Ooze", 0, numberOfActivatedAbilities);
}
}

View file

@ -0,0 +1,67 @@
/*
* 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 org.mage.test.cards.triggers;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class TargetedTriggeredTest extends CardTestPlayerBase {
/**
* Tests that the first spell that targets Kira, Great Glass-Spinner is
* countered.
*
*/
@Test
@Ignore
// this does currently not work in test, because the target event will be fired earlier during tests,
// so the zone change counter for the fixed target of the counterspell will not work
public void testKiraGreatGlassSpinnerFirstSpellTurn() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.HAND, playerA, "Lightning Bolt");
addCard(Zone.BATTLEFIELD, playerB, "Kira, Great Glass-Spinner", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Kira, Great Glass-Spinner");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerA, "Lightning Bolt", 1);
assertPermanentCount(playerB, "Kira, Great Glass-Spinner", 1);
}
}

View file

@ -0,0 +1,86 @@
/*
* 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.common;
import java.util.UUID;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent.EventType;
import mage.game.events.GameEvent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author LoneFox
*/
public class AttacksAloneTriggeredAbility extends TriggeredAbilityImpl {
public AttacksAloneTriggeredAbility(Effect effect) {
super(Zone.BATTLEFIELD, effect);
}
public AttacksAloneTriggeredAbility(final AttacksAloneTriggeredAbility ability) {
super(ability);
}
@Override
public AttacksAloneTriggeredAbility copy() {
return new AttacksAloneTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.DECLARED_ATTACKERS;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if(game.getActivePlayerId().equals(this.controllerId) ) {
UUID creatureId = this.getSourceId();
if(creatureId != null) {
if(game.getCombat().attacksAlone() && creatureId == game.getCombat().getAttackers().get(0)) {
UUID defender = game.getCombat().getDefenderId(creatureId);
if(defender != null) {
for(Effect effect: getEffects()) {
effect.setTargetPointer(new FixedTarget(defender));
}
}
return true;
}
}
}
return false;
}
@Override
public String getRule() {
return "Whenever {this} attacks alone, " + super.getRule();
}
}

View file

@ -30,11 +30,11 @@ package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
* Checks if the player has its commander in play
* Checks if the player has its commander in play and controls it
*
* @author LevelX2
*/
@ -42,7 +42,8 @@ public class CommanderInPlayCondition implements Condition {
private static CommanderInPlayCondition fInstance = null;
private CommanderInPlayCondition() {}
private CommanderInPlayCondition() {
}
public static Condition getInstance() {
if (fInstance == null) {
@ -55,7 +56,8 @@ public class CommanderInPlayCondition implements Condition {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
return game.getPermanent(controller.getCommanderId()) != null;
Permanent commander = game.getPermanent(controller.getCommanderId());
return commander != null && commander.getControllerId().equals(source.getControllerId());
}
return false;
}
@ -65,4 +67,4 @@ public class CommanderInPlayCondition implements Condition {
return "As long as you control your commander";
}
}
}

View file

@ -1,34 +1,35 @@
/*
* 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.effects;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.constants.Duration;
@ -43,25 +44,42 @@ import mage.game.Game;
public interface ContinuousEffect extends Effect {
boolean isUsed();
boolean isDiscarded();
void discard();
Duration getDuration();
long getOrder();
void setOrder(long order);
boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game);
boolean hasLayer(Layer layer);
boolean isInactive(Ability source, Game game);
void init(Ability source, Game game);
Layer getLayer();
SubLayer getSublayer();
void overrideRuleText(String text);
List<MageObjectReference> getAffectedObjects();
Set<UUID> isDependentTo(List<ContinuousEffect> allEffectsInLayer);
@Override
void newId();
@Override
ContinuousEffect copy();
boolean isTemporary();
void setTemporary(boolean temporary);
}

View file

@ -29,6 +29,7 @@ package mage.abilities.effects;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
@ -250,4 +251,9 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu
this.temporary = temporary;
}
@Override
public Set<UUID> isDependentTo(List<ContinuousEffect> allEffectsInLayer) {
return null;
}
}

View file

@ -38,6 +38,7 @@ import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import mage.MageObject;
@ -851,8 +852,9 @@ public class ContinuousEffects implements Serializable {
//20091005 - 613
public void apply(Game game) {
removeInactiveEffects(game);
List<ContinuousEffect> layerEffects = getLayeredEffects(game);
List<ContinuousEffect> layer = filterLayeredEffects(layerEffects, Layer.CopyEffects_1);
List<ContinuousEffect> activeLayerEffects = getLayeredEffects(game);
List<ContinuousEffect> layer = filterLayeredEffects(activeLayerEffects, Layer.CopyEffects_1);
for (ContinuousEffect effect : layer) {
HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
for (Ability ability : abilities) {
@ -861,10 +863,10 @@ public class ContinuousEffects implements Serializable {
}
//Reload layerEffect if copy effects were applied
if (layer.size() > 0) {
layerEffects = getLayeredEffects(game);
activeLayerEffects = getLayeredEffects(game);
}
layer = filterLayeredEffects(layerEffects, Layer.ControlChangingEffects_2);
layer = filterLayeredEffects(activeLayerEffects, Layer.ControlChangingEffects_2);
// apply control changing effects multiple times if it's needed
// for cases when control over permanents with change control abilities is changed
// e.g. Mind Control is controlled by Steal Enchantment
@ -882,55 +884,72 @@ public class ContinuousEffects implements Serializable {
// reset control before reapplying control changing effects
game.getBattlefield().resetPermanentsControl();
}
layer = filterLayeredEffects(layerEffects, Layer.TextChangingEffects_3);
for (ContinuousEffect effect : layer) {
HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
for (Ability ability : abilities) {
effect.apply(Layer.TextChangingEffects_3, SubLayer.NA, ability, game);
}
}
layer = filterLayeredEffects(layerEffects, Layer.TypeChangingEffects_4);
for (ContinuousEffect effect : layer) {
HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
for (Ability ability : abilities) {
effect.apply(Layer.TypeChangingEffects_4, SubLayer.NA, ability, game);
}
}
layer = filterLayeredEffects(layerEffects, Layer.ColorChangingEffects_5);
for (ContinuousEffect effect : layer) {
HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
for (Ability ability : abilities) {
effect.apply(Layer.ColorChangingEffects_5, SubLayer.NA, ability, game);
}
}
Map<ContinuousEffect, List<Ability>> appliedEffects = new HashMap<>();
applyLayer(activeLayerEffects, Layer.TextChangingEffects_3, game);
applyLayer(activeLayerEffects, Layer.TypeChangingEffects_4, game);
applyLayer(activeLayerEffects, Layer.ColorChangingEffects_5, game);
Map<ContinuousEffect, List<Ability>> appliedEffectAbilities = new HashMap<>();
boolean done = false;
Map<ContinuousEffect, Set<UUID>> waitingEffects = new LinkedHashMap<>();
Set<UUID> appliedEffects = new HashSet<>();
while (!done) { // loop needed if a added effect adds again an effect (e.g. Level 5- of Joraga Treespeaker)
done = true;
layer = filterLayeredEffects(layerEffects, Layer.AbilityAddingRemovingEffects_6);
layer = filterLayeredEffects(activeLayerEffects, Layer.AbilityAddingRemovingEffects_6);
for (ContinuousEffect effect : layer) {
if (layerEffects.contains(effect)) {
List<Ability> appliedAbilities = appliedEffects.get(effect);
if (activeLayerEffects.contains(effect) && !appliedEffects.contains(effect.getId())) { // Effect does still exist and was not applied yet
Set<UUID> dependentTo = effect.isDependentTo(layer);
if (dependentTo != null && !appliedEffects.containsAll(dependentTo)) {
waitingEffects.put(effect, dependentTo);
continue;
}
List<Ability> appliedAbilities = appliedEffectAbilities.get(effect);
HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
for (Ability ability : abilities) {
if (appliedAbilities == null || !appliedAbilities.contains(ability)) {
if (appliedAbilities == null) {
appliedAbilities = new ArrayList<>();
appliedEffects.put(effect, appliedAbilities);
appliedEffectAbilities.put(effect, appliedAbilities);
}
appliedAbilities.add(ability);
effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, ability, game);
done = false;
// list must be updated after each applied effect (eg. if "Turn to Frog" removes abilities)
layerEffects = getLayeredEffects(game);
activeLayerEffects = getLayeredEffects(game);
}
}
appliedEffects.add(effect.getId());
if (!waitingEffects.isEmpty()) {
// check if waiting effects can be applied now
for (Iterator<Map.Entry<ContinuousEffect, Set<UUID>>> iterator = waitingEffects.entrySet().iterator(); iterator.hasNext();) {
Map.Entry<ContinuousEffect, Set<UUID>> entry = iterator.next();
if (appliedEffects.containsAll(entry.getValue())) { // all dependent to effects are applied now so apply the effect itself
appliedAbilities = appliedEffectAbilities.get(entry.getKey());
abilities = layeredEffects.getAbility(entry.getKey().getId());
for (Ability ability : abilities) {
if (appliedAbilities == null || !appliedAbilities.contains(ability)) {
if (appliedAbilities == null) {
appliedAbilities = new ArrayList<>();
appliedEffectAbilities.put(entry.getKey(), appliedAbilities);
}
appliedAbilities.add(ability);
entry.getKey().apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, ability, game);
done = false;
// list must be updated after each applied effect (eg. if "Turn to Frog" removes abilities)
activeLayerEffects = getLayeredEffects(game);
}
}
appliedEffects.add(entry.getKey().getId());
iterator.remove();
}
}
}
}
}
}
layer = filterLayeredEffects(layerEffects, Layer.PTChangingEffects_7);
layer = filterLayeredEffects(activeLayerEffects, Layer.PTChangingEffects_7);
for (ContinuousEffect effect : layer) {
HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
for (Ability ability : abilities) {
@ -952,14 +971,14 @@ public class ContinuousEffects implements Serializable {
effect.apply(Layer.PTChangingEffects_7, SubLayer.SwitchPT_e, ability, game);
}
}
layer = filterLayeredEffects(layerEffects, Layer.PlayerEffects);
layer = filterLayeredEffects(activeLayerEffects, Layer.PlayerEffects);
for (ContinuousEffect effect : layer) {
HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
for (Ability ability : abilities) {
effect.apply(Layer.PlayerEffects, SubLayer.NA, ability, game);
}
}
layer = filterLayeredEffects(layerEffects, Layer.RulesEffects);
layer = filterLayeredEffects(activeLayerEffects, Layer.RulesEffects);
for (ContinuousEffect effect : layer) {
HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
for (Ability ability : abilities) {
@ -968,6 +987,42 @@ public class ContinuousEffects implements Serializable {
}
}
private void applyLayer(List<ContinuousEffect> activeLayerEffects, Layer currentLayer, Game game) {
List<ContinuousEffect> layer = filterLayeredEffects(activeLayerEffects, currentLayer);
if (!layer.isEmpty()) {
int numberOfEffects = layer.size();
Set<UUID> appliedEffects = new HashSet<>();
Map<ContinuousEffect, Set<UUID>> waitingEffects = new LinkedHashMap<>();
for (ContinuousEffect effect : layer) {
if (numberOfEffects > 1) { // If an effect is dependent to not applied effects yet of this layer, so wait to apply this effect
Set<UUID> dependentTo = effect.isDependentTo(layer);
if (dependentTo != null && !appliedEffects.containsAll(dependentTo)) {
waitingEffects.put(effect, dependentTo);
continue;
}
}
applyContinuousEffect(effect, currentLayer, game);
appliedEffects.add(effect.getId());
if (!waitingEffects.isEmpty()) {
// check if waiting effects can be applied now
for (Entry<ContinuousEffect, Set<UUID>> entry : waitingEffects.entrySet()) {
if (appliedEffects.containsAll(entry.getValue())) { // all dependent to effects are applied now so apply the effect itself
applyContinuousEffect(entry.getKey(), currentLayer, game);
appliedEffects.add(entry.getKey().getId());
}
}
}
}
}
}
private void applyContinuousEffect(ContinuousEffect effect, Layer currentLayer, Game game) {
HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
for (Ability ability : abilities) {
effect.apply(currentLayer, SubLayer.NA, ability, game);
}
}
/**
* Adds a continuous ability with a reference to a sourceId. It's used for
* effects that cease to exist again So this effects were removed again

View file

@ -0,0 +1,41 @@
/*
* 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.keyword;
import mage.ObjectColor;
import mage.abilities.common.SimpleStaticAbility;
import mage.constants.Zone;
/**
*
* @author LevelX2
*/
public class DevoidAbility extends SimpleStaticAbility {
public DevoidAbility(ObjectColor color) {
super(Zone.ALL, null);
color.setBlack(false);
color.setWhite(false);
color.setGreen(false);
color.setBlue(false);
color.setRed(false);
}
public DevoidAbility(final DevoidAbility ability) {
super(ability);
}
@Override
public DevoidAbility copy() {
return new DevoidAbility(this);
}
@Override
public String getRule() {
return "Devoid <i>(This card has no color.)<i/>";
}
}

View file

@ -0,0 +1,71 @@
/*
* 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.keyword;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
/**
*
* @author LevelX2
*/
public class IngestAbility extends DealsCombatDamageToAPlayerTriggeredAbility {
public IngestAbility() {
super(new IngestEffect(), false, true);
}
public IngestAbility(IngestAbility ability) {
super(ability);
}
@Override
public String getRule() {
return "Ingest (Whenever this creature deals combat damage to a player, that player exiles the top card of his or her library.)";
}
@Override
public IngestAbility copy() {
return new IngestAbility(this);
}
}
class IngestEffect extends OneShotEffect {
public IngestEffect() {
super(Outcome.Exile);
this.staticText = "that player exiles the top card of his or her library";
}
public IngestEffect(final IngestEffect effect) {
super(effect);
}
@Override
public IngestEffect copy() {
return new IngestEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
if (targetPlayer != null) {
Card card = targetPlayer.getLibrary().getFromTop(game);
if (card != null) {
targetPlayer.moveCards(card, Zone.LIBRARY, Zone.EXILED, source, game);
}
return true;
}
return false;
}
}

View file

@ -60,5 +60,11 @@ public enum PlayerAction {
ADD_PERMISSION_TO_ROLLBACK_TURN,
DENY_PERMISSON_TO_ROLLBACK_TURN,
PERMISSION_REQUESTS_ALLOWED_ON,
PERMISSION_REQUESTS_ALLOWED_OFF
PERMISSION_REQUESTS_ALLOWED_OFF,
REQUEST_AUTO_ANSWER_ID_YES,
REQUEST_AUTO_ANSWER_ID_NO,
REQUEST_AUTO_ANSWER_TEXT_YES,
REQUEST_AUTO_ANSWER_TEXT_NO,
REQUEST_AUTO_ANSWER_RESET_ALL,
}

View file

@ -73,6 +73,7 @@ import mage.game.turn.Turn;
import mage.players.Player;
import mage.players.PlayerList;
import mage.players.Players;
import mage.util.MessageToClient;
import mage.util.functions.ApplyToPermanent;
public interface Game extends MageItem, Serializable {
@ -221,13 +222,13 @@ public interface Game extends MageItem, Serializable {
void addPlayerQueryEventListener(Listener<PlayerQueryEvent> listener);
void fireAskPlayerEvent(UUID playerId, String message);
void fireAskPlayerEvent(UUID playerId, MessageToClient message, Ability source);
void fireChooseChoiceEvent(UUID playerId, Choice choice);
void fireSelectTargetEvent(UUID playerId, String message, Set<UUID> targets, boolean required, Map<String, Serializable> options);
void fireSelectTargetEvent(UUID playerId, MessageToClient message, Set<UUID> targets, boolean required, Map<String, Serializable> options);
void fireSelectTargetEvent(UUID playerId, String message, Cards cards, boolean required, Map<String, Serializable> options);
void fireSelectTargetEvent(UUID playerId, MessageToClient message, Cards cards, boolean required, Map<String, Serializable> options);
void fireSelectTargetTriggeredAbilityEvent(UUID playerId, String message, List<TriggeredAbility> abilities);

View file

@ -118,6 +118,7 @@ import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.TargetPlayer;
import mage.util.GameLog;
import mage.util.MessageToClient;
import mage.util.functions.ApplyToPermanent;
import mage.watchers.Watchers;
import mage.watchers.common.BlockedAttackerWatcher;
@ -1886,11 +1887,11 @@ public abstract class GameImpl implements Game, Serializable {
}
@Override
public void fireAskPlayerEvent(UUID playerId, String message) {
public void fireAskPlayerEvent(UUID playerId, MessageToClient message, Ability source) {
if (simulation) {
return;
}
playerQueryEventSource.ask(playerId, message);
playerQueryEventSource.ask(playerId, message.getMessage(), source, addMessageToOptions(message, null));
}
@Override
@ -1914,19 +1915,19 @@ public abstract class GameImpl implements Game, Serializable {
}
@Override
public void fireSelectTargetEvent(UUID playerId, String message, Set<UUID> targets, boolean required, Map<String, Serializable> options) {
public void fireSelectTargetEvent(UUID playerId, MessageToClient message, Set<UUID> targets, boolean required, Map<String, Serializable> options) {
if (simulation) {
return;
}
playerQueryEventSource.target(playerId, message, targets, required, options);
playerQueryEventSource.target(playerId, message.getMessage(), targets, required, addMessageToOptions(message, options));
}
@Override
public void fireSelectTargetEvent(UUID playerId, String message, Cards cards, boolean required, Map<String, Serializable> options) {
public void fireSelectTargetEvent(UUID playerId, MessageToClient message, Cards cards, boolean required, Map<String, Serializable> options) {
if (simulation) {
return;
}
playerQueryEventSource.target(playerId, message, cards, required, options);
playerQueryEventSource.target(playerId, message.getMessage(), cards, required, addMessageToOptions(message, options));
}
/**
@ -2692,4 +2693,19 @@ public abstract class GameImpl implements Game, Serializable {
return enterWithCounters.get(sourceId);
}
private Map<String, Serializable> addMessageToOptions(MessageToClient message, Map<String, Serializable> options) {
if (message.getSecondMessage() != null) {
if (options == null) {
options = new HashMap<>();
}
options.put("secondMessage", message.getSecondMessage());
}
if (message.getHintText() != null) {
if (options == null) {
options = new HashMap<>();
}
options.put("hintText", message.getHintText());
}
return options;
}
}

View file

@ -149,8 +149,14 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri
this.playerId = playerId;
}
public static PlayerQueryEvent askEvent(UUID playerId, String message) {
return new PlayerQueryEvent(playerId, message, null, null, null, null, QueryType.ASK, 0, 0, false, null);
public static PlayerQueryEvent askEvent(UUID playerId, String message, Ability source, Map<String, Serializable> options) {
if (source != null) {
if (options == null) {
options = new HashMap<>();
}
options.put("originalId", source.getOriginalId());
}
return new PlayerQueryEvent(playerId, message, null, null, null, null, QueryType.ASK, 0, 0, false, options);
}
public static PlayerQueryEvent chooseAbilityEvent(UUID playerId, String message, String objectName, List<? extends ActivatedAbility> choices) {

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