mirror of
https://github.com/correl/mage.git
synced 2024-12-25 19:25:41 +00:00
Merge branch 'master' of https://github.com/brodee/mage
This commit is contained in:
commit
4c94938c14
146 changed files with 4424 additions and 1541 deletions
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-root</artifactId>
|
<artifactId>mage-root</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
XMage.de 1 (Europe/Germany) fast :xmage.de:17171
|
|
||||||
old xmage.de (Europe/Germany) :185.3.232.200:17171
|
|
||||||
XMage Players MTG:xmageplayersmtg.ddns.net:17171
|
|
||||||
XMage.tahiti :xmage.tahiti.one:443
|
|
||||||
Seedds Server (Asia) :115.29.203.80:17171
|
|
||||||
localhost -> connect to your local server (must be started):localhost:17171
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.client.deck.generator;
|
package mage.client.deck.generator;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -7,6 +6,7 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
import mage.cards.repository.CardCriteria;
|
import mage.cards.repository.CardCriteria;
|
||||||
|
@ -368,7 +368,6 @@ public final class DeckGenerator {
|
||||||
private static Card getBasicLand(ColoredManaSymbol color, Map<String, List<CardInfo>> basicLands) {
|
private static Card getBasicLand(ColoredManaSymbol color, Map<String, List<CardInfo>> basicLands) {
|
||||||
String landName = DeckGeneratorPool.getBasicLandName(color.toString());
|
String landName = DeckGeneratorPool.getBasicLandName(color.toString());
|
||||||
List<CardInfo> basicLandsInfo = basicLands.get(landName);
|
List<CardInfo> basicLandsInfo = basicLands.get(landName);
|
||||||
return basicLandsInfo.get(RandomUtil.nextInt(basicLandsInfo.size() - 1)).getMockCard().copy();
|
return basicLandsInfo.get(RandomUtil.nextInt(basicLandsInfo.size())).getMockCard().copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,28 @@ package mage.client.deckeditor;
|
||||||
import mage.util.StreamUtils;
|
import mage.util.StreamUtils;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.datatransfer.DataFlavor;
|
||||||
|
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
public class DeckImportFromClipboardDialog extends JDialog {
|
public class DeckImportFromClipboardDialog extends JDialog {
|
||||||
|
|
||||||
|
private static final String FORMAT_TEXT =
|
||||||
|
"// Example:\n" +
|
||||||
|
"//1 Library of Congress\n" +
|
||||||
|
"//1 Cryptic Gateway\n" +
|
||||||
|
"//1 Azami, Lady of Scrolls\n" +
|
||||||
|
"// NB: This is slow as, and will lock your screen :)\n" +
|
||||||
|
"\n" +
|
||||||
|
"// Your current clipboard:\n";
|
||||||
|
|
||||||
private JPanel contentPane;
|
private JPanel contentPane;
|
||||||
private JButton buttonOK;
|
private JButton buttonOK;
|
||||||
private JButton buttonCancel;
|
private JButton buttonCancel;
|
||||||
|
@ -21,6 +34,9 @@ public class DeckImportFromClipboardDialog extends JDialog {
|
||||||
|
|
||||||
public DeckImportFromClipboardDialog() {
|
public DeckImportFromClipboardDialog() {
|
||||||
initComponents();
|
initComponents();
|
||||||
|
|
||||||
|
onRefreshClipboard();
|
||||||
|
|
||||||
setContentPane(contentPane);
|
setContentPane(contentPane);
|
||||||
setModal(true);
|
setModal(true);
|
||||||
getRootPane().setDefaultButton(buttonOK);
|
getRootPane().setDefaultButton(buttonOK);
|
||||||
|
@ -40,6 +56,15 @@ public class DeckImportFromClipboardDialog extends JDialog {
|
||||||
contentPane.registerKeyboardAction(e -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
|
contentPane.registerKeyboardAction(e -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Optional<String> getClipboardStringData() {
|
||||||
|
try {
|
||||||
|
return Optional.of((String)Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor));
|
||||||
|
} catch (HeadlessException | UnsupportedFlavorException | IOException e) {
|
||||||
|
//e.printStackTrace();
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
private void onOK() {
|
private void onOK() {
|
||||||
BufferedWriter bw = null;
|
BufferedWriter bw = null;
|
||||||
try {
|
try {
|
||||||
|
@ -60,6 +85,10 @@ public class DeckImportFromClipboardDialog extends JDialog {
|
||||||
dispose();
|
dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onRefreshClipboard() {
|
||||||
|
txtDeckList.setText(FORMAT_TEXT + getClipboardStringData().orElse(""));
|
||||||
|
}
|
||||||
|
|
||||||
public String getTmpPath() {
|
public String getTmpPath() {
|
||||||
return tmpPath;
|
return tmpPath;
|
||||||
}
|
}
|
||||||
|
@ -143,7 +172,7 @@ public class DeckImportFromClipboardDialog extends JDialog {
|
||||||
|
|
||||||
txtDeckList.setMinimumSize(new Dimension(250, 400));
|
txtDeckList.setMinimumSize(new Dimension(250, 400));
|
||||||
txtDeckList.setPreferredSize(new Dimension(550, 400));
|
txtDeckList.setPreferredSize(new Dimension(550, 400));
|
||||||
txtDeckList.setText("// Example:\n//1 Library of Congress\n//1 Cryptic Gateway\n//1 Azami, Lady of Scrolls\n// NB: This is slow as, and will lock your screen :)");
|
txtDeckList.setText(FORMAT_TEXT);
|
||||||
JScrollPane txtScrollableDeckList = new JScrollPane(txtDeckList);
|
JScrollPane txtScrollableDeckList = new JScrollPane(txtDeckList);
|
||||||
panel3.add(txtScrollableDeckList, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0,
|
panel3.add(txtScrollableDeckList, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0,
|
||||||
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
|
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
|
||||||
|
|
|
@ -340,8 +340,8 @@
|
||||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||||
<Image iconType="3" name="/flags/us.png"/>
|
<Image iconType="3" name="/flags/us.png"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="text" type="java.lang.String" value="W"/>
|
<Property name="text" type="java.lang.String" value="P"/>
|
||||||
<Property name="toolTipText" type="java.lang.String" value="Connect to vaporservermtg.com (USA)"/>
|
<Property name="toolTipText" type="java.lang.String" value="Connect to mtg.powersofwar.com (USA)"/>
|
||||||
<Property name="actionCommand" type="java.lang.String" value="connectXmageus"/>
|
<Property name="actionCommand" type="java.lang.String" value="connectXmageus"/>
|
||||||
<Property name="alignmentY" type="float" value="0.0"/>
|
<Property name="alignmentY" type="float" value="0.0"/>
|
||||||
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
||||||
|
|
|
@ -270,8 +270,8 @@ public class ConnectDialog extends MageDialog {
|
||||||
});
|
});
|
||||||
|
|
||||||
btnFind3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/us.png"))); // NOI18N
|
btnFind3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/us.png"))); // NOI18N
|
||||||
btnFind3.setText("W");
|
btnFind3.setText("P");
|
||||||
btnFind3.setToolTipText("Connect to vaporservermtg.com (USA)");
|
btnFind3.setToolTipText("Connect to mtg.powersofwar.com (USA)");
|
||||||
btnFind3.setActionCommand("connectXmageus");
|
btnFind3.setActionCommand("connectXmageus");
|
||||||
btnFind3.setAlignmentY(0.0F);
|
btnFind3.setAlignmentY(0.0F);
|
||||||
btnFind3.setMargin(new java.awt.Insets(2, 2, 2, 2));
|
btnFind3.setMargin(new java.awt.Insets(2, 2, 2, 2));
|
||||||
|
@ -688,7 +688,7 @@ public class ConnectDialog extends MageDialog {
|
||||||
}//GEN-LAST:event_btnFind2findPublicServerActionPerformed
|
}//GEN-LAST:event_btnFind2findPublicServerActionPerformed
|
||||||
|
|
||||||
private void connectXmageus(java.awt.event.ActionEvent evt) {
|
private void connectXmageus(java.awt.event.ActionEvent evt) {
|
||||||
String serverAddress = "vapormtgserver.com";
|
String serverAddress = "mtg.powersofwar.com";
|
||||||
this.txtServer.setText(serverAddress);
|
this.txtServer.setText(serverAddress);
|
||||||
this.txtPort.setText("17171");
|
this.txtPort.setText("17171");
|
||||||
// Update userName and password according to the chosen server.
|
// Update userName and password according to the chosen server.
|
||||||
|
|
|
@ -51,6 +51,7 @@ public class NewTableDialog extends MageDialog {
|
||||||
this.spnNumWins.setModel(new SpinnerNumberModel(1, 1, 5, 1));
|
this.spnNumWins.setModel(new SpinnerNumberModel(1, 1, 5, 1));
|
||||||
this.spnFreeMulligans.setModel(new SpinnerNumberModel(0, 0, 5, 1));
|
this.spnFreeMulligans.setModel(new SpinnerNumberModel(0, 0, 5, 1));
|
||||||
this.spnQuitRatio.setModel(new SpinnerNumberModel(100, 0, 100, 5));
|
this.spnQuitRatio.setModel(new SpinnerNumberModel(100, 0, 100, 5));
|
||||||
|
this.spnMinimumRating.setModel(new SpinnerNumberModel(0, 0, 3000, 10));
|
||||||
this.spnEdhPowerLevel.setModel(new SpinnerNumberModel(100, 0, 100, 5));
|
this.spnEdhPowerLevel.setModel(new SpinnerNumberModel(100, 0, 100, 5));
|
||||||
MageFrame.getUI().addButton(MageComponents.NEW_TABLE_OK_BUTTON, btnOK);
|
MageFrame.getUI().addButton(MageComponents.NEW_TABLE_OK_BUTTON, btnOK);
|
||||||
}
|
}
|
||||||
|
@ -102,8 +103,10 @@ public class NewTableDialog extends MageDialog {
|
||||||
btnPreviousConfiguration2 = new javax.swing.JButton();
|
btnPreviousConfiguration2 = new javax.swing.JButton();
|
||||||
btnCancel = new javax.swing.JButton();
|
btnCancel = new javax.swing.JButton();
|
||||||
lblQuitRatio = new javax.swing.JLabel();
|
lblQuitRatio = new javax.swing.JLabel();
|
||||||
|
lblMinimumRating = new javax.swing.JLabel();
|
||||||
lblEdhPowerLevel = new javax.swing.JLabel();
|
lblEdhPowerLevel = new javax.swing.JLabel();
|
||||||
spnQuitRatio = new javax.swing.JSpinner();
|
spnQuitRatio = new javax.swing.JSpinner();
|
||||||
|
spnMinimumRating = new javax.swing.JSpinner();
|
||||||
spnEdhPowerLevel = new javax.swing.JSpinner();
|
spnEdhPowerLevel = new javax.swing.JSpinner();
|
||||||
|
|
||||||
setTitle("New Table");
|
setTitle("New Table");
|
||||||
|
@ -186,9 +189,11 @@ public class NewTableDialog extends MageDialog {
|
||||||
btnCancel.addActionListener(evt -> btnCancelActionPerformed(evt));
|
btnCancel.addActionListener(evt -> btnCancelActionPerformed(evt));
|
||||||
|
|
||||||
lblQuitRatio.setText("Allowed quit %");
|
lblQuitRatio.setText("Allowed quit %");
|
||||||
|
lblMinimumRating.setText("Minimum rating");
|
||||||
lblEdhPowerLevel.setText("EDH power level");
|
lblEdhPowerLevel.setText("EDH power level");
|
||||||
|
|
||||||
spnQuitRatio.setToolTipText("Players with quit % more than this value can't join this table");
|
spnQuitRatio.setToolTipText("Players with quit % more than this value can't join this table");
|
||||||
|
spnMinimumRating.setToolTipText("Players with rating less than this value can't join this table");
|
||||||
spnEdhPowerLevel.setToolTipText("Players with decks with a higher power level can't join this table");
|
spnEdhPowerLevel.setToolTipText("Players with decks with a higher power level can't join this table");
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||||
|
@ -239,9 +244,10 @@ public class NewTableDialog extends MageDialog {
|
||||||
.addComponent(lblQuitRatio)
|
.addComponent(lblQuitRatio)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addComponent(lblEdhPowerLevel)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
|
.addComponent(lblMinimumRating)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(spnEdhPowerLevel, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
.addComponent(spnMinimumRating, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
||||||
.addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING)
|
.addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(jLabel2, javax.swing.GroupLayout.Alignment.LEADING)
|
.addComponent(jLabel2, javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
@ -270,7 +276,11 @@ public class NewTableDialog extends MageDialog {
|
||||||
.addGap(18, 18, 18)
|
.addGap(18, 18, 18)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(lblNumWins)
|
.addComponent(lblNumWins)
|
||||||
.addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
.addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(lblEdhPowerLevel)
|
||||||
|
.addComponent(spnEdhPowerLevel, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||||
.addComponent(jSeparator2)
|
.addComponent(jSeparator2)
|
||||||
.addComponent(player1Panel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addComponent(player1Panel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
.addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
@ -297,14 +307,13 @@ public class NewTableDialog extends MageDialog {
|
||||||
.addComponent(cbTimeLimit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(cbTimeLimit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(cbDeckType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addComponent(lbDeckType)
|
.addComponent(lbDeckType)
|
||||||
|
.addComponent(cbDeckType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addComponent(chkRated)
|
||||||
.addComponent(lblQuitRatio)
|
.addComponent(lblQuitRatio)
|
||||||
.addComponent(chkRated)
|
|
||||||
.addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addComponent(lblEdhPowerLevel)
|
.addComponent(lblMinimumRating)
|
||||||
.addComponent(chkRated)
|
.addComponent(spnMinimumRating, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addComponent(spnEdhPowerLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
@ -326,6 +335,7 @@ public class NewTableDialog extends MageDialog {
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(lblSkillLevel)
|
.addComponent(lblSkillLevel)
|
||||||
.addComponent(lblNumWins)
|
.addComponent(lblNumWins)
|
||||||
|
.addComponent(lblEdhPowerLevel)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(lblRange)
|
.addComponent(lblRange)
|
||||||
.addComponent(lblAttack)))
|
.addComponent(lblAttack)))
|
||||||
|
@ -334,7 +344,8 @@ public class NewTableDialog extends MageDialog {
|
||||||
.addComponent(cbRange, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(cbRange, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addComponent(cbAttackOption, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(cbAttackOption, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addComponent(cbSkillLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(cbSkillLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
.addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addComponent(spnEdhPowerLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
@ -394,6 +405,7 @@ public class NewTableDialog extends MageDialog {
|
||||||
options.setFreeMulligans((Integer) this.spnFreeMulligans.getValue());
|
options.setFreeMulligans((Integer) this.spnFreeMulligans.getValue());
|
||||||
options.setPassword(this.txtPassword.getText());
|
options.setPassword(this.txtPassword.getText());
|
||||||
options.setQuitRatio((Integer) this.spnQuitRatio.getValue());
|
options.setQuitRatio((Integer) this.spnQuitRatio.getValue());
|
||||||
|
options.setMinimumRating((Integer) this.spnMinimumRating.getValue());
|
||||||
options.setEdhPowerLevel((Integer) this.spnEdhPowerLevel.getValue());
|
options.setEdhPowerLevel((Integer) this.spnEdhPowerLevel.getValue());
|
||||||
String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> "");
|
String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> "");
|
||||||
options.setBannedUsers(IgnoreList.ignoreList(serverAddress));
|
options.setBannedUsers(IgnoreList.ignoreList(serverAddress));
|
||||||
|
@ -695,6 +707,7 @@ public class NewTableDialog extends MageDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.spnQuitRatio.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_QUIT_RATIO, "100")));
|
this.spnQuitRatio.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_QUIT_RATIO, "100")));
|
||||||
|
this.spnMinimumRating.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_MINIMUM_RATING + versionStr, "0")));
|
||||||
this.spnEdhPowerLevel.setValue(0);
|
this.spnEdhPowerLevel.setValue(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,6 +742,7 @@ public class NewTableDialog extends MageDialog {
|
||||||
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_SPECTATORS_ALLOWED + versionStr, options.isSpectatorsAllowed() ? "Yes" : "No");
|
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_SPECTATORS_ALLOWED + versionStr, options.isSpectatorsAllowed() ? "Yes" : "No");
|
||||||
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_PLANECHASE + versionStr, options.isPlaneChase() ? "Yes" : "No");
|
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_PLANECHASE + versionStr, options.isPlaneChase() ? "Yes" : "No");
|
||||||
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_QUIT_RATIO + versionStr, Integer.toString(options.getQuitRatio()));
|
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_QUIT_RATIO + versionStr, Integer.toString(options.getQuitRatio()));
|
||||||
|
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_MINIMUM_RATING + versionStr, Integer.toString(options.getMinimumRating()));
|
||||||
StringBuilder playerTypesString = new StringBuilder();
|
StringBuilder playerTypesString = new StringBuilder();
|
||||||
for (Object player : players) {
|
for (Object player : players) {
|
||||||
if (playerTypesString.length() > 0) {
|
if (playerTypesString.length() > 0) {
|
||||||
|
@ -770,6 +784,7 @@ public class NewTableDialog extends MageDialog {
|
||||||
private javax.swing.JLabel lblNumWins;
|
private javax.swing.JLabel lblNumWins;
|
||||||
private javax.swing.JLabel lblPassword;
|
private javax.swing.JLabel lblPassword;
|
||||||
private javax.swing.JLabel lblQuitRatio;
|
private javax.swing.JLabel lblQuitRatio;
|
||||||
|
private javax.swing.JLabel lblMinimumRating;
|
||||||
private javax.swing.JLabel lblEdhPowerLevel;
|
private javax.swing.JLabel lblEdhPowerLevel;
|
||||||
private javax.swing.JLabel lblRange;
|
private javax.swing.JLabel lblRange;
|
||||||
private javax.swing.JLabel lblSkillLevel;
|
private javax.swing.JLabel lblSkillLevel;
|
||||||
|
@ -779,6 +794,7 @@ public class NewTableDialog extends MageDialog {
|
||||||
private javax.swing.JSpinner spnNumPlayers;
|
private javax.swing.JSpinner spnNumPlayers;
|
||||||
private javax.swing.JSpinner spnNumWins;
|
private javax.swing.JSpinner spnNumWins;
|
||||||
private javax.swing.JSpinner spnQuitRatio;
|
private javax.swing.JSpinner spnQuitRatio;
|
||||||
|
private javax.swing.JSpinner spnMinimumRating;
|
||||||
private javax.swing.JSpinner spnEdhPowerLevel;
|
private javax.swing.JSpinner spnEdhPowerLevel;
|
||||||
private javax.swing.JTextField txtName;
|
private javax.swing.JTextField txtName;
|
||||||
private javax.swing.JTextField txtPassword;
|
private javax.swing.JTextField txtPassword;
|
||||||
|
|
|
@ -75,6 +75,7 @@ public class NewTournamentDialog extends MageDialog {
|
||||||
this.spnConstructTime.setModel(new SpinnerNumberModel(10, CONSTRUCTION_TIME_MIN, CONSTRUCTION_TIME_MAX, 2));
|
this.spnConstructTime.setModel(new SpinnerNumberModel(10, CONSTRUCTION_TIME_MIN, CONSTRUCTION_TIME_MAX, 2));
|
||||||
this.spnNumRounds.setModel(new SpinnerNumberModel(2, 2, 10, 1));
|
this.spnNumRounds.setModel(new SpinnerNumberModel(2, 2, 10, 1));
|
||||||
this.spnQuitRatio.setModel(new SpinnerNumberModel(100, 0, 100, 5));
|
this.spnQuitRatio.setModel(new SpinnerNumberModel(100, 0, 100, 5));
|
||||||
|
this.spnMinimumRating.setModel(new SpinnerNumberModel(0, 0, 3000, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showDialog(UUID roomId) {
|
public void showDialog(UUID roomId) {
|
||||||
|
@ -165,6 +166,8 @@ public class NewTournamentDialog extends MageDialog {
|
||||||
pnlRandomPacks = new javax.swing.JPanel();
|
pnlRandomPacks = new javax.swing.JPanel();
|
||||||
lblQuitRatio = new javax.swing.JLabel();
|
lblQuitRatio = new javax.swing.JLabel();
|
||||||
spnQuitRatio = new javax.swing.JSpinner();
|
spnQuitRatio = new javax.swing.JSpinner();
|
||||||
|
lblMinimumRating = new javax.swing.JLabel();
|
||||||
|
spnMinimumRating = new javax.swing.JSpinner();
|
||||||
|
|
||||||
setTitle("New Tournament");
|
setTitle("New Tournament");
|
||||||
|
|
||||||
|
@ -315,8 +318,10 @@ public class NewTournamentDialog extends MageDialog {
|
||||||
pnlRandomPacks.setLayout(new javax.swing.BoxLayout(pnlRandomPacks, javax.swing.BoxLayout.Y_AXIS));
|
pnlRandomPacks.setLayout(new javax.swing.BoxLayout(pnlRandomPacks, javax.swing.BoxLayout.Y_AXIS));
|
||||||
|
|
||||||
lblQuitRatio.setText("Allowed quit %:");
|
lblQuitRatio.setText("Allowed quit %:");
|
||||||
|
lblMinimumRating.setText("Minimum rating:");
|
||||||
|
|
||||||
spnQuitRatio.setToolTipText("Players with quit % more than this value can't join this table");
|
spnQuitRatio.setToolTipText("Players with quit % more than this value can't join this table");
|
||||||
|
spnMinimumRating.setToolTipText("Players with rating less than this value can't join this table");
|
||||||
spnNumSeats.setToolTipText("The number of seats for each duel. If more than 2, will set number of wins to 1");
|
spnNumSeats.setToolTipText("The number of seats for each duel. If more than 2, will set number of wins to 1");
|
||||||
spnNumPlayers.setToolTipText("The total number of players who will draft");
|
spnNumPlayers.setToolTipText("The total number of players who will draft");
|
||||||
|
|
||||||
|
@ -386,11 +391,15 @@ public class NewTournamentDialog extends MageDialog {
|
||||||
.addComponent(lblNumWins)
|
.addComponent(lblNumWins)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
.addComponent(lblQuitRatio)
|
.addComponent(lblQuitRatio)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
|
.addComponent(lblMinimumRating)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(spnMinimumRating, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
.addComponent(chkRated))
|
.addComponent(chkRated))
|
||||||
.addComponent(cbTournamentType, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
.addComponent(cbTournamentType, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
@ -444,6 +453,8 @@ public class NewTournamentDialog extends MageDialog {
|
||||||
.addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addComponent(lblQuitRatio)
|
.addComponent(lblQuitRatio)
|
||||||
.addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addComponent(lblMinimumRating)
|
||||||
|
.addComponent(spnMinimumRating, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addComponent(chkRated))
|
.addComponent(chkRated))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
@ -522,6 +533,7 @@ public class NewTournamentDialog extends MageDialog {
|
||||||
tOptions.setWatchingAllowed(cbAllowSpectators.isSelected());
|
tOptions.setWatchingAllowed(cbAllowSpectators.isSelected());
|
||||||
tOptions.setPlaneChase(cbPlaneChase.isSelected());
|
tOptions.setPlaneChase(cbPlaneChase.isSelected());
|
||||||
tOptions.setQuitRatio((Integer) spnQuitRatio.getValue());
|
tOptions.setQuitRatio((Integer) spnQuitRatio.getValue());
|
||||||
|
tOptions.setMinimumRating((Integer) spnMinimumRating.getValue());
|
||||||
for (TournamentPlayerPanel player : players) {
|
for (TournamentPlayerPanel player : players) {
|
||||||
tOptions.getPlayerTypes().add((PlayerType) player.getPlayerType().getSelectedItem());
|
tOptions.getPlayerTypes().add((PlayerType) player.getPlayerType().getSelectedItem());
|
||||||
}
|
}
|
||||||
|
@ -1065,6 +1077,7 @@ public class NewTournamentDialog extends MageDialog {
|
||||||
this.spnFreeMulligans.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_FREE_MULLIGANS + versionStr, "0")));
|
this.spnFreeMulligans.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_FREE_MULLIGANS + versionStr, "0")));
|
||||||
this.spnNumWins.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_WINS + versionStr, "2")));
|
this.spnNumWins.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_WINS + versionStr, "2")));
|
||||||
this.spnQuitRatio.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_QUIT_RATIO + versionStr, "100")));
|
this.spnQuitRatio.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_QUIT_RATIO + versionStr, "100")));
|
||||||
|
this.spnMinimumRating.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_MINIMUM_RATING + versionStr, "0")));
|
||||||
|
|
||||||
TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem();
|
TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem();
|
||||||
activatePanelElements(tournamentType);
|
activatePanelElements(tournamentType);
|
||||||
|
@ -1150,6 +1163,7 @@ public class NewTournamentDialog extends MageDialog {
|
||||||
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_FREE_MULLIGANS + versionStr, Integer.toString(tOptions.getMatchOptions().getFreeMulligans()));
|
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_FREE_MULLIGANS + versionStr, Integer.toString(tOptions.getMatchOptions().getFreeMulligans()));
|
||||||
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_WINS + versionStr, Integer.toString(tOptions.getMatchOptions().getWinsNeeded()));
|
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_WINS + versionStr, Integer.toString(tOptions.getMatchOptions().getWinsNeeded()));
|
||||||
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_QUIT_RATIO + versionStr, Integer.toString(tOptions.getQuitRatio()));
|
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_QUIT_RATIO + versionStr, Integer.toString(tOptions.getQuitRatio()));
|
||||||
|
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_MINIMUM_RATING + versionStr, Integer.toString(tOptions.getMinimumRating()));
|
||||||
|
|
||||||
if (tOptions.getTournamentType().startsWith("Sealed")) {
|
if (tOptions.getTournamentType().startsWith("Sealed")) {
|
||||||
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_SEALED + versionStr, tOptions.getLimitedOptions().getSetCodes().toString());
|
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_SEALED + versionStr, tOptions.getLimitedOptions().getSetCodes().toString());
|
||||||
|
@ -1221,6 +1235,7 @@ public class NewTournamentDialog extends MageDialog {
|
||||||
private javax.swing.JLabel lblPassword;
|
private javax.swing.JLabel lblPassword;
|
||||||
private javax.swing.JLabel lblPlayer1;
|
private javax.swing.JLabel lblPlayer1;
|
||||||
private javax.swing.JLabel lblQuitRatio;
|
private javax.swing.JLabel lblQuitRatio;
|
||||||
|
private javax.swing.JLabel lblMinimumRating;
|
||||||
private javax.swing.JLabel lblTournamentType;
|
private javax.swing.JLabel lblTournamentType;
|
||||||
private mage.client.table.NewPlayerPanel player1Panel;
|
private mage.client.table.NewPlayerPanel player1Panel;
|
||||||
private javax.swing.JPanel pnlDraftOptions;
|
private javax.swing.JPanel pnlDraftOptions;
|
||||||
|
@ -1235,6 +1250,7 @@ public class NewTournamentDialog extends MageDialog {
|
||||||
private javax.swing.JSpinner spnNumRounds;
|
private javax.swing.JSpinner spnNumRounds;
|
||||||
private javax.swing.JSpinner spnNumWins;
|
private javax.swing.JSpinner spnNumWins;
|
||||||
private javax.swing.JSpinner spnQuitRatio;
|
private javax.swing.JSpinner spnQuitRatio;
|
||||||
|
private javax.swing.JSpinner spnMinimumRating;
|
||||||
private javax.swing.JTextField txtName;
|
private javax.swing.JTextField txtName;
|
||||||
private javax.swing.JTextField txtPassword;
|
private javax.swing.JTextField txtPassword;
|
||||||
private org.jdesktop.beansbinding.BindingGroup bindingGroup;
|
private org.jdesktop.beansbinding.BindingGroup bindingGroup;
|
||||||
|
|
|
@ -222,6 +222,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
||||||
public static final String KEY_NEW_TABLE_NUMBER_PLAYERS = "newTableNumberPlayers";
|
public static final String KEY_NEW_TABLE_NUMBER_PLAYERS = "newTableNumberPlayers";
|
||||||
public static final String KEY_NEW_TABLE_PLAYER_TYPES = "newTablePlayerTypes";
|
public static final String KEY_NEW_TABLE_PLAYER_TYPES = "newTablePlayerTypes";
|
||||||
public static final String KEY_NEW_TABLE_QUIT_RATIO = "newTableQuitRatio";
|
public static final String KEY_NEW_TABLE_QUIT_RATIO = "newTableQuitRatio";
|
||||||
|
public static final String KEY_NEW_TABLE_MINIMUM_RATING = "newTableMinimumRating";
|
||||||
public static final String KEY_NEW_TABLE_RATED = "newTableRated";
|
public static final String KEY_NEW_TABLE_RATED = "newTableRated";
|
||||||
|
|
||||||
// pref setting for new tournament dialog
|
// pref setting for new tournament dialog
|
||||||
|
@ -243,6 +244,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
||||||
public static final String KEY_NEW_TOURNAMENT_ALLOW_ROLLBACKS = "newTournamentAllowRollbacks";
|
public static final String KEY_NEW_TOURNAMENT_ALLOW_ROLLBACKS = "newTournamentAllowRollbacks";
|
||||||
public static final String KEY_NEW_TOURNAMENT_DECK_FILE = "newTournamentDeckFile";
|
public static final String KEY_NEW_TOURNAMENT_DECK_FILE = "newTournamentDeckFile";
|
||||||
public static final String KEY_NEW_TOURNAMENT_QUIT_RATIO = "newTournamentQuitRatio";
|
public static final String KEY_NEW_TOURNAMENT_QUIT_RATIO = "newTournamentQuitRatio";
|
||||||
|
public static final String KEY_NEW_TOURNAMENT_MINIMUM_RATING = "newTournamentMinimumRating";
|
||||||
public static final String KEY_NEW_TOURNAMENT_RATED = "newTournamentRated";
|
public static final String KEY_NEW_TOURNAMENT_RATED = "newTournamentRated";
|
||||||
|
|
||||||
// pref setting for deck generator
|
// pref setting for deck generator
|
||||||
|
|
|
@ -26,6 +26,8 @@ import mage.view.CardView;
|
||||||
import mage.view.PermanentView;
|
import mage.view.PermanentView;
|
||||||
import net.xeoh.plugins.base.PluginManager;
|
import net.xeoh.plugins.base.PluginManager;
|
||||||
import net.xeoh.plugins.base.impl.PluginManagerFactory;
|
import net.xeoh.plugins.base.impl.PluginManagerFactory;
|
||||||
|
import net.xeoh.plugins.base.util.uri.ClassURI;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.mage.plugins.card.CardPluginImpl;
|
import org.mage.plugins.card.CardPluginImpl;
|
||||||
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
|
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
|
||||||
|
@ -46,13 +48,15 @@ public enum Plugins implements MagePlugins {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadPlugins() {
|
public void loadPlugins() {
|
||||||
|
|
||||||
LOGGER.info("Loading plugins...");
|
LOGGER.info("Loading plugins...");
|
||||||
pm = PluginManagerFactory.createPluginManager();
|
pm = PluginManagerFactory.createPluginManager();
|
||||||
pm.addPluginsFrom(new File(PLUGINS_DIRECTORY + File.separator).toURI());
|
pm.addPluginsFrom(new File(PLUGINS_DIRECTORY + File.separator).toURI());
|
||||||
this.cardPlugin = new CardPluginImpl();
|
pm.addPluginsFrom(new ClassURI(CardPluginImpl.class).toURI());
|
||||||
|
pm.addPluginsFrom(new ClassURI(ThemePluginImpl.class).toURI());
|
||||||
|
|
||||||
|
this.cardPlugin = pm.getPlugin(CardPlugin.class);
|
||||||
this.counterPlugin = pm.getPlugin(CounterPlugin.class);
|
this.counterPlugin = pm.getPlugin(CounterPlugin.class);
|
||||||
this.themePlugin = new ThemePluginImpl();
|
this.themePlugin = pm.getPlugin(ThemePlugin.class);
|
||||||
LOGGER.info("Done.");
|
LOGGER.info("Done.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,66 +1,58 @@
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TablesPanel.java
|
* TablesPanel.java
|
||||||
*
|
*
|
||||||
* Created on 15-Dec-2009, 10:54:01 PM
|
* Created on 15-Dec-2009, 10:54:01 PM
|
||||||
*/
|
*/
|
||||||
package mage.client.table;
|
package mage.client.table;
|
||||||
|
|
||||||
import java.awt.*;
|
import mage.cards.decks.importer.DeckImporterUtil;
|
||||||
import java.awt.event.ActionEvent;
|
import mage.client.MageFrame;
|
||||||
import java.awt.event.MouseAdapter;
|
import mage.client.SessionHandler;
|
||||||
import java.awt.event.MouseEvent;
|
import mage.client.chat.ChatPanelBasic;
|
||||||
import java.beans.PropertyVetoException;
|
import mage.client.components.MageComponents;
|
||||||
import java.io.File;
|
import mage.client.dialog.*;
|
||||||
import java.text.DateFormat;
|
import mage.client.util.*;
|
||||||
import java.text.SimpleDateFormat;
|
import mage.client.util.gui.GuiDisplayUtil;
|
||||||
import java.util.*;
|
import mage.client.util.gui.TableUtil;
|
||||||
import java.util.concurrent.CancellationException;
|
import mage.constants.*;
|
||||||
import java.util.concurrent.ExecutionException;
|
import mage.game.match.MatchOptions;
|
||||||
import java.util.concurrent.Executors;
|
import mage.players.PlayerType;
|
||||||
import java.util.concurrent.TimeUnit;
|
import mage.remote.MageRemoteException;
|
||||||
import javax.swing.*;
|
import mage.view.MatchView;
|
||||||
import javax.swing.table.AbstractTableModel;
|
import mage.view.RoomUsersView;
|
||||||
import javax.swing.table.DefaultTableCellRenderer;
|
import mage.view.TableView;
|
||||||
import javax.swing.table.TableCellRenderer;
|
import mage.view.UserRequestMessage;
|
||||||
import mage.cards.decks.importer.DeckImporterUtil;
|
import org.apache.log4j.Logger;
|
||||||
import mage.client.MageFrame;
|
import org.mage.card.arcane.CardRendererUtils;
|
||||||
import mage.client.SessionHandler;
|
import org.ocpsoft.prettytime.Duration;
|
||||||
import mage.client.chat.ChatPanelBasic;
|
import org.ocpsoft.prettytime.PrettyTime;
|
||||||
import mage.client.components.MageComponents;
|
import org.ocpsoft.prettytime.units.JustNow;
|
||||||
import mage.client.dialog.*;
|
|
||||||
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_COLUMNS_ORDER;
|
|
||||||
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH;
|
|
||||||
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_FILTER_SETTINGS;
|
|
||||||
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_1;
|
|
||||||
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_2;
|
|
||||||
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_3;
|
|
||||||
import mage.client.util.ButtonColumn;
|
|
||||||
import mage.client.util.GUISizeHelper;
|
|
||||||
import mage.client.util.IgnoreList;
|
|
||||||
import mage.client.util.MageTableRowSorter;
|
|
||||||
import mage.client.util.URLHandler;
|
|
||||||
import mage.client.util.gui.GuiDisplayUtil;
|
|
||||||
import mage.client.util.gui.TableUtil;
|
|
||||||
import mage.constants.*;
|
|
||||||
import mage.game.match.MatchOptions;
|
|
||||||
import mage.players.PlayerType;
|
|
||||||
import mage.remote.MageRemoteException;
|
|
||||||
import mage.view.MatchView;
|
|
||||||
import mage.view.RoomUsersView;
|
|
||||||
import mage.view.TableView;
|
|
||||||
import mage.view.UserRequestMessage;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.ocpsoft.prettytime.Duration;
|
|
||||||
import org.ocpsoft.prettytime.PrettyTime;
|
|
||||||
import org.ocpsoft.prettytime.units.JustNow;
|
|
||||||
|
|
||||||
/**
|
import javax.swing.*;
|
||||||
*
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
|
import javax.swing.table.TableCellRenderer;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.beans.PropertyVetoException;
|
||||||
|
import java.io.File;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CancellationException;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static mage.client.dialog.PreferencesDialog.*;
|
||||||
|
|
||||||
|
/**
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
public class TablesPanel extends javax.swing.JPanel {
|
public class TablesPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(TablesPanel.class);
|
private static final Logger LOGGER = Logger.getLogger(TablesPanel.class);
|
||||||
private static final int[] DEFAULT_COLUMNS_WIDTH = {35, 150, 120, 180, 80, 120, 80, 60, 40, 40, 60};
|
private static final int[] DEFAULT_COLUMNS_WIDTH = {35, 150, 120, 180, 80, 120, 80, 60, 40, 40, 60};
|
||||||
|
@ -134,6 +126,41 @@ public class TablesPanel extends javax.swing.JPanel {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// skill renderer
|
||||||
|
TableCellRenderer skillCellRenderer = new DefaultTableCellRenderer() {
|
||||||
|
|
||||||
|
// base panel to render
|
||||||
|
private JPanel renderPanel = new JPanel();
|
||||||
|
private ImageIcon skillIcon = new ImageIcon(this.getClass().getResource("/info/yellow_star_16.png"));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||||
|
|
||||||
|
// get table text cell settings
|
||||||
|
DefaultTableCellRenderer baseRenderer = (DefaultTableCellRenderer) table.getDefaultRenderer(String.class);
|
||||||
|
JLabel baseComp = (JLabel) baseRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||||
|
String skillCode = baseComp.getText();
|
||||||
|
|
||||||
|
// apply settings to render panel from parent
|
||||||
|
renderPanel.setOpaque(baseComp.isOpaque());
|
||||||
|
renderPanel.setForeground(CardRendererUtils.copyColor(baseComp.getForeground()));
|
||||||
|
renderPanel.setBackground(CardRendererUtils.copyColor(baseComp.getBackground()));
|
||||||
|
renderPanel.setBorder(baseComp.getBorder());
|
||||||
|
|
||||||
|
// create each skill symbol as child label
|
||||||
|
renderPanel.removeAll();
|
||||||
|
renderPanel.setLayout(new BoxLayout(renderPanel, BoxLayout.X_AXIS));
|
||||||
|
for (char skillSymbol : skillCode.toCharArray()) {
|
||||||
|
JLabel symbolLabel = new JLabel();
|
||||||
|
symbolLabel.setBorder(new EmptyBorder(0, 3, 0, 0));
|
||||||
|
symbolLabel.setIcon(skillIcon);
|
||||||
|
renderPanel.add(symbolLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderPanel;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new form TablesPanel
|
* Creates new form TablesPanel
|
||||||
*/
|
*/
|
||||||
|
@ -158,6 +185,9 @@ public class TablesPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
// time ago
|
// time ago
|
||||||
tableTables.getColumnModel().getColumn(TableTableModel.COLUMN_CREATED).setCellRenderer(timeAgoCellRenderer);
|
tableTables.getColumnModel().getColumn(TableTableModel.COLUMN_CREATED).setCellRenderer(timeAgoCellRenderer);
|
||||||
|
// skill level
|
||||||
|
tableTables.getColumnModel().getColumn(TableTableModel.COLUMN_SKILL).setCellRenderer(skillCellRenderer);
|
||||||
|
|
||||||
/* date sorter (not need, default is good - see getColumnClass)
|
/* date sorter (not need, default is good - see getColumnClass)
|
||||||
activeTablesSorter.setComparator(TableTableModel.COLUMN_CREATED, new Comparator<Date>() {
|
activeTablesSorter.setComparator(TableTableModel.COLUMN_CREATED, new Comparator<Date>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -166,6 +196,7 @@ public class TablesPanel extends javax.swing.JPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
});*/
|
});*/
|
||||||
|
|
||||||
// default sort by created date (last games from above)
|
// default sort by created date (last games from above)
|
||||||
ArrayList list = new ArrayList();
|
ArrayList list = new ArrayList();
|
||||||
list.add(new RowSorter.SortKey(TableTableModel.COLUMN_CREATED, SortOrder.DESCENDING));
|
list.add(new RowSorter.SortKey(TableTableModel.COLUMN_CREATED, SortOrder.DESCENDING));
|
||||||
|
@ -326,9 +357,14 @@ public class TablesPanel extends javax.swing.JPanel {
|
||||||
table.addMouseListener(new MouseAdapter() {
|
table.addMouseListener(new MouseAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void mouseClicked(MouseEvent e) {
|
public void mouseClicked(MouseEvent e) {
|
||||||
int row = table.convertRowIndexToModel(table.getSelectedRow());
|
if (e.getClickCount() == 2) {
|
||||||
if (e.getClickCount() == 2 && row != -1) {
|
int selRow = table.getSelectedRow();
|
||||||
action.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "" + row));
|
if (selRow != -1) {
|
||||||
|
int dataRow = table.convertRowIndexToModel(selRow);
|
||||||
|
if (dataRow != -1) {
|
||||||
|
action.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "" + dataRow));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -620,15 +656,16 @@ public class TablesPanel extends javax.swing.JPanel {
|
||||||
formatFilterList.add(RowFilter.regexFilter("^Momir Basic|^Constructed - Pauper|^Constructed - Frontier|^Constructed - Extended|^Constructed - Eternal|^Constructed - Historical|^Constructed - Super|^Constructed - Freeform|^Australian Highlander|^Canadian Highlander|^Constructed - Old", TableTableModel.COLUMN_DECK_TYPE));
|
formatFilterList.add(RowFilter.regexFilter("^Momir Basic|^Constructed - Pauper|^Constructed - Frontier|^Constructed - Extended|^Constructed - Eternal|^Constructed - Historical|^Constructed - Super|^Constructed - Freeform|^Australian Highlander|^Canadian Highlander|^Constructed - Old", TableTableModel.COLUMN_DECK_TYPE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skill
|
||||||
java.util.List<RowFilter<Object, Object>> skillFilterList = new ArrayList<>();
|
java.util.List<RowFilter<Object, Object>> skillFilterList = new ArrayList<>();
|
||||||
if (btnSkillBeginner.isSelected()) {
|
if (btnSkillBeginner.isSelected()) {
|
||||||
skillFilterList.add(RowFilter.regexFilter(SkillLevel.BEGINNER.toString(), TableTableModel.COLUMN_SKILL));
|
skillFilterList.add(RowFilter.regexFilter(this.tableModel.getSkillLevelAsCode(SkillLevel.BEGINNER, true), TableTableModel.COLUMN_SKILL));
|
||||||
}
|
}
|
||||||
if (btnSkillCasual.isSelected()) {
|
if (btnSkillCasual.isSelected()) {
|
||||||
skillFilterList.add(RowFilter.regexFilter(SkillLevel.CASUAL.toString(), TableTableModel.COLUMN_SKILL));
|
skillFilterList.add(RowFilter.regexFilter(this.tableModel.getSkillLevelAsCode(SkillLevel.CASUAL, true), TableTableModel.COLUMN_SKILL));
|
||||||
}
|
}
|
||||||
if (btnSkillSerious.isSelected()) {
|
if (btnSkillSerious.isSelected()) {
|
||||||
skillFilterList.add(RowFilter.regexFilter(SkillLevel.SERIOUS.toString(), TableTableModel.COLUMN_SKILL));
|
skillFilterList.add(RowFilter.regexFilter(this.tableModel.getSkillLevelAsCode(SkillLevel.SERIOUS, true), TableTableModel.COLUMN_SKILL));
|
||||||
}
|
}
|
||||||
|
|
||||||
String ratedMark = TableTableModel.RATED_VALUE_YES;
|
String ratedMark = TableTableModel.RATED_VALUE_YES;
|
||||||
|
@ -1221,6 +1258,7 @@ public class TablesPanel extends javax.swing.JPanel {
|
||||||
options.setSkillLevel(SkillLevel.CASUAL);
|
options.setSkillLevel(SkillLevel.CASUAL);
|
||||||
options.setRollbackTurnsAllowed(true);
|
options.setRollbackTurnsAllowed(true);
|
||||||
options.setQuitRatio(100);
|
options.setQuitRatio(100);
|
||||||
|
options.setMinimumRating(0);
|
||||||
String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> "");
|
String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> "");
|
||||||
options.setBannedUsers(IgnoreList.ignoreList(serverAddress));
|
options.setBannedUsers(IgnoreList.ignoreList(serverAddress));
|
||||||
table = SessionHandler.createTable(roomId, options);
|
table = SessionHandler.createTable(roomId, options);
|
||||||
|
@ -1335,14 +1373,15 @@ class TableTableModel extends AbstractTableModel {
|
||||||
public static final int COLUMN_SKILL = 8;
|
public static final int COLUMN_SKILL = 8;
|
||||||
public static final int COLUMN_RATING = 9;
|
public static final int COLUMN_RATING = 9;
|
||||||
public static final int COLUMN_QUIT_RATIO = 10;
|
public static final int COLUMN_QUIT_RATIO = 10;
|
||||||
public static final int ACTION_COLUMN = 11; // column the action is located (starting with 0)
|
public static final int COLUMN_MINIMUM_RATING = 11;
|
||||||
|
public static final int ACTION_COLUMN = 12; // column the action is located (starting with 0)
|
||||||
|
|
||||||
public static final String RATED_VALUE_YES = "YES";
|
public static final String RATED_VALUE_YES = "YES";
|
||||||
public static final String RATED_VALUE_NO = "";
|
public static final String RATED_VALUE_NO = "";
|
||||||
|
|
||||||
public static final String PASSWORD_VALUE_YES = "YES";
|
public static final String PASSWORD_VALUE_YES = "YES";
|
||||||
|
|
||||||
private final String[] columnNames = new String[]{"M/T", "Deck Type", "Owner / Players", "Game Type", "Info", "Status", "Password", "Created / Started", "Skill Level", "Rating", "Quit %", "Action"};
|
private final String[] columnNames = new String[]{"M/T", "Deck Type", "Owner / Players", "Game Type", "Info", "Status", "Password", "Created / Started", "Skill Level", "Rated", "Quit %", "Min Rating", "Action"};
|
||||||
|
|
||||||
private TableView[] tables = new TableView[0];
|
private TableView[] tables = new TableView[0];
|
||||||
|
|
||||||
|
@ -1354,6 +1393,31 @@ class TableTableModel extends AbstractTableModel {
|
||||||
this.fireTableDataChanged();
|
this.fireTableDataChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSkillLevelAsCode(SkillLevel skill, boolean asRegExp) {
|
||||||
|
String res;
|
||||||
|
switch (skill) {
|
||||||
|
case BEGINNER:
|
||||||
|
res = "*";
|
||||||
|
break;
|
||||||
|
case CASUAL:
|
||||||
|
res = "**";
|
||||||
|
break;
|
||||||
|
case SERIOUS:
|
||||||
|
res = "***";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// regexp format for search table rows
|
||||||
|
if (asRegExp) {
|
||||||
|
res = String.format("^%s$", res.replace("*", "\\*"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRowCount() {
|
public int getRowCount() {
|
||||||
return tables.length;
|
return tables.length;
|
||||||
|
@ -1384,12 +1448,14 @@ class TableTableModel extends AbstractTableModel {
|
||||||
case 7:
|
case 7:
|
||||||
return tables[arg0].getCreateTime(); // use cell render, not format here
|
return tables[arg0].getCreateTime(); // use cell render, not format here
|
||||||
case 8:
|
case 8:
|
||||||
return tables[arg0].getSkillLevel();
|
return this.getSkillLevelAsCode(tables[arg0].getSkillLevel(), false);
|
||||||
case 9:
|
case 9:
|
||||||
return tables[arg0].isRated() ? RATED_VALUE_YES : RATED_VALUE_NO;
|
return tables[arg0].isRated() ? RATED_VALUE_YES : RATED_VALUE_NO;
|
||||||
case 10:
|
case 10:
|
||||||
return tables[arg0].getQuitRatio();
|
return tables[arg0].getQuitRatio();
|
||||||
case 11:
|
case 11:
|
||||||
|
return tables[arg0].getMinimumRating();
|
||||||
|
case 12:
|
||||||
switch (tables[arg0].getTableState()) {
|
switch (tables[arg0].getTableState()) {
|
||||||
|
|
||||||
case WAITING:
|
case WAITING:
|
||||||
|
@ -1419,14 +1485,14 @@ class TableTableModel extends AbstractTableModel {
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
case 12:
|
|
||||||
return tables[arg0].isTournament();
|
|
||||||
case 13:
|
case 13:
|
||||||
|
return tables[arg0].isTournament();
|
||||||
|
case 14:
|
||||||
if (!tables[arg0].getGames().isEmpty()) {
|
if (!tables[arg0].getGames().isEmpty()) {
|
||||||
return tables[arg0].getGames().get(0);
|
return tables[arg0].getGames().get(0);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
case 14:
|
case 15:
|
||||||
return tables[arg0].getTableId();
|
return tables[arg0].getTableId();
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
/*
|
|
||||||
* 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 org.mage.card.arcane;
|
package org.mage.card.arcane;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
@ -74,9 +69,9 @@ public final class CardRendererUtils {
|
||||||
int b = c.getBlue();
|
int b = c.getBlue();
|
||||||
int alpha = c.getAlpha();
|
int alpha = c.getAlpha();
|
||||||
|
|
||||||
int plus_r = (int) (Math.min (255 - r, r) / 2);
|
int plus_r = (int) (Math.min(255 - r, r) / 2);
|
||||||
int plus_g = (int) (Math.min (255 - g, g) / 2);
|
int plus_g = (int) (Math.min(255 - g, g) / 2);
|
||||||
int plus_b = (int) (Math.min (255 - b, b) / 2);
|
int plus_b = (int) (Math.min(255 - b, b) / 2);
|
||||||
|
|
||||||
return new Color(r - plus_r,
|
return new Color(r - plus_r,
|
||||||
g - plus_g,
|
g - plus_g,
|
||||||
|
@ -192,4 +187,12 @@ public final class CardRendererUtils {
|
||||||
.replaceAll("<i>", "")
|
.replaceAll("<i>", "")
|
||||||
.replaceAll("</i>", "");
|
.replaceAll("</i>", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Color copyColor(Color color) {
|
||||||
|
if (color != null) {
|
||||||
|
return new Color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,13 @@ import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author JayDi85
|
||||||
|
*/
|
||||||
public final class ManaSymbolsCellRenderer extends DefaultTableCellRenderer {
|
public final class ManaSymbolsCellRenderer extends DefaultTableCellRenderer {
|
||||||
|
|
||||||
// base panel to render
|
// base panel to render
|
||||||
private JPanel manaPanel = new JPanel();
|
private JPanel renderPanel = new JPanel();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
|
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
|
||||||
|
@ -20,47 +23,47 @@ public final class ManaSymbolsCellRenderer extends DefaultTableCellRenderer {
|
||||||
|
|
||||||
// get table text cell settings
|
// get table text cell settings
|
||||||
DefaultTableCellRenderer baseRenderer = (DefaultTableCellRenderer) table.getDefaultRenderer(String.class);
|
DefaultTableCellRenderer baseRenderer = (DefaultTableCellRenderer) table.getDefaultRenderer(String.class);
|
||||||
JLabel baseLabel = (JLabel)baseRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
JLabel baseComp = (JLabel) baseRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||||
|
|
||||||
// apply settings to mana panel from parent
|
// apply settings to mana panel from parent
|
||||||
manaPanel.setOpaque(baseLabel.isOpaque());
|
renderPanel.setOpaque(baseComp.isOpaque());
|
||||||
manaPanel.setForeground(baseLabel.getForeground());
|
renderPanel.setForeground(CardRendererUtils.copyColor(baseComp.getForeground()));
|
||||||
manaPanel.setBackground(baseLabel.getBackground());
|
renderPanel.setBackground(CardRendererUtils.copyColor(baseComp.getBackground()));
|
||||||
|
renderPanel.setBorder(baseComp.getBorder());
|
||||||
|
|
||||||
// icons size with margin
|
// icons size with margin
|
||||||
int symbolWidth = GUISizeHelper.symbolTableSize;
|
int symbolWidth = GUISizeHelper.symbolTableSize;
|
||||||
int symbolHorizontalMargin = 2;
|
int symbolHorizontalMargin = 2;
|
||||||
|
|
||||||
// create each mana symbol as child label
|
// create each mana symbol as child label
|
||||||
String manaCost = (String)value;
|
String manaCost = (String) value;
|
||||||
manaPanel.removeAll();
|
renderPanel.removeAll();
|
||||||
manaPanel.setLayout(new BoxLayout(manaPanel, BoxLayout.X_AXIS));
|
renderPanel.setLayout(new BoxLayout(renderPanel, BoxLayout.X_AXIS));
|
||||||
if(manaCost != null){
|
if (manaCost != null) {
|
||||||
StringTokenizer tok = new StringTokenizer(manaCost, " ");
|
StringTokenizer tok = new StringTokenizer(manaCost, " ");
|
||||||
while (tok.hasMoreTokens()) {
|
while (tok.hasMoreTokens()) {
|
||||||
String symbol = tok.nextToken();
|
String symbol = tok.nextToken();
|
||||||
|
|
||||||
JLabel symbolLabel = new JLabel();
|
JLabel symbolLabel = new JLabel();
|
||||||
//symbolLabel.setBorder(new LineBorder(new Color(150, 150, 150))); // debug
|
//symbolLabel.setBorder(new LineBorder(new Color(150, 150, 150))); // debug
|
||||||
symbolLabel.setBorder(new EmptyBorder(0, symbolHorizontalMargin,0, 0));
|
symbolLabel.setBorder(new EmptyBorder(0, symbolHorizontalMargin, 0, 0));
|
||||||
|
|
||||||
BufferedImage image = ManaSymbols.getSizedManaSymbol(symbol, symbolWidth);
|
BufferedImage image = ManaSymbols.getSizedManaSymbol(symbol, symbolWidth);
|
||||||
if (image != null){
|
if (image != null) {
|
||||||
// icon
|
// icon
|
||||||
symbolLabel.setIcon(new ImageIcon(image));
|
symbolLabel.setIcon(new ImageIcon(image));
|
||||||
}else
|
} else {
|
||||||
{
|
|
||||||
// text
|
// text
|
||||||
symbolLabel.setText("{" + symbol + "}");
|
symbolLabel.setText("{" + symbol + "}");
|
||||||
symbolLabel.setOpaque(baseLabel.isOpaque());
|
symbolLabel.setOpaque(baseComp.isOpaque());
|
||||||
symbolLabel.setForeground(baseLabel.getForeground());
|
symbolLabel.setForeground(baseComp.getForeground());
|
||||||
symbolLabel.setBackground(baseLabel.getBackground());
|
symbolLabel.setBackground(baseComp.getBackground());
|
||||||
}
|
}
|
||||||
|
|
||||||
manaPanel.add(symbolLabel);
|
renderPanel.add(symbolLabel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return manaPanel;
|
return renderPanel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
Mage.Client/src/main/resources/info/yellow_star_16.png
Normal file
BIN
Mage.Client/src/main/resources/info/yellow_star_16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 478 B |
BIN
Mage.Client/src/main/resources/info/yellow_star_24.png
Normal file
BIN
Mage.Client/src/main/resources/info/yellow_star_24.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 658 B |
BIN
Mage.Client/src/main/resources/info/yellow_star_32.png
Normal file
BIN
Mage.Client/src/main/resources/info/yellow_star_32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 931 B |
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-root</artifactId>
|
<artifactId>mage-root</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-common</artifactId>
|
<artifactId>mage-common</artifactId>
|
||||||
|
|
|
@ -13,8 +13,8 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
|
||||||
*/
|
*/
|
||||||
public final static int MAGE_VERSION_MAJOR = 1;
|
public final static int MAGE_VERSION_MAJOR = 1;
|
||||||
public final static int MAGE_VERSION_MINOR = 4;
|
public final static int MAGE_VERSION_MINOR = 4;
|
||||||
public final static int MAGE_VERSION_PATCH = 31;
|
public final static int MAGE_VERSION_PATCH = 32;
|
||||||
public final static String MAGE_VERSION_MINOR_PATCH = "V4";
|
public final static String MAGE_VERSION_MINOR_PATCH = "V0";
|
||||||
public final static String MAGE_VERSION_INFO = "";
|
public final static String MAGE_VERSION_INFO = "";
|
||||||
|
|
||||||
private final int major;
|
private final int major;
|
||||||
|
|
|
@ -36,6 +36,7 @@ public class TableView implements Serializable {
|
||||||
private List<SeatView> seats = new ArrayList<>();
|
private List<SeatView> seats = new ArrayList<>();
|
||||||
private List<UUID> games = new ArrayList<>();
|
private List<UUID> games = new ArrayList<>();
|
||||||
private final String quitRatio;
|
private final String quitRatio;
|
||||||
|
private final String minimumRating;
|
||||||
private final boolean limited;
|
private final boolean limited;
|
||||||
private final boolean rated;
|
private final boolean rated;
|
||||||
private final boolean passworded;
|
private final boolean passworded;
|
||||||
|
@ -111,6 +112,7 @@ public class TableView implements Serializable {
|
||||||
this.additionalInfo = addInfo.toString();
|
this.additionalInfo = addInfo.toString();
|
||||||
this.skillLevel = table.getMatch().getOptions().getSkillLevel();
|
this.skillLevel = table.getMatch().getOptions().getSkillLevel();
|
||||||
this.quitRatio = Integer.toString(table.getMatch().getOptions().getQuitRatio());
|
this.quitRatio = Integer.toString(table.getMatch().getOptions().getQuitRatio());
|
||||||
|
this.minimumRating = Integer.toString(table.getMatch().getOptions().getMinimumRating());
|
||||||
this.limited = table.getMatch().getOptions().isLimited();
|
this.limited = table.getMatch().getOptions().isLimited();
|
||||||
this.rated = table.getMatch().getOptions().isRated();
|
this.rated = table.getMatch().getOptions().isRated();
|
||||||
this.passworded = !table.getMatch().getOptions().getPassword().isEmpty();
|
this.passworded = !table.getMatch().getOptions().getPassword().isEmpty();
|
||||||
|
@ -159,6 +161,7 @@ public class TableView implements Serializable {
|
||||||
this.deckType = table.getDeckType() + ' ' + table.getTournament().getBoosterInfo() + (tableNameInfo != null ? tableNameInfo : "");
|
this.deckType = table.getDeckType() + ' ' + table.getTournament().getBoosterInfo() + (tableNameInfo != null ? tableNameInfo : "");
|
||||||
this.skillLevel = table.getTournament().getOptions().getMatchOptions().getSkillLevel();
|
this.skillLevel = table.getTournament().getOptions().getMatchOptions().getSkillLevel();
|
||||||
this.quitRatio = Integer.toString(table.getTournament().getOptions().getQuitRatio());
|
this.quitRatio = Integer.toString(table.getTournament().getOptions().getQuitRatio());
|
||||||
|
this.minimumRating = Integer.toString(table.getTournament().getOptions().getMinimumRating());
|
||||||
this.limited = table.getTournament().getOptions().getMatchOptions().isLimited();
|
this.limited = table.getTournament().getOptions().getMatchOptions().isLimited();
|
||||||
this.rated = table.getTournament().getOptions().getMatchOptions().isRated();
|
this.rated = table.getTournament().getOptions().getMatchOptions().isRated();
|
||||||
this.passworded = !table.getTournament().getOptions().getPassword().isEmpty();
|
this.passworded = !table.getTournament().getOptions().getPassword().isEmpty();
|
||||||
|
@ -223,9 +226,9 @@ public class TableView implements Serializable {
|
||||||
return skillLevel;
|
return skillLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getQuitRatio() {
|
public String getQuitRatio() { return quitRatio; }
|
||||||
return quitRatio;
|
|
||||||
}
|
public String getMinimumRating() { return minimumRating; }
|
||||||
|
|
||||||
public boolean isLimited() {
|
public boolean isLimited() {
|
||||||
return limited;
|
return limited;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-plugins</artifactId>
|
<artifactId>mage-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-counter-plugin</artifactId>
|
<artifactId>mage-counter-plugin</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-root</artifactId>
|
<artifactId>mage-root</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-plugins</artifactId>
|
<artifactId>mage-plugins</artifactId>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-root</artifactId>
|
<artifactId>mage-root</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-deck-constructed</artifactId>
|
<artifactId>mage-deck-constructed</artifactId>
|
||||||
|
|
|
@ -45,6 +45,7 @@ public class CanadianHighlander extends Constructed {
|
||||||
pointMap.put("Personal Tutor", 1);
|
pointMap.put("Personal Tutor", 1);
|
||||||
pointMap.put("Protean Hulk", 3);
|
pointMap.put("Protean Hulk", 3);
|
||||||
pointMap.put("Sol Ring", 3);
|
pointMap.put("Sol Ring", 3);
|
||||||
|
pointMap.put("Spellseeker", 1);
|
||||||
pointMap.put("Stoneforge Mystic", 1);
|
pointMap.put("Stoneforge Mystic", 1);
|
||||||
pointMap.put("Strip Mine", 2);
|
pointMap.put("Strip Mine", 2);
|
||||||
pointMap.put("Summoner's Pact", 2);
|
pointMap.put("Summoner's Pact", 2);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-deck-limited</artifactId>
|
<artifactId>mage-deck-limited</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-brawlduel</artifactId>
|
<artifactId>mage-game-brawlduel</artifactId>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-brawlfreeforall</artifactId>
|
<artifactId>mage-game-brawlfreeforall</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-canadianhighlanderduel</artifactId>
|
<artifactId>mage-game-canadianhighlanderduel</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-commanderduel</artifactId>
|
<artifactId>mage-game-commanderduel</artifactId>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-commanderfreeforall</artifactId>
|
<artifactId>mage-game-commanderfreeforall</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-freeforall</artifactId>
|
<artifactId>mage-game-freeforall</artifactId>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-freeformcommanderfreeforall</artifactId>
|
<artifactId>mage-game-freeformcommanderfreeforall</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-momirduel</artifactId>
|
<artifactId>mage-game-momirduel</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-momirfreeforall</artifactId>
|
<artifactId>mage-game-momirfreeforall</artifactId>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-pennydreadfulcommanderfreeforall</artifactId>
|
<artifactId>mage-game-pennydreadfulcommanderfreeforall</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-tinyleadersduel</artifactId>
|
<artifactId>mage-game-tinyleadersduel</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-game-twoplayerduel</artifactId>
|
<artifactId>mage-game-twoplayerduel</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-player-ai-draftbot</artifactId>
|
<artifactId>mage-player-ai-draftbot</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-player-ai-ma</artifactId>
|
<artifactId>mage-player-ai-ma</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-player-ai</artifactId>
|
<artifactId>mage-player-ai</artifactId>
|
||||||
|
|
|
@ -862,6 +862,19 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
return target.isChosen();
|
return target.isChosen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (target.getOriginalTarget() instanceof TargetCardInGraveyardOrBattlefield) {
|
||||||
|
List<Card> cards = new ArrayList<>();
|
||||||
|
for (Player player : game.getPlayers().values()) {
|
||||||
|
cards.addAll(player.getGraveyard().getCards(game));
|
||||||
|
cards.addAll(game.getBattlefield().getAllActivePermanents(new FilterPermanent(), player.getId(), game));
|
||||||
|
}
|
||||||
|
Card card = pickTarget(cards, outcome, target, source, game);
|
||||||
|
if (card != null) {
|
||||||
|
target.addTarget(card.getId(), source, game);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
throw new IllegalStateException("Target wasn't handled. class:" + target.getClass().toString());
|
throw new IllegalStateException("Target wasn't handled. class:" + target.getClass().toString());
|
||||||
} //end of chooseTarget method
|
} //end of chooseTarget method
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-player-ai-mcts</artifactId>
|
<artifactId>mage-player-ai-mcts</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-player-aiminimax</artifactId>
|
<artifactId>mage-player-aiminimax</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-player-human</artifactId>
|
<artifactId>mage-player-human</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-tournament-boosterdraft</artifactId>
|
<artifactId>mage-tournament-boosterdraft</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-tournament-constructed</artifactId>
|
<artifactId>mage-tournament-constructed</artifactId>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-tournament-sealed</artifactId>
|
<artifactId>mage-tournament-sealed</artifactId>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-root</artifactId>
|
<artifactId>mage-root</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-server-plugins</artifactId>
|
<artifactId>mage-server-plugins</artifactId>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-root</artifactId>
|
<artifactId>mage-root</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>mage-server</artifactId>
|
<artifactId>mage-server</artifactId>
|
||||||
|
|
|
@ -227,6 +227,20 @@ public class MageServerImpl implements MageServer {
|
||||||
user.showUserMessage("Create tournament", message);
|
user.showUserMessage("Create tournament", message);
|
||||||
throw new MageException("No message");
|
throw new MageException("No message");
|
||||||
}
|
}
|
||||||
|
// check if the user satisfies the minimumRating requirement.
|
||||||
|
int minimumRating = options.getMinimumRating();
|
||||||
|
int userRating;
|
||||||
|
if (options.getMatchOptions().isLimited()) {
|
||||||
|
userRating = user.getUserData().getLimitedRating();
|
||||||
|
} else {
|
||||||
|
userRating = user.getUserData().getConstructedRating();
|
||||||
|
}
|
||||||
|
if (userRating < minimumRating) {
|
||||||
|
String message = new StringBuilder("Your rating ").append(userRating)
|
||||||
|
.append(" is lower than the table requirement ").append(minimumRating).toString();
|
||||||
|
user.showUserMessage("Create tournament", message);
|
||||||
|
throw new MageException("No message");
|
||||||
|
}
|
||||||
Optional<GamesRoom> room = GamesRoomManager.instance.getRoom(roomId);
|
Optional<GamesRoom> room = GamesRoomManager.instance.getRoom(roomId);
|
||||||
if (!room.isPresent()) {
|
if (!room.isPresent()) {
|
||||||
|
|
||||||
|
@ -1386,7 +1400,19 @@ public class MageServerImpl implements MageServer {
|
||||||
user.showUserMessage("Create table", "Your quit ratio " + user.getMatchQuitRatio() + "% is higher than the table requirement " + quitRatio + '%');
|
user.showUserMessage("Create table", "Your quit ratio " + user.getMatchQuitRatio() + "% is higher than the table requirement " + quitRatio + '%');
|
||||||
throw new MageException("No message");
|
throw new MageException("No message");
|
||||||
}
|
}
|
||||||
|
// check if the user satisfies the minimumRating requirement.
|
||||||
|
int minimumRating = options.getMinimumRating();
|
||||||
|
int userRating;
|
||||||
|
if (options.isLimited()) {
|
||||||
|
userRating = user.getUserData().getLimitedRating();
|
||||||
|
} else {
|
||||||
|
userRating = user.getUserData().getConstructedRating();
|
||||||
|
}
|
||||||
|
if (userRating < minimumRating) {
|
||||||
|
String message = new StringBuilder("Your rating ").append(userRating).append(" is lower than the table requirement ").append(minimumRating).toString();
|
||||||
|
user.showUserMessage("Create table", message);
|
||||||
|
throw new MageException("No message");
|
||||||
|
}
|
||||||
Optional<GamesRoom> room = GamesRoomManager.instance.getRoom(roomId);
|
Optional<GamesRoom> room = GamesRoomManager.instance.getRoom(roomId);
|
||||||
if (room.isPresent()) {
|
if (room.isPresent()) {
|
||||||
TableView table = room.get().createTable(userId, options);
|
TableView table = room.get().createTable(userId, options);
|
||||||
|
|
|
@ -172,6 +172,21 @@ public class TableController {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check minimum rating.
|
||||||
|
int minimumRating = table.getTournament().getOptions().getMinimumRating();
|
||||||
|
int userRating;
|
||||||
|
if (table.getTournament().getOptions().getMatchOptions().isLimited()) {
|
||||||
|
userRating = user.getUserData().getLimitedRating();
|
||||||
|
} else {
|
||||||
|
userRating = user.getUserData().getConstructedRating();
|
||||||
|
}
|
||||||
|
if (userRating < minimumRating) {
|
||||||
|
String message = new StringBuilder("Your rating ").append(userRating)
|
||||||
|
.append(" is lower than the table requirement ").append(minimumRating).toString();
|
||||||
|
user.showUserMessage("Join Table", message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Optional<Player> playerOptional = createPlayer(name, seat.getPlayerType(), skill);
|
Optional<Player> playerOptional = createPlayer(name, seat.getPlayerType(), skill);
|
||||||
if (playerOptional.isPresent()) {
|
if (playerOptional.isPresent()) {
|
||||||
Player player = playerOptional.get();
|
Player player = playerOptional.get();
|
||||||
|
@ -272,6 +287,21 @@ public class TableController {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check minimum rating.
|
||||||
|
int minimumRating = table.getMatch().getOptions().getMinimumRating();
|
||||||
|
int userRating;
|
||||||
|
if (table.getMatch().getOptions().isLimited()) {
|
||||||
|
userRating = user.getUserData().getLimitedRating();
|
||||||
|
} else {
|
||||||
|
userRating = user.getUserData().getConstructedRating();
|
||||||
|
}
|
||||||
|
if (userRating < minimumRating) {
|
||||||
|
String message = new StringBuilder("Your rating ").append(userRating)
|
||||||
|
.append(" is lower than the table requirement ").append(minimumRating).toString();
|
||||||
|
user.showUserMessage("Join Table", message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Check power level for table (currently only used for EDH/Commander table)
|
// Check power level for table (currently only used for EDH/Commander table)
|
||||||
int edhPowerLevel = table.getMatch().getOptions().getEdhPowerLevel();
|
int edhPowerLevel = table.getMatch().getOptions().getEdhPowerLevel();
|
||||||
if (edhPowerLevel > 0 && table.getValidator().getName().toLowerCase(Locale.ENGLISH).equals("commander")) {
|
if (edhPowerLevel > 0 && table.getValidator().getName().toLowerCase(Locale.ENGLISH).equals("commander")) {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>mage-root</artifactId>
|
<artifactId>mage-root</artifactId>
|
||||||
<version>1.4.31</version>
|
<version>1.4.32</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.common.AttacksTriggeredAbility;
|
import mage.abilities.common.AttacksTriggeredAbility;
|
||||||
import mage.abilities.effects.common.LoseLifeOpponentsEffect;
|
import mage.abilities.effects.common.LoseLifeAllPlayersEffect;
|
||||||
import mage.abilities.keyword.MenaceAbility;
|
import mage.abilities.keyword.MenaceAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
@ -18,7 +17,7 @@ import mage.constants.SubType;
|
||||||
public final class AdroitHateflayer extends CardImpl {
|
public final class AdroitHateflayer extends CardImpl {
|
||||||
|
|
||||||
public AdroitHateflayer(UUID ownerId, CardSetInfo setInfo) {
|
public AdroitHateflayer(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U}{B}{R}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{B}{R}");
|
||||||
this.subtype.add(SubType.NAUTOLAN);
|
this.subtype.add(SubType.NAUTOLAN);
|
||||||
this.subtype.add(SubType.SITH);
|
this.subtype.add(SubType.SITH);
|
||||||
this.power = new MageInt(3);
|
this.power = new MageInt(3);
|
||||||
|
@ -27,8 +26,8 @@ public final class AdroitHateflayer extends CardImpl {
|
||||||
// Menace
|
// Menace
|
||||||
this.addAbility(new MenaceAbility());
|
this.addAbility(new MenaceAbility());
|
||||||
|
|
||||||
// Whenever Adroit Hateflayer attacks, each opponent loses 2 life.
|
// Whenever Adroit Hateflayer attacks, each player loses 2 life.
|
||||||
this.addAbility(new AttacksTriggeredAbility(new LoseLifeOpponentsEffect(2), false));
|
this.addAbility(new AttacksTriggeredAbility(new LoseLifeAllPlayersEffect(2), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public AdroitHateflayer(final AdroitHateflayer card) {
|
public AdroitHateflayer(final AdroitHateflayer card) {
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class AminatouTheFateShifter extends CardImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
public AminatouTheFateShifter(UUID ownerId, CardSetInfo setInfo) {
|
public AminatouTheFateShifter(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{W}{U}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{W}{U}{B}");
|
||||||
this.addSuperType(SuperType.LEGENDARY);
|
this.addSuperType(SuperType.LEGENDARY);
|
||||||
this.subtype.add(SubType.AMINATOU);
|
this.subtype.add(SubType.AMINATOU);
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ public class AminatouTheFateShifter extends CardImpl {
|
||||||
|
|
||||||
// -1: Exile another target permanent you own, then return it to the battlefield under your control.
|
// -1: Exile another target permanent you own, then return it to the battlefield under your control.
|
||||||
ability = new LoyaltyAbility(new ExileTargetForSourceEffect(), -1);
|
ability = new LoyaltyAbility(new ExileTargetForSourceEffect(), -1);
|
||||||
ability.addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect());
|
ability.addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect(true));
|
||||||
ability.addTarget(new TargetPermanent(filter));
|
ability.addTarget(new TargetPermanent(filter));
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ public class AminatouTheFateShifter extends CardImpl {
|
||||||
// Aminatou, the Fateshifter can be your commander.
|
// Aminatou, the Fateshifter can be your commander.
|
||||||
this.addAbility(CanBeYourCommanderAbility.getInstance());
|
this.addAbility(CanBeYourCommanderAbility.getInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
public AminatouTheFateShifter(final AminatouTheFateShifter card) {
|
public AminatouTheFateShifter(final AminatouTheFateShifter card) {
|
||||||
super(card);
|
super(card);
|
||||||
}
|
}
|
||||||
|
@ -79,6 +80,7 @@ public class AminatouTheFateShifter extends CardImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
class AminatouPlusEffect extends OneShotEffect {
|
class AminatouPlusEffect extends OneShotEffect {
|
||||||
|
|
||||||
public AminatouPlusEffect() {
|
public AminatouPlusEffect() {
|
||||||
super(Outcome.DrawCard);
|
super(Outcome.DrawCard);
|
||||||
staticText = "draw a card, then put a card from your hand on top of your library";
|
staticText = "draw a card, then put a card from your hand on top of your library";
|
||||||
|
@ -118,10 +120,11 @@ class AminatouPlusEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
|
|
||||||
class AminatouUltimateEffect extends OneShotEffect {
|
class AminatouUltimateEffect extends OneShotEffect {
|
||||||
public AminatouUltimateEffect (){
|
|
||||||
|
public AminatouUltimateEffect() {
|
||||||
super(Outcome.Benefit);
|
super(Outcome.Benefit);
|
||||||
staticText = "Choose left or right. Each player gains control of all nonland permanents other than Aminatou," +
|
staticText = "Choose left or right. Each player gains control of all nonland permanents other than Aminatou,"
|
||||||
" the Fateshifter controlled by the next player in the chosen direction.";
|
+ " the Fateshifter controlled by the next player in the chosen direction.";
|
||||||
}
|
}
|
||||||
|
|
||||||
public AminatouUltimateEffect(final AminatouUltimateEffect effect) {
|
public AminatouUltimateEffect(final AminatouUltimateEffect effect) {
|
||||||
|
@ -129,7 +132,9 @@ class AminatouUltimateEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AminatouUltimateEffect copy(){return new AminatouUltimateEffect(this);}
|
public AminatouUltimateEffect copy() {
|
||||||
|
return new AminatouUltimateEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
|
@ -154,7 +159,7 @@ class AminatouUltimateEffect extends OneShotEffect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// skip players out of range
|
// skip players out of range
|
||||||
if (!game.getState().getPlayersInRange(controller.getId(), game).contains(nextPlayer)){
|
if (!game.getState().getPlayersInRange(controller.getId(), game).contains(nextPlayer)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// save first next player to check for iteration stop
|
// save first next player to check for iteration stop
|
||||||
|
@ -164,7 +169,7 @@ class AminatouUltimateEffect extends OneShotEffect {
|
||||||
FilterNonlandPermanent nextPlayerNonlandPermanentsFilter = new FilterNonlandPermanent();
|
FilterNonlandPermanent nextPlayerNonlandPermanentsFilter = new FilterNonlandPermanent();
|
||||||
nextPlayerNonlandPermanentsFilter.add(new ControllerIdPredicate(nextPlayer));
|
nextPlayerNonlandPermanentsFilter.add(new ControllerIdPredicate(nextPlayer));
|
||||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(nextPlayerNonlandPermanentsFilter, game)) {
|
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(nextPlayerNonlandPermanentsFilter, game)) {
|
||||||
if (permanent.getId().equals(source.getSourceId())){
|
if (permanent.getId().equals(source.getSourceId())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfGame, currentPlayer);
|
ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfGame, currentPlayer);
|
||||||
|
@ -188,4 +193,3 @@ class AminatouUltimateEffect extends OneShotEffect {
|
||||||
return nextPlayerId;
|
return nextPlayerId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,34 +1,23 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.MageObject;
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
|
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.common.ZoneChangeTriggeredAbility;
|
import mage.abilities.effects.common.ExileTargetForSourceEffect;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
|
||||||
import mage.abilities.effects.common.ReturnFromExileForSourceEffect;
|
import mage.abilities.effects.common.ReturnFromExileForSourceEffect;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
import mage.cards.Card;
|
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Outcome;
|
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.filter.FilterCard;
|
|
||||||
import mage.filter.common.FilterCreatureCard;
|
import mage.filter.common.FilterCreatureCard;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.predicate.Predicates;
|
||||||
import mage.filter.predicate.permanent.AnotherPredicate;
|
import mage.filter.predicate.mageobject.CardIdPredicate;
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.events.GameEvent;
|
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.players.Player;
|
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.target.common.TargetCardInGraveyard;
|
import mage.target.common.TargetCardInGraveyardOrBattlefield;
|
||||||
import mage.target.common.TargetCreaturePermanent;
|
|
||||||
import mage.util.CardUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -36,8 +25,10 @@ import mage.util.CardUtil;
|
||||||
*/
|
*/
|
||||||
public final class AngelOfSerenity extends CardImpl {
|
public final class AngelOfSerenity extends CardImpl {
|
||||||
|
|
||||||
|
private static final String rule = "you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards.";
|
||||||
|
|
||||||
public AngelOfSerenity(UUID ownerId, CardSetInfo setInfo) {
|
public AngelOfSerenity(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{W}{W}{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}{W}");
|
||||||
this.subtype.add(SubType.ANGEL);
|
this.subtype.add(SubType.ANGEL);
|
||||||
|
|
||||||
this.power = new MageInt(5);
|
this.power = new MageInt(5);
|
||||||
|
@ -47,7 +38,12 @@ public final class AngelOfSerenity extends CardImpl {
|
||||||
this.addAbility(FlyingAbility.getInstance());
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
// When Angel of Serenity enters the battlefield, you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards.
|
// When Angel of Serenity enters the battlefield, you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards.
|
||||||
this.addAbility(new AngelOfSerenityTriggeredAbility());
|
FilterCreatureCard filter = new FilterCreatureCard("creatures from the battlefield and/or a graveyard");
|
||||||
|
filter.add(Predicates.not(new CardIdPredicate(this.getId())));
|
||||||
|
Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetForSourceEffect().setText(rule), true);
|
||||||
|
Target target = new TargetCardInGraveyardOrBattlefield(0, 3, filter);
|
||||||
|
ability.addTarget(target);
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
// When Angel of Serenity leaves the battlefield, return the exiled cards to their owners' hands.
|
// When Angel of Serenity leaves the battlefield, return the exiled cards to their owners' hands.
|
||||||
this.addAbility(new LeavesBattlefieldTriggeredAbility(new ReturnFromExileForSourceEffect(Zone.HAND, false, true), false));
|
this.addAbility(new LeavesBattlefieldTriggeredAbility(new ReturnFromExileForSourceEffect(Zone.HAND, false, true), false));
|
||||||
|
@ -62,92 +58,3 @@ public final class AngelOfSerenity extends CardImpl {
|
||||||
return new AngelOfSerenity(this);
|
return new AngelOfSerenity(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AngelOfSerenityTriggeredAbility extends ZoneChangeTriggeredAbility {
|
|
||||||
|
|
||||||
public AngelOfSerenityTriggeredAbility() {
|
|
||||||
super(Zone.BATTLEFIELD, new AngelOfSerenityEnterEffect(), "When {this} enters the battlefield, ", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AngelOfSerenityTriggeredAbility(AngelOfSerenityTriggeredAbility ability) {
|
|
||||||
super(ability);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
|
||||||
if (super.checkTrigger(event, game)) {
|
|
||||||
getTargets().clear();
|
|
||||||
FilterCreaturePermanent filter = new FilterCreaturePermanent("up to three other target creatures");
|
|
||||||
filter.add(new AnotherPredicate());
|
|
||||||
TargetCreaturePermanent target1 = new TargetCreaturePermanent(0, 3, filter, false);
|
|
||||||
game.getPlayer(getControllerId()).chooseTarget(Outcome.Exile, target1, this, game);
|
|
||||||
if (!target1.getTargets().isEmpty()) {
|
|
||||||
getTargets().add(target1);
|
|
||||||
|
|
||||||
}
|
|
||||||
int leftTargets = 3 - target1.getTargets().size();
|
|
||||||
if (leftTargets > 0) {
|
|
||||||
FilterCard filter2 = new FilterCreatureCard("up to " + leftTargets + " target creature card" + (leftTargets > 1 ? "s" : "") + " from graveyards");
|
|
||||||
TargetCardInGraveyard target2 = new TargetCardInGraveyard(0, leftTargets, filter2);
|
|
||||||
game.getPlayer(getControllerId()).chooseTarget(Outcome.Exile, target2, this, game);
|
|
||||||
if (!target2.getTargets().isEmpty()) {
|
|
||||||
getTargets().add(target2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AngelOfSerenityTriggeredAbility copy() {
|
|
||||||
return new AngelOfSerenityTriggeredAbility(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class AngelOfSerenityEnterEffect extends OneShotEffect {
|
|
||||||
|
|
||||||
public AngelOfSerenityEnterEffect() {
|
|
||||||
super(Outcome.ReturnToHand);
|
|
||||||
this.staticText = "you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards";
|
|
||||||
}
|
|
||||||
|
|
||||||
public AngelOfSerenityEnterEffect(final AngelOfSerenityEnterEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AngelOfSerenityEnterEffect copy() {
|
|
||||||
return new AngelOfSerenityEnterEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
boolean result = true;
|
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
|
||||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
|
||||||
if (controller != null && sourceObject != null && !source.getTargets().isEmpty()) {
|
|
||||||
UUID exileZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
|
|
||||||
for (Target target : source.getTargets()) {
|
|
||||||
if (target instanceof TargetCreaturePermanent) {
|
|
||||||
for (UUID permanentId : target.getTargets()) {
|
|
||||||
Permanent permanent = game.getPermanent(permanentId);
|
|
||||||
if (permanent != null) {
|
|
||||||
result |= controller.moveCardToExileWithInfo(permanent, exileZoneId, sourceObject.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (target instanceof TargetCardInGraveyard) {
|
|
||||||
for (UUID cardId : target.getTargets()) {
|
|
||||||
Card card = game.getCard(cardId);
|
|
||||||
if (card != null) {
|
|
||||||
result |= controller.moveCardToExileWithInfo(card, exileZoneId, sourceObject.getIdName(), source.getSourceId(), game, Zone.GRAVEYARD, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
67
Mage.Sets/src/mage/cards/a/ArcheryTraining.java
Normal file
67
Mage.Sets/src/mage/cards/a/ArcheryTraining.java
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
package mage.cards.a;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
|
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||||
|
import mage.abilities.effects.common.AttachEffect;
|
||||||
|
import mage.abilities.effects.common.DamageTargetEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
|
||||||
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
import mage.abilities.keyword.EnchantAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.AttachmentType;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.TargetController;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.counters.CounterType;
|
||||||
|
import mage.target.common.TargetAttackingOrBlockingCreature;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeffwadsworth
|
||||||
|
*/
|
||||||
|
public final class ArcheryTraining extends CardImpl {
|
||||||
|
|
||||||
|
private static final String rule = "This creature deals X damage to target attacking or blocking creature, where X is the number of arrow counters on {this}.";
|
||||||
|
|
||||||
|
public ArcheryTraining(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.AURA);
|
||||||
|
|
||||||
|
// Enchant creature
|
||||||
|
TargetPermanent auraTarget = new TargetCreaturePermanent();
|
||||||
|
this.getSpellAbility().addTarget(auraTarget);
|
||||||
|
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
|
||||||
|
Ability ability = new EnchantAbility(auraTarget.getTargetName());
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
// At the beginning of your upkeep, you may put an arrow counter on Archery Training.
|
||||||
|
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
|
||||||
|
new AddCountersSourceEffect(CounterType.ARROW.createInstance(), true), TargetController.YOU, true));
|
||||||
|
|
||||||
|
// Enchanted creature has "{tap}: This creature deals X damage to target attacking or blocking creature, where X is the number of arrow counters on Archery Training."
|
||||||
|
Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new CountersSourceCount(CounterType.ARROW)).setText(rule), new TapSourceCost());
|
||||||
|
gainedAbility.addTarget(new TargetAttackingOrBlockingCreature());
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(gainedAbility, AttachmentType.AURA)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArcheryTraining(final ArcheryTraining card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArcheryTraining copy() {
|
||||||
|
return new ArcheryTraining(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,14 @@
|
||||||
|
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
|
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
|
||||||
import mage.abilities.effects.common.SkipNextCombatEffect;
|
import mage.abilities.effects.common.SkipCombatStepEffect;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,7 +18,7 @@ import mage.constants.SubType;
|
||||||
public final class BlindingAngel extends CardImpl {
|
public final class BlindingAngel extends CardImpl {
|
||||||
|
|
||||||
public BlindingAngel(UUID ownerId, CardSetInfo setInfo) {
|
public BlindingAngel(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}");
|
||||||
this.subtype.add(SubType.ANGEL);
|
this.subtype.add(SubType.ANGEL);
|
||||||
|
|
||||||
this.power = new MageInt(2);
|
this.power = new MageInt(2);
|
||||||
|
@ -26,8 +26,10 @@ public final class BlindingAngel extends CardImpl {
|
||||||
|
|
||||||
// Flying
|
// Flying
|
||||||
this.addAbility(FlyingAbility.getInstance());
|
this.addAbility(FlyingAbility.getInstance());
|
||||||
|
|
||||||
// Whenever Blinding Angel deals combat damage to a player, that player skips their next combat phase.
|
// Whenever Blinding Angel deals combat damage to a player, that player skips their next combat phase.
|
||||||
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new SkipNextCombatEffect(), false, true));
|
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new SkipCombatStepEffect(Duration.OneUse).setText("that player skips their next combat phase."), false, true));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlindingAngel(final BlindingAngel card) {
|
public BlindingAngel(final BlindingAngel card) {
|
||||||
|
|
91
Mage.Sets/src/mage/cards/b/BronzeHorse.java
Normal file
91
Mage.Sets/src/mage/cards/b/BronzeHorse.java
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
|
||||||
|
package mage.cards.b;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.Mode;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||||
|
import mage.abilities.decorator.ConditionalReplacementEffect;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.common.PreventAllDamageToSourceEffect;
|
||||||
|
import mage.abilities.keyword.TrampleAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.stack.Spell;
|
||||||
|
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||||
|
import mage.filter.predicate.permanent.AnotherPredicate;
|
||||||
|
import mage.target.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author L_J
|
||||||
|
*/
|
||||||
|
public final class BronzeHorse extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(new AnotherPredicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public BronzeHorse(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT, CardType.CREATURE},"{7}");
|
||||||
|
this.subtype.add(SubType.HORSE);
|
||||||
|
this.power = new MageInt(4);
|
||||||
|
this.toughness = new MageInt(4);
|
||||||
|
|
||||||
|
// Trample
|
||||||
|
this.addAbility(TrampleAbility.getInstance());
|
||||||
|
|
||||||
|
// As long as you control another creature, prevent all damage that would be dealt to Bronze Horse by spells that target it.
|
||||||
|
Effect effect = new ConditionalReplacementEffect(new PreventDamageToSourceBySpellsThatTargetIt(), new PermanentsOnTheBattlefieldCondition(filter));
|
||||||
|
effect.setText("As long as you control another creature, prevent all damage that would be dealt to {this} by spells that target it.");
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
|
||||||
|
}
|
||||||
|
|
||||||
|
public BronzeHorse(final BronzeHorse card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BronzeHorse copy() {
|
||||||
|
return new BronzeHorse(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PreventDamageToSourceBySpellsThatTargetIt extends PreventAllDamageToSourceEffect {
|
||||||
|
|
||||||
|
public PreventDamageToSourceBySpellsThatTargetIt() {
|
||||||
|
super(Duration.WhileOnBattlefield);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||||
|
if (super.applies(event, source, game)) {
|
||||||
|
if (event.getTargetId().equals(source.getSourceId())) {
|
||||||
|
Spell spell = game.getStack().getSpell(event.getSourceId());
|
||||||
|
if (spell != null) {
|
||||||
|
for (UUID modeId : spell.getStackAbility().getModes().getSelectedModes()) {
|
||||||
|
Mode mode = spell.getStackAbility().getModes().get(modeId);
|
||||||
|
for (Target target : mode.getTargets()) {
|
||||||
|
for (UUID targetId : target.getTargets()) {
|
||||||
|
if (targetId.equals(source.getSourceId())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
52
Mage.Sets/src/mage/cards/c/CanalDredger.java
Normal file
52
Mage.Sets/src/mage/cards/c/CanalDredger.java
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
|
||||||
|
package mage.cards.c;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
|
import mage.abilities.effects.common.InfoEffect;
|
||||||
|
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.target.common.TargetCardInYourGraveyard;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author L_J
|
||||||
|
*/
|
||||||
|
public final class CanalDredger extends CardImpl {
|
||||||
|
|
||||||
|
public CanalDredger(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}");
|
||||||
|
this.subtype.add(SubType.CONSTRUCT);
|
||||||
|
this.power = new MageInt(1);
|
||||||
|
this.toughness = new MageInt(5);
|
||||||
|
|
||||||
|
// TODO: Draft specific abilities not implemented
|
||||||
|
// Draft Canal Dredger face up.
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("Draft Canal Dredger face up.")));
|
||||||
|
|
||||||
|
// Each player passes the last card from each booster pack to a player who drafted a card named Canal Dredger.
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("Each player passes the last card from each booster pack to a player who drafted a card named Canal Dredger.")));
|
||||||
|
|
||||||
|
// {T}: Put target card from your graveyard on the bottom of your library.
|
||||||
|
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutOnLibraryTargetEffect(false), new TapSourceCost());
|
||||||
|
ability.addTarget(new TargetCardInYourGraveyard());
|
||||||
|
this.addAbility(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CanalDredger(final CanalDredger card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CanalDredger copy() {
|
||||||
|
return new CanalDredger(this);
|
||||||
|
}
|
||||||
|
}
|
93
Mage.Sets/src/mage/cards/c/Contempt.java
Normal file
93
Mage.Sets/src/mage/cards/c/Contempt.java
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
package mage.cards.c;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.AttacksAttachedTriggeredAbility;
|
||||||
|
import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.AttachEffect;
|
||||||
|
import mage.abilities.effects.common.ReturnToHandSourceEffect;
|
||||||
|
import mage.abilities.effects.common.ReturnToHandTargetEffect;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
import mage.abilities.keyword.EnchantAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.target.targetpointer.FixedTarget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeffwadsworth
|
||||||
|
*/
|
||||||
|
public final class Contempt extends CardImpl {
|
||||||
|
|
||||||
|
public Contempt(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.AURA);
|
||||||
|
|
||||||
|
// Enchant creature
|
||||||
|
TargetPermanent auraTarget = new TargetCreaturePermanent();
|
||||||
|
this.getSpellAbility().addTarget(auraTarget);
|
||||||
|
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
|
||||||
|
Ability ability = new EnchantAbility(auraTarget.getTargetName());
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
// Whenever enchanted creature attacks, return it and Contempt to their owners' hands at end of combat.
|
||||||
|
this.addAbility(new AttacksAttachedTriggeredAbility(new ContemptEffect()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Contempt(final Contempt card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Contempt copy() {
|
||||||
|
return new Contempt(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ContemptEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
ContemptEffect() {
|
||||||
|
super(Outcome.Detriment);
|
||||||
|
this.staticText = "return it and {this} to their owners' hands at end of combat.";
|
||||||
|
}
|
||||||
|
|
||||||
|
ContemptEffect(final ContemptEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContemptEffect copy() {
|
||||||
|
return new ContemptEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Permanent contempt = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||||
|
if (contempt != null) {
|
||||||
|
Permanent attachedToPermanent = game.getPermanent(contempt.getAttachedTo());
|
||||||
|
if (attachedToPermanent != null) {
|
||||||
|
Effect effect = new ReturnToHandTargetEffect();
|
||||||
|
effect.setTargetPointer(new FixedTarget(
|
||||||
|
attachedToPermanent.getId())).setText("return "
|
||||||
|
+ attachedToPermanent.getName() + " to owner's hand.");
|
||||||
|
AtTheEndOfCombatDelayedTriggeredAbility ability = new AtTheEndOfCombatDelayedTriggeredAbility(effect);
|
||||||
|
game.addDelayedTriggeredAbility(ability, source);
|
||||||
|
}
|
||||||
|
Effect effect = new ReturnToHandSourceEffect();
|
||||||
|
AtTheEndOfCombatDelayedTriggeredAbility ability = new AtTheEndOfCombatDelayedTriggeredAbility(effect);
|
||||||
|
game.addDelayedTriggeredAbility(ability, source);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
50
Mage.Sets/src/mage/cards/d/DealBroker.java
Normal file
50
Mage.Sets/src/mage/cards/d/DealBroker.java
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
|
||||||
|
package mage.cards.d;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
|
import mage.abilities.effects.common.DrawDiscardControllerEffect;
|
||||||
|
import mage.abilities.effects.common.InfoEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author L_J
|
||||||
|
*/
|
||||||
|
public final class DealBroker extends CardImpl {
|
||||||
|
|
||||||
|
public DealBroker(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT, CardType.CREATURE},"{3}");
|
||||||
|
this.subtype.add(SubType.CONSTRUCT);
|
||||||
|
this.power = new MageInt(2);
|
||||||
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
|
// TODO: Draft specific abilities not implemented
|
||||||
|
// Draft Deal Broker face up.
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("Draft Deal Broker face up.")));
|
||||||
|
|
||||||
|
// Immediately after the draft, you may reveal a card in your card pool. Each other player may offer you one card in their card pool in exchange. You may accept any one offer.
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("Immediately after the draft, you may reveal a card in your card pool. "
|
||||||
|
+ "Each other player may offer you one card in their card pool in exchange. You may accept any one offer.")));
|
||||||
|
|
||||||
|
// {T}: Draw a card, then discard a card.
|
||||||
|
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawDiscardControllerEffect(), new TapSourceCost()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DealBroker(final DealBroker card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DealBroker copy() {
|
||||||
|
return new DealBroker(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
87
Mage.Sets/src/mage/cards/d/Disappear.java
Normal file
87
Mage.Sets/src/mage/cards/d/Disappear.java
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
package mage.cards.d;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.AttachEffect;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
import mage.abilities.keyword.EnchantAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.players.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeffwadsworth
|
||||||
|
*/
|
||||||
|
public final class Disappear extends CardImpl {
|
||||||
|
|
||||||
|
public Disappear(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{U}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.AURA);
|
||||||
|
|
||||||
|
// Enchant creature
|
||||||
|
TargetPermanent auraTarget = new TargetCreaturePermanent();
|
||||||
|
this.getSpellAbility().addTarget(auraTarget);
|
||||||
|
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
|
||||||
|
Ability ability = new EnchantAbility(auraTarget.getTargetName());
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
// {U}: Return enchanted creature and Disappear to their owners' hands.
|
||||||
|
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DisappearEffect(), new ManaCostsImpl("{U}")));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Disappear(final Disappear card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Disappear copy() {
|
||||||
|
return new Disappear(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DisappearEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
public DisappearEffect() {
|
||||||
|
super(Outcome.ReturnToHand);
|
||||||
|
staticText = "Return enchanted creature and {this} to their owners' hands";
|
||||||
|
}
|
||||||
|
|
||||||
|
public DisappearEffect(final DisappearEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DisappearEffect copy() {
|
||||||
|
return new DisappearEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Permanent aura = (Permanent) game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
if (controller != null
|
||||||
|
&& aura != null
|
||||||
|
&& aura.getAttachedTo() != null) {
|
||||||
|
Permanent enchantedCreature = game.getPermanent(aura.getAttachedTo());
|
||||||
|
controller.moveCards(aura, Zone.HAND, source, game);
|
||||||
|
if (enchantedCreature != null) {
|
||||||
|
controller.moveCards(enchantedCreature, Zone.HAND, source, game);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
200
Mage.Sets/src/mage/cards/d/Duplicity.java
Normal file
200
Mage.Sets/src/mage/cards/d/Duplicity.java
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
package mage.cards.d;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageObject;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.DelayedTriggeredAbility;
|
||||||
|
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||||
|
import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility;
|
||||||
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.discard.DiscardControllerEffect;
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.TargetController;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeffwadsworth
|
||||||
|
*/
|
||||||
|
public final class Duplicity extends CardImpl {
|
||||||
|
|
||||||
|
public Duplicity(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}{U}");
|
||||||
|
|
||||||
|
// When Duplicity enters the battlefield, exile the top five cards of your library face down.
|
||||||
|
this.addAbility(new EntersBattlefieldTriggeredAbility(new DuplicityEffect(), false));
|
||||||
|
|
||||||
|
// At the beginning of your upkeep, you may exile all cards from your hand face down. If you do, put all other cards you own exiled with Duplicity into your hand.
|
||||||
|
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DuplicityExileHandEffect(), TargetController.YOU, true));
|
||||||
|
|
||||||
|
// At the beginning of your end step, discard a card.
|
||||||
|
this.addAbility(new BeginningOfYourEndStepTriggeredAbility(new DiscardControllerEffect(1), false));
|
||||||
|
|
||||||
|
// When you lose control of Duplicity, put all cards exiled with Duplicity into their owner's graveyard.
|
||||||
|
this.addAbility(new LoseControlDuplicity());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Duplicity(final Duplicity card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Duplicity copy() {
|
||||||
|
return new Duplicity(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DuplicityEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
public DuplicityEffect() {
|
||||||
|
super(Outcome.Exile);
|
||||||
|
staticText = "exile the top five cards of your library face down";
|
||||||
|
}
|
||||||
|
|
||||||
|
public DuplicityEffect(final DuplicityEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||||
|
if (controller != null
|
||||||
|
&& sourceObject != null) {
|
||||||
|
if (controller.getLibrary().hasCards()) {
|
||||||
|
UUID exileId = CardUtil.getCardExileZoneId(game, source);
|
||||||
|
Set<Card> cardsToExile = controller.getLibrary().getTopCards(game, 5);
|
||||||
|
for (Card card : cardsToExile) {
|
||||||
|
controller.moveCardsToExile(card, source, game, true, exileId, sourceObject.getName());
|
||||||
|
card.setFaceDown(true, game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DuplicityEffect copy() {
|
||||||
|
return new DuplicityEffect(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DuplicityExileHandEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
public DuplicityExileHandEffect() {
|
||||||
|
super(Outcome.Exile);
|
||||||
|
staticText = "you may exile all cards from your hand face down. If you do, put all other cards you own exiled with {this} into your hand";
|
||||||
|
}
|
||||||
|
|
||||||
|
public DuplicityExileHandEffect(final DuplicityExileHandEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||||
|
if (controller != null
|
||||||
|
&& sourceObject != null) {
|
||||||
|
if (!controller.getHand().isEmpty()) {
|
||||||
|
UUID exileId = CardUtil.getCardExileZoneId(game, source);
|
||||||
|
Set<Card> cardsFromHandToExile = controller.getHand().getCards(game);
|
||||||
|
for (Card card : cardsFromHandToExile) {
|
||||||
|
controller.moveCardsToExile(card, source, game, true, exileId, sourceObject.getName());
|
||||||
|
card.setFaceDown(true, game);
|
||||||
|
}
|
||||||
|
Set<Card> cardsInExile = game.getExile().getExileZone(exileId).getCards(game);
|
||||||
|
Set<Card> cardsToReturnToHandFromExile = new HashSet<>();
|
||||||
|
for (Card card : cardsInExile) {
|
||||||
|
if (!cardsFromHandToExile.contains(card)) {
|
||||||
|
cardsToReturnToHandFromExile.add(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
controller.moveCards(cardsToReturnToHandFromExile, Zone.HAND, source, game);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DuplicityExileHandEffect copy() {
|
||||||
|
return new DuplicityExileHandEffect(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LoseControlDuplicity extends DelayedTriggeredAbility {
|
||||||
|
|
||||||
|
public LoseControlDuplicity() {
|
||||||
|
super(new PutExiledCardsInOwnersGraveyard(), Duration.EndOfGame, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoseControlDuplicity(final LoseControlDuplicity ability) {
|
||||||
|
super(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LoseControlDuplicity copy() {
|
||||||
|
return new LoseControlDuplicity(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkEventType(GameEvent event, Game game) {
|
||||||
|
return event.getType() == GameEvent.EventType.LOST_CONTROL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
|
return event.getPlayerId().equals(controllerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRule() {
|
||||||
|
return "When you lose control of {this}, put all cards exiled with {this} into their owner's graveyard.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PutExiledCardsInOwnersGraveyard extends OneShotEffect {
|
||||||
|
|
||||||
|
public PutExiledCardsInOwnersGraveyard() {
|
||||||
|
super(Outcome.Neutral);
|
||||||
|
staticText = " put all cards exiled with {this} into their owner's graveyard.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public PutExiledCardsInOwnersGraveyard(final PutExiledCardsInOwnersGraveyard effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||||
|
if (controller != null
|
||||||
|
&& sourceObject != null) {
|
||||||
|
UUID exileId = CardUtil.getCardExileZoneId(game, source);
|
||||||
|
Set<Card> cardsInExile = game.getExile().getExileZone(exileId).getCards(game);
|
||||||
|
controller.moveCardsToGraveyardWithInfo(cardsInExile, source, game, Zone.EXILED);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PutExiledCardsInOwnersGraveyard copy() {
|
||||||
|
return new PutExiledCardsInOwnersGraveyard(this);
|
||||||
|
}
|
||||||
|
}
|
102
Mage.Sets/src/mage/cards/e/ElderSpawn.java
Normal file
102
Mage.Sets/src/mage/cards/e/ElderSpawn.java
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
|
||||||
|
package mage.cards.e;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.ObjectColor;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||||
|
import mage.abilities.common.SimpleEvasionAbility;
|
||||||
|
import mage.abilities.costs.common.SacrificeTargetCost;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.TargetController;
|
||||||
|
import mage.filter.common.FilterControlledPermanent;
|
||||||
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||||
|
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.common.TargetControlledPermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author L_J
|
||||||
|
*/
|
||||||
|
public final class ElderSpawn extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("red creatures");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(new ColorPredicate(ObjectColor.RED));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ElderSpawn(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{U}{U}");
|
||||||
|
this.subtype.add(SubType.SPAWN);
|
||||||
|
this.power = new MageInt(6);
|
||||||
|
this.toughness = new MageInt(6);
|
||||||
|
|
||||||
|
// At the beginning of your upkeep, unless you sacrifice an Island, sacrifice Elder Spawn and it deals 6 damage to you.
|
||||||
|
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ElderSpawnEffect(), TargetController.YOU, false));
|
||||||
|
|
||||||
|
// Elder Spawn can't be blocked by red creatures.
|
||||||
|
this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ElderSpawn(final ElderSpawn card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElderSpawn copy() {
|
||||||
|
return new ElderSpawn(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ElderSpawnEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
private static final FilterControlledPermanent filter = new FilterControlledPermanent("an Island");
|
||||||
|
static {
|
||||||
|
filter.add(new SubtypePredicate(SubType.ISLAND));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ElderSpawnEffect() {
|
||||||
|
super(Outcome.Sacrifice);
|
||||||
|
staticText = "unless you sacrifice an Island, sacrifice {this} and it deals 6 damage to you";
|
||||||
|
}
|
||||||
|
|
||||||
|
public ElderSpawnEffect(final ElderSpawnEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElderSpawnEffect copy() {
|
||||||
|
return new ElderSpawnEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||||
|
if (controller != null && sourcePermanent != null) {
|
||||||
|
TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true);
|
||||||
|
SacrificeTargetCost cost = new SacrificeTargetCost(target);
|
||||||
|
if (!controller.chooseUse(Outcome.AIDontUseIt, "Do you wish to sacrifice an Island?", source, game)
|
||||||
|
|| !cost.canPay(source, source.getSourceId(), source.getControllerId(), game)
|
||||||
|
|| !cost.pay(source, game, source.getSourceId(), source.getControllerId(), true)) {
|
||||||
|
sourcePermanent.sacrifice(source.getSourceId(), game);
|
||||||
|
controller.damage(6, sourcePermanent.getId(), game, false, true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
|
|
||||||
package mage.cards.e;
|
package mage.cards.e;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.abilities.effects.common.SkipNextCombatEffect;
|
import mage.abilities.effects.common.SkipCombatStepEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
import mage.target.common.TargetOpponent;
|
import mage.target.common.TargetOpponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,10 +15,10 @@ import mage.target.common.TargetOpponent;
|
||||||
public final class EmptyCityRuse extends CardImpl {
|
public final class EmptyCityRuse extends CardImpl {
|
||||||
|
|
||||||
public EmptyCityRuse(UUID ownerId, CardSetInfo setInfo) {
|
public EmptyCityRuse(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}");
|
||||||
|
|
||||||
// Target opponent skips all combat phases of their next turn.
|
// Target opponent skips all combat phases of their next turn.
|
||||||
this.getSpellAbility().addEffect(new SkipNextCombatEffect());
|
this.getSpellAbility().addEffect(new SkipCombatStepEffect(Duration.UntilYourNextTurn).setText("Target opponent skips all combat phases of their next turn."));
|
||||||
this.getSpellAbility().addTarget(new TargetOpponent());
|
this.getSpellAbility().addTarget(new TargetOpponent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
79
Mage.Sets/src/mage/cards/e/EnchantedBeing.java
Normal file
79
Mage.Sets/src/mage/cards/e/EnchantedBeing.java
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
|
||||||
|
package mage.cards.e;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.MageObject;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.common.PreventAllDamageToSourceEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author L_J
|
||||||
|
*/
|
||||||
|
public final class EnchantedBeing extends CardImpl {
|
||||||
|
|
||||||
|
public EnchantedBeing(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{W}");
|
||||||
|
this.subtype.add(SubType.HUMAN);
|
||||||
|
this.power = new MageInt(2);
|
||||||
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
|
// Prevent all damage that would be dealt to Enchanted Being by enchanted creatures.
|
||||||
|
Effect effect = new PreventDamageToSourceByEnchantedCreatures();
|
||||||
|
effect.setText("Prevent all damage that would be dealt to {this} by enchanted creatures.");
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnchantedBeing(final EnchantedBeing card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnchantedBeing copy() {
|
||||||
|
return new EnchantedBeing(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PreventDamageToSourceByEnchantedCreatures extends PreventAllDamageToSourceEffect {
|
||||||
|
|
||||||
|
public PreventDamageToSourceByEnchantedCreatures() {
|
||||||
|
super(Duration.WhileOnBattlefield);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||||
|
if (super.applies(event, source, game)) {
|
||||||
|
if (isEnchantedCreature(game.getObject(event.getSourceId()), game)) {
|
||||||
|
if (event.getTargetId().equals(source.getSourceId())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnchantedCreature(MageObject input, Game game) {
|
||||||
|
if (input == null || input.isCreature()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (UUID attachmentId : ((Permanent) input).getAttachments()) {
|
||||||
|
Permanent attachment = game.getPermanent(attachmentId);
|
||||||
|
if (attachment != null && attachment.isEnchantment()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
|
|
||||||
package mage.cards.f;
|
package mage.cards.f;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.abilities.effects.common.SkipNextCombatEffect;
|
import mage.abilities.effects.common.SkipCombatStepEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
import mage.target.TargetPlayer;
|
import mage.target.TargetPlayer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,10 +15,10 @@ import mage.target.TargetPlayer;
|
||||||
public final class FalsePeace extends CardImpl {
|
public final class FalsePeace extends CardImpl {
|
||||||
|
|
||||||
public FalsePeace(UUID ownerId, CardSetInfo setInfo) {
|
public FalsePeace(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}");
|
||||||
|
|
||||||
// Target player skips all combat phases of their next turn.
|
// Target player skips all combat phases of their next turn.
|
||||||
this.getSpellAbility().addEffect(new SkipNextCombatEffect());
|
this.getSpellAbility().addEffect(new SkipCombatStepEffect(Duration.UntilYourNextTurn).setText("Target player skips all combat phases of their next turn."));
|
||||||
this.getSpellAbility().addTarget(new TargetPlayer());
|
this.getSpellAbility().addTarget(new TargetPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
36
Mage.Sets/src/mage/cards/f/Fatigue.java
Normal file
36
Mage.Sets/src/mage/cards/f/Fatigue.java
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package mage.cards.f;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.effects.common.SkipNextDrawStepTargetEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.target.TargetPlayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeffwadsworth
|
||||||
|
*/
|
||||||
|
public final class Fatigue extends CardImpl {
|
||||||
|
|
||||||
|
private static final String rule = "Target player skips his or her next draw step.";
|
||||||
|
|
||||||
|
public Fatigue(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}");
|
||||||
|
|
||||||
|
|
||||||
|
// Target player skips his or her next draw step.
|
||||||
|
this.getSpellAbility().addEffect(new SkipNextDrawStepTargetEffect().setText(rule));
|
||||||
|
this.getSpellAbility().addTarget(new TargetPlayer());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Fatigue(final Fatigue card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fatigue copy() {
|
||||||
|
return new Fatigue(this);
|
||||||
|
}
|
||||||
|
}
|
41
Mage.Sets/src/mage/cards/f/FendOff.java
Normal file
41
Mage.Sets/src/mage/cards/f/FendOff.java
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
package mage.cards.f;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.effects.common.PreventDamageByTargetEffect;
|
||||||
|
import mage.abilities.keyword.CyclingAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeffwadsworth
|
||||||
|
*/
|
||||||
|
public final class FendOff extends CardImpl {
|
||||||
|
|
||||||
|
private static final String rule = "Prevent all combat damage that would be dealt by target creature this turn.";
|
||||||
|
|
||||||
|
public FendOff(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");
|
||||||
|
|
||||||
|
// Prevent all combat damage that would be dealt by target creature this turn.
|
||||||
|
this.getSpellAbility().addEffect(new PreventDamageByTargetEffect(Duration.EndOfTurn, true).setText(rule));
|
||||||
|
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||||
|
|
||||||
|
// Cycling {2}
|
||||||
|
this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}")));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public FendOff(final FendOff card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FendOff copy() {
|
||||||
|
return new FendOff(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -156,8 +156,12 @@ class FlickerformReturnEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
ExileZone exileZone = game.getExile().getExileZone(exileZoneId);
|
ExileZone exileZone = game.getExile().getExileZone(exileZoneId);
|
||||||
Card enchantedCard = exileZone.get(enchantedCardId, game);
|
Card enchantedCard = exileZone.get(enchantedCardId, game);
|
||||||
|
//skip if exiled card is missing
|
||||||
if (enchantedCard != null) {
|
if (enchantedCard != null) {
|
||||||
controller.moveCards(enchantedCard, Zone.BATTLEFIELD, source, game);
|
Player owner = game.getPlayer(enchantedCard.getOwnerId());
|
||||||
|
//skip if card's owner is missing
|
||||||
|
if (owner != null) {
|
||||||
|
owner.moveCards(enchantedCard, Zone.BATTLEFIELD, source, game);
|
||||||
Permanent newPermanent = game.getPermanent(enchantedCardId);
|
Permanent newPermanent = game.getPermanent(enchantedCardId);
|
||||||
if (newPermanent != null) {
|
if (newPermanent != null) {
|
||||||
Set<Card> toBattlefieldAttached = new HashSet<Card>();
|
Set<Card> toBattlefieldAttached = new HashSet<Card>();
|
||||||
|
@ -190,6 +194,7 @@ class FlickerformReturnEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
91
Mage.Sets/src/mage/cards/f/ForethoughtAmulet.java
Normal file
91
Mage.Sets/src/mage/cards/f/ForethoughtAmulet.java
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
|
||||||
|
package mage.cards.f;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageObject;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||||
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
|
import mage.abilities.effects.ReplacementEffectImpl;
|
||||||
|
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.TargetController;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author L_J
|
||||||
|
*/
|
||||||
|
public final class ForethoughtAmulet extends CardImpl {
|
||||||
|
|
||||||
|
public ForethoughtAmulet(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
|
||||||
|
|
||||||
|
// At the beginning of your upkeep, sacrifice Forethought Amulet unless you pay {3}.
|
||||||
|
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new GenericManaCost(3)), TargetController.YOU, false));
|
||||||
|
|
||||||
|
// If an instant or sorcery source would deal 3 or more damage to you, it deals 2 damage to you instead.
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ForethoughtAmuletEffect()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ForethoughtAmulet(final ForethoughtAmulet card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ForethoughtAmulet copy() {
|
||||||
|
return new ForethoughtAmulet(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ForethoughtAmuletEffect extends ReplacementEffectImpl {
|
||||||
|
|
||||||
|
public ForethoughtAmuletEffect() {
|
||||||
|
super(Duration.WhileOnBattlefield, Outcome.Neutral);
|
||||||
|
staticText = "If an instant or sorcery source would deal 3 or more damage to you, it deals 2 damage to you instead";
|
||||||
|
}
|
||||||
|
|
||||||
|
public ForethoughtAmuletEffect(final ForethoughtAmuletEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ForethoughtAmuletEffect copy() {
|
||||||
|
return new ForethoughtAmuletEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checksEventType(GameEvent event, Game game) {
|
||||||
|
return event.getType() == GameEvent.EventType.DAMAGE_PLAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||||
|
if (event.getAmount() >= 3) {
|
||||||
|
MageObject object = game.getObject(event.getSourceId());
|
||||||
|
return object != null && (object.isInstant() || object.isSorcery());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||||
|
if (event.getTargetId().equals(source.getControllerId())) {
|
||||||
|
event.setAmount(2);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.g;
|
package mage.cards.g;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -16,7 +15,6 @@ import mage.constants.CardType;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.filter.StaticFilters;
|
import mage.filter.StaticFilters;
|
||||||
import mage.filter.common.FilterBasicLandCard;
|
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
@ -30,7 +28,7 @@ import mage.target.common.TargetLandPermanent;
|
||||||
public final class GhostQuarter extends CardImpl {
|
public final class GhostQuarter extends CardImpl {
|
||||||
|
|
||||||
public GhostQuarter(UUID ownerId, CardSetInfo setInfo) {
|
public GhostQuarter(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
|
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||||
|
|
||||||
// {T}: Add {C}.
|
// {T}: Add {C}.
|
||||||
this.addAbility(new ColorlessManaAbility());
|
this.addAbility(new ColorlessManaAbility());
|
||||||
|
|
|
@ -77,9 +77,9 @@ class GoblinMachinistEffect extends OneShotEffect {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
controller.revealCards(source, cards, game);
|
controller.revealCards(source, cards, game);
|
||||||
controller.putCardsOnBottomOfLibrary(cards, game, source, true);
|
controller.putCardsOnBottomOfLibrary(cards, game, source, true);
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -71,7 +71,10 @@ class HiddenPredatorsStateTriggeredAbility extends StateTriggeredAbility {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkInterveningIfClause(Game game) {
|
public boolean checkInterveningIfClause(Game game) {
|
||||||
return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT);
|
if (getSourcePermanentIfItStillExists(game) != null) {
|
||||||
|
return getSourcePermanentIfItStillExists(game).isEnchantment();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -59,15 +59,17 @@ class IcequakeEffect extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
|
||||||
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||||
if (permanent != null && controller != null) {
|
if (permanent != null) {
|
||||||
|
Player controller = game.getPlayer(permanent.getControllerId());
|
||||||
|
if(controller != null) {
|
||||||
permanent.destroy(source.getSourceId(), game, false);
|
permanent.destroy(source.getSourceId(), game, false);
|
||||||
if (permanent.isSnow()) {
|
if (permanent.isSnow()) {
|
||||||
controller.damage(1, source.getSourceId(), game, false, true);
|
controller.damage(1, source.getSourceId(), game, false, true);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
65
Mage.Sets/src/mage/cards/i/Incendiary.java
Normal file
65
Mage.Sets/src/mage/cards/i/Incendiary.java
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
package mage.cards.i;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||||
|
import mage.abilities.common.DiesAttachedTriggeredAbility;
|
||||||
|
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.common.AttachEffect;
|
||||||
|
import mage.abilities.effects.common.DamageTargetEffect;
|
||||||
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
import mage.abilities.keyword.EnchantAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.TargetController;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.counters.CounterType;
|
||||||
|
import mage.target.common.TargetCreatureOrPlayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeffwadsworth
|
||||||
|
*/
|
||||||
|
public final class Incendiary extends CardImpl {
|
||||||
|
|
||||||
|
private static final String rule = "{this} deals X damage to any target, where X is the number of fuse counters on {this}.";
|
||||||
|
|
||||||
|
public Incendiary(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.AURA);
|
||||||
|
|
||||||
|
// Enchant creature
|
||||||
|
TargetPermanent auraTarget = new TargetCreaturePermanent();
|
||||||
|
this.getSpellAbility().addTarget(auraTarget);
|
||||||
|
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
|
||||||
|
Ability ability = new EnchantAbility(auraTarget.getTargetName());
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
// At the beginning of your upkeep, you may put a fuse counter on Incendiary.
|
||||||
|
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
|
||||||
|
new AddCountersSourceEffect(CounterType.FUSE.createInstance(), true), TargetController.YOU, true));
|
||||||
|
|
||||||
|
// When enchanted creature dies, Incendiary deals X damage to any target, where X is the number of fuse counters on Incendiary.
|
||||||
|
Effect effect = new DamageTargetEffect(new CountersSourceCount(CounterType.FUSE)).setText(rule);
|
||||||
|
Ability ability2 = new DiesAttachedTriggeredAbility(effect, "enchanted creature");
|
||||||
|
ability.addTarget(new TargetCreatureOrPlayer());
|
||||||
|
this.addAbility(ability2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Incendiary(final Incendiary card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Incendiary copy() {
|
||||||
|
return new Incendiary(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
|
|
||||||
package mage.cards.j;
|
package mage.cards.j;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.MageObjectReference;
|
import mage.MageObjectReference;
|
||||||
|
@ -9,7 +10,6 @@ import mage.abilities.Ability;
|
||||||
import mage.abilities.DelayedTriggeredAbility;
|
import mage.abilities.DelayedTriggeredAbility;
|
||||||
import mage.abilities.LoyaltyAbility;
|
import mage.abilities.LoyaltyAbility;
|
||||||
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
|
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
|
||||||
import mage.abilities.effects.Effect;
|
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
|
@ -24,7 +24,10 @@ import mage.constants.SubType;
|
||||||
import mage.constants.SuperType;
|
import mage.constants.SuperType;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.filter.FilterCard;
|
import mage.filter.FilterCard;
|
||||||
|
import mage.filter.FilterPlayer;
|
||||||
import mage.filter.common.FilterNonlandCard;
|
import mage.filter.common.FilterNonlandCard;
|
||||||
|
import mage.filter.predicate.Predicates;
|
||||||
|
import mage.filter.predicate.other.PlayerIdPredicate;
|
||||||
import mage.game.ExileZone;
|
import mage.game.ExileZone;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
|
@ -32,6 +35,7 @@ import mage.game.events.GameEvent.EventType;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.TargetCard;
|
import mage.target.TargetCard;
|
||||||
|
import mage.target.TargetPlayer;
|
||||||
import mage.target.common.TargetCardInExile;
|
import mage.target.common.TargetCardInExile;
|
||||||
import mage.target.common.TargetCardInLibrary;
|
import mage.target.common.TargetCardInLibrary;
|
||||||
import mage.target.common.TargetOpponent;
|
import mage.target.common.TargetOpponent;
|
||||||
|
@ -119,9 +123,9 @@ class JaceArchitectOfThoughtDelayedTriggeredAbility extends DelayedTriggeredAbil
|
||||||
@Override
|
@Override
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
if (game.getOpponents(getControllerId()).contains(event.getPlayerId())) {
|
if (game.getOpponents(getControllerId()).contains(event.getPlayerId())) {
|
||||||
for (Effect effect : getEffects()) {
|
getEffects().forEach((effect) -> {
|
||||||
effect.setTargetPointer(new FixedTarget(event.getSourceId()));
|
effect.setTargetPointer(new FixedTarget(event.getSourceId()));
|
||||||
}
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -180,7 +184,6 @@ class JaceArchitectOfThoughtEffect2 extends OneShotEffect {
|
||||||
if (opponent == null) {
|
if (opponent == null) {
|
||||||
opponent = game.getPlayer(opponents.iterator().next());
|
opponent = game.getPlayer(opponents.iterator().next());
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetCard target = new TargetCard(0, allCards.size(), Zone.LIBRARY, new FilterCard("cards to put in the first pile"));
|
TargetCard target = new TargetCard(0, allCards.size(), Zone.LIBRARY, new FilterCard("cards to put in the first pile"));
|
||||||
target.setNotTarget(true);
|
target.setNotTarget(true);
|
||||||
opponent.choose(Outcome.Neutral, allCards, target, game);
|
opponent.choose(Outcome.Neutral, allCards, target, game);
|
||||||
|
@ -206,9 +209,9 @@ class JaceArchitectOfThoughtEffect2 extends OneShotEffect {
|
||||||
|
|
||||||
private void postPileToLog(String pileName, Set<Card> cards, Game game) {
|
private void postPileToLog(String pileName, Set<Card> cards, Game game) {
|
||||||
StringBuilder message = new StringBuilder(pileName).append(": ");
|
StringBuilder message = new StringBuilder(pileName).append(": ");
|
||||||
for (Card card : cards) {
|
cards.forEach((card) -> {
|
||||||
message.append(card.getName()).append(' ');
|
message.append(card.getName()).append(' ');
|
||||||
}
|
});
|
||||||
if (cards.isEmpty()) {
|
if (cards.isEmpty()) {
|
||||||
message.append(" (empty)");
|
message.append(" (empty)");
|
||||||
}
|
}
|
||||||
|
@ -239,30 +242,65 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect {
|
||||||
if (controller == null || sourcePermanent == null) {
|
if (controller == null || sourcePermanent == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
if (controller.chooseUse(Outcome.Benefit, "Look at all players' libraries before card select?", null, game)) {
|
||||||
|
game.informPlayers(controller.getLogName() + " is looking at all players' libraries.");
|
||||||
|
controller.lookAtAllLibraries(source, game);
|
||||||
|
}
|
||||||
|
List<UUID> playerList = new ArrayList<>();
|
||||||
|
playerList.addAll(game.getState().getPlayersInRange(controller.getId(), game));
|
||||||
|
Set<UUID> checkList = new HashSet<>();
|
||||||
|
while (!playerList.isEmpty()) {
|
||||||
|
FilterPlayer filter = new FilterPlayer();
|
||||||
|
List<PlayerIdPredicate> playerPredicates = new ArrayList<>();
|
||||||
|
playerList.forEach((playerId) -> {
|
||||||
|
playerPredicates.add(new PlayerIdPredicate(playerId));
|
||||||
|
});
|
||||||
|
filter.add(Predicates.or(playerPredicates));
|
||||||
|
TargetPlayer targetPlayer = new TargetPlayer(1, 1, true, filter);
|
||||||
|
targetPlayer.setRequired(!checkList.containsAll(playerList));
|
||||||
|
if (controller.chooseTarget(outcome, targetPlayer, source, game)) {
|
||||||
|
UUID playerId = targetPlayer.getFirstTarget();
|
||||||
Player player = game.getPlayer(playerId);
|
Player player = game.getPlayer(playerId);
|
||||||
|
if (player != null) {
|
||||||
String playerName = new StringBuilder(player.getLogName()).append("'s").toString();
|
String playerName = new StringBuilder(player.getLogName()).append("'s").toString();
|
||||||
if (source.isControlledBy(player.getId())) {
|
if (source.isControlledBy(player.getId())) {
|
||||||
playerName = "your";
|
playerName = "your";
|
||||||
}
|
}
|
||||||
TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString()));
|
TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString()));
|
||||||
if (controller.searchLibrary(target, game, playerId)) {
|
if (controller.searchLibrary(target, game, playerId, !checkList.contains(playerId))) {
|
||||||
|
checkList.add(playerId);
|
||||||
UUID targetId = target.getFirstTarget();
|
UUID targetId = target.getFirstTarget();
|
||||||
Card card = player.getLibrary().remove(targetId, game);
|
Card card = player.getLibrary().remove(targetId, game);
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true);
|
controller.moveCardsToExile(card, source, game, true, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getName());
|
||||||
|
playerList.remove(playerId);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
playerList.remove(playerId);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
playerList.remove(playerId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
playerList.stream().map((playerId) -> game.getPlayer(playerId)).filter((player) -> (player == null
|
||||||
|
|| !player.canRespond())).forEachOrdered((player) -> {
|
||||||
|
playerList.remove(player.getId());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
checkList.stream().map((playerId) -> game.getPlayer(playerId)).filter((player) -> (player != null)).forEachOrdered((player) -> {
|
||||||
player.shuffleLibrary(source, game);
|
player.shuffleLibrary(source, game);
|
||||||
}
|
});
|
||||||
|
|
||||||
ExileZone jaceExileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
ExileZone jaceExileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
||||||
if (jaceExileZone == null) {
|
if (jaceExileZone == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
FilterCard filter = new FilterCard("card to cast without mana costs");
|
FilterCard filter = new FilterCard("card to cast without mana costs");
|
||||||
TargetCardInExile target = new TargetCardInExile(filter, source.getSourceId());
|
TargetCardInExile target = new TargetCardInExile(filter, source.getSourceId());
|
||||||
while (jaceExileZone.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, jaceExileZone, target, game)) {
|
while (jaceExileZone.count(filter, game) > 0
|
||||||
|
&& controller.chooseUse(Outcome.Benefit, "Cast another spell from exile zone for free?", source, game)) {
|
||||||
|
controller.choose(Outcome.PlayForFree, jaceExileZone, target, game);
|
||||||
Card card = game.getCard(target.getFirstTarget());
|
Card card = game.getCard(target.getFirstTarget());
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
|
if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
|
||||||
|
|
49
Mage.Sets/src/mage/cards/k/KryShield.java
Normal file
49
Mage.Sets/src/mage/cards/k/KryShield.java
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
|
||||||
|
package mage.cards.k;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
|
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||||
|
import mage.abilities.dynamicvalue.common.TargetConvertedManaCost;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.common.PreventDamageByTargetEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.target.common.TargetControlledCreaturePermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author L_J
|
||||||
|
*/
|
||||||
|
public final class KryShield extends CardImpl {
|
||||||
|
|
||||||
|
public KryShield(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
|
||||||
|
|
||||||
|
// {2}, {T}: Prevent all damage that would be dealt this turn by target creature you control. That creature gets +0/+X until end of turn, where X is its converted mana cost.
|
||||||
|
Effect effect = new PreventDamageByTargetEffect(Duration.EndOfTurn);
|
||||||
|
effect.setText("Prevent all damage that would be dealt this turn by target creature you control");
|
||||||
|
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(2));
|
||||||
|
ability.addEffect(new BoostTargetEffect(new StaticValue(0), new TargetConvertedManaCost(), Duration.EndOfTurn, true)
|
||||||
|
.setText("That creature gets +0/+X until end of turn, where X is its converted mana cost"));
|
||||||
|
ability.addCost(new TapSourceCost());
|
||||||
|
ability.addTarget(new TargetControlledCreaturePermanent());
|
||||||
|
this.addAbility(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KryShield(final KryShield card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KryShield copy() {
|
||||||
|
return new KryShield(this);
|
||||||
|
}
|
||||||
|
}
|
130
Mage.Sets/src/mage/cards/l/LurkingJackals.java
Normal file
130
Mage.Sets/src/mage/cards/l/LurkingJackals.java
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
package mage.cards.l;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.StateTriggeredAbility;
|
||||||
|
import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.permanent.token.TokenImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeffwadsworth
|
||||||
|
*/
|
||||||
|
public final class LurkingJackals extends CardImpl {
|
||||||
|
|
||||||
|
public LurkingJackals(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}");
|
||||||
|
|
||||||
|
// When an opponent has 10 or less life, if Lurking Jackals is an enchantment, it becomes a 3/2 Hound creature.
|
||||||
|
this.addAbility(new LurkingJackalsStateTriggeredAbility());
|
||||||
|
}
|
||||||
|
|
||||||
|
public LurkingJackals(final LurkingJackals card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LurkingJackals copy() {
|
||||||
|
return new LurkingJackals(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LurkingJackalsStateTriggeredAbility extends StateTriggeredAbility {
|
||||||
|
|
||||||
|
public LurkingJackalsStateTriggeredAbility() {
|
||||||
|
super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new LurkingJackalsToken(), "", Duration.Custom, true, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public LurkingJackalsStateTriggeredAbility(final LurkingJackalsStateTriggeredAbility ability) {
|
||||||
|
super(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LurkingJackalsStateTriggeredAbility copy() {
|
||||||
|
return new LurkingJackalsStateTriggeredAbility(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
|
if (game.getOpponents(getControllerId()) != null) {
|
||||||
|
for (UUID opponentId : game.getOpponents(getControllerId())) {
|
||||||
|
if (game.getPlayer(opponentId).getLife() <= 10) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkInterveningIfClause(Game game) {
|
||||||
|
if (getSourcePermanentIfItStillExists(game) != null) {
|
||||||
|
return getSourcePermanentIfItStillExists(game).isEnchantment();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canTrigger(Game game) {
|
||||||
|
//20100716 - 603.8
|
||||||
|
Boolean triggered = (Boolean) game.getState().getValue(getSourceId().toString() + "triggered");
|
||||||
|
if (triggered == null) {
|
||||||
|
triggered = Boolean.FALSE;
|
||||||
|
}
|
||||||
|
return !triggered;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trigger(Game game, UUID controllerId) {
|
||||||
|
//20100716 - 603.8
|
||||||
|
game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.TRUE);
|
||||||
|
super.trigger(game, controllerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean resolve(Game game) {
|
||||||
|
//20100716 - 603.8
|
||||||
|
boolean result = super.resolve(game);
|
||||||
|
game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void counter(Game game) {
|
||||||
|
game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRule() {
|
||||||
|
return new StringBuilder("When an opponent has 10 or less life, if {this} is an enchantment, ").append(super.getRule()).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class LurkingJackalsToken extends TokenImpl {
|
||||||
|
|
||||||
|
public LurkingJackalsToken() {
|
||||||
|
super("Hound", "3/2 Hound creature");
|
||||||
|
cardType.add(CardType.CREATURE);
|
||||||
|
subtype.add(SubType.HOUND);
|
||||||
|
power = new MageInt(3);
|
||||||
|
toughness = new MageInt(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LurkingJackalsToken(final LurkingJackalsToken token) {
|
||||||
|
super(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LurkingJackalsToken copy() {
|
||||||
|
return new LurkingJackalsToken(this);
|
||||||
|
}
|
||||||
|
}
|
47
Mage.Sets/src/mage/cards/m/MetathranElite.java
Normal file
47
Mage.Sets/src/mage/cards/m/MetathranElite.java
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package mage.cards.m;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.condition.common.EnchantedSourceCondition;
|
||||||
|
import mage.abilities.decorator.ConditionalRestrictionEffect;
|
||||||
|
import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeffwadsworth
|
||||||
|
*/
|
||||||
|
public final class MetathranElite extends CardImpl {
|
||||||
|
|
||||||
|
private static final String rule = "{this} is unblockable as long as it's enchanted.";
|
||||||
|
|
||||||
|
public MetathranElite(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.METATHRAN);
|
||||||
|
this.subtype.add(SubType.SOLDIER);
|
||||||
|
this.power = new MageInt(2);
|
||||||
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
|
// Metathran Elite is unblockable as long as it's enchanted.
|
||||||
|
ConditionalRestrictionEffect effect = new ConditionalRestrictionEffect(
|
||||||
|
new CantBeBlockedSourceEffect(), new EnchantedSourceCondition());
|
||||||
|
effect.setText(rule);
|
||||||
|
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public MetathranElite(final MetathranElite card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MetathranElite copy() {
|
||||||
|
return new MetathranElite(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +1,10 @@
|
||||||
|
|
||||||
package mage.cards.m;
|
package mage.cards.m;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.cards.Card;
|
import mage.cards.*;
|
||||||
import mage.cards.CardImpl;
|
|
||||||
import mage.cards.CardSetInfo;
|
|
||||||
import mage.cards.Cards;
|
|
||||||
import mage.cards.CardsImpl;
|
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.filter.FilterCard;
|
import mage.filter.FilterCard;
|
||||||
|
@ -20,8 +13,11 @@ import mage.players.Player;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.target.common.TargetDiscard;
|
import mage.target.common.TargetDiscard;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
public final class MindBomb extends CardImpl {
|
public final class MindBomb extends CardImpl {
|
||||||
|
@ -67,6 +63,7 @@ class MindBombEffect extends OneShotEffect {
|
||||||
if (controller != null && sourceObject != null) {
|
if (controller != null && sourceObject != null) {
|
||||||
Map<UUID, Cards> cardsToDiscard = new HashMap<>();
|
Map<UUID, Cards> cardsToDiscard = new HashMap<>();
|
||||||
|
|
||||||
|
// choose
|
||||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||||
Player player = game.getPlayer(playerId);
|
Player player = game.getPlayer(playerId);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
|
@ -77,6 +74,8 @@ class MindBombEffect extends OneShotEffect {
|
||||||
cardsToDiscard.put(playerId, cards);
|
cardsToDiscard.put(playerId, cards);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// discard
|
||||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||||
Player player = game.getPlayer(playerId);
|
Player player = game.getPlayer(playerId);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
|
@ -91,31 +90,17 @@ class MindBombEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// damage
|
||||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||||
Player player = game.getPlayer(playerId);
|
Player player = game.getPlayer(playerId);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
Cards cardsPlayer = cardsToDiscard.get(playerId);
|
Cards cardsPlayer = cardsToDiscard.get(playerId);
|
||||||
if (cardsPlayer != null && !cardsPlayer.isEmpty()) {
|
if (cardsPlayer != null) {
|
||||||
player.damage(3 - cardsPlayer.size(), source.getId(), game, false, true);
|
player.damage(3 - cardsPlayer.size(), source.getId(), game, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// reveal the searched lands, put in hands, and shuffle
|
|
||||||
// for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
|
||||||
// Player player = game.getPlayer(playerId);
|
|
||||||
// if (player != null) {
|
|
||||||
// Cards cardsPlayer = cardsToReveal.get(playerId);
|
|
||||||
// if (cardsPlayer != null) {
|
|
||||||
// for (UUID cardId : cardsPlayer) {
|
|
||||||
// Cards cards = new CardsImpl(game.getCard(cardId));
|
|
||||||
// Card card = game.getCard(cardId);
|
|
||||||
// player.revealCards(sourceObject.getIdName() + " (" + player.getName() + ')', cards, game);
|
|
||||||
// player.moveCards(card, Zone.HAND, source, game);
|
|
||||||
// player.shuffleLibrary(source, game);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -10,10 +10,11 @@ import mage.constants.*;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import mage.abilities.effects.AsThoughManaEffect;
|
||||||
|
import mage.players.ManaPoolItem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
|
@ -69,17 +70,18 @@ class MnemonicBetrayalExileEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
Cards cards = new CardsImpl();
|
Cards cards = new CardsImpl();
|
||||||
Map<UUID, Integer> cardMap = new HashMap();
|
Map<UUID, Integer> cardMap = new HashMap();
|
||||||
for (UUID playerId : game.getOpponents(source.getControllerId())) {
|
game.getOpponents(source.getControllerId()).stream().map((playerId) -> game.getPlayer(playerId)).filter((player) -> (player != null)).forEachOrdered((player) -> {
|
||||||
Player player = game.getPlayer(playerId);
|
|
||||||
if (player != null) {
|
|
||||||
cards.addAll(player.getGraveyard());
|
cards.addAll(player.getGraveyard());
|
||||||
}
|
});
|
||||||
}
|
cards.getCards(game).stream().map((card) -> {
|
||||||
for (Card card : cards.getCards(game)) {
|
|
||||||
cardMap.put(card.getId(), card.getZoneChangeCounter(game));
|
cardMap.put(card.getId(), card.getZoneChangeCounter(game));
|
||||||
|
return card;
|
||||||
|
}).map((card) -> {
|
||||||
game.addEffect(new MnemonicBetrayalCastFromExileEffect(card, game), source);
|
game.addEffect(new MnemonicBetrayalCastFromExileEffect(card, game), source);
|
||||||
|
return card;
|
||||||
|
}).forEachOrdered((card) -> {
|
||||||
game.addEffect(new MnemonicBetrayalAnyColorEffect(card, game), source);
|
game.addEffect(new MnemonicBetrayalAnyColorEffect(card, game), source);
|
||||||
}
|
});
|
||||||
controller.moveCardsToExile(cards.getCards(game), source, game, true, source.getSourceId(), source.getSourceObjectIfItStillExists(game).getName());
|
controller.moveCardsToExile(cards.getCards(game), source, game, true, source.getSourceId(), source.getSourceObjectIfItStillExists(game).getName());
|
||||||
game.addDelayedTriggeredAbility(new MnemonicBetrayalDelayedTriggeredAbility(cards, cardMap), source);
|
game.addDelayedTriggeredAbility(new MnemonicBetrayalDelayedTriggeredAbility(cards, cardMap), source);
|
||||||
return true;
|
return true;
|
||||||
|
@ -125,7 +127,7 @@ class MnemonicBetrayalCastFromExileEffect extends AsThoughEffectImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MnemonicBetrayalAnyColorEffect extends AsThoughEffectImpl {
|
class MnemonicBetrayalAnyColorEffect extends AsThoughEffectImpl implements AsThoughManaEffect {
|
||||||
|
|
||||||
private final Card card;
|
private final Card card;
|
||||||
private final int zoneCounter;
|
private final int zoneCounter;
|
||||||
|
@ -154,13 +156,21 @@ class MnemonicBetrayalAnyColorEffect extends AsThoughEffectImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||||
if (card.getZoneChangeCounter(game) != zoneCounter) {
|
if (objectId.equals(card.getId())
|
||||||
|
&& card.getZoneChangeCounter(game) <= zoneCounter + 1
|
||||||
|
&& affectedControllerId.equals(source.getControllerId())) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (objectId.equals(card.getId())) {
|
||||||
this.discard();
|
this.discard();
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return objectId.equals(card.getId())
|
|
||||||
&& card.getZoneChangeCounter(game) == zoneCounter
|
@Override
|
||||||
&& affectedControllerId.equals(source.getControllerId());
|
public ManaType getAsThoughManaType(ManaType manaType, ManaPoolItem mana, UUID affectedControllerId, Ability source, Game game) {
|
||||||
|
return mana.getFirstAvailable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,12 +250,10 @@ class MnemonicBetrayalReturnEffect extends OneShotEffect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Cards cardsToReturn = new CardsImpl();
|
Cards cardsToReturn = new CardsImpl();
|
||||||
for (Card card : cards.getCards(game)) {
|
cards.getCards(game).stream().filter((card) -> (game.getState().getZone(card.getId()) == Zone.EXILED
|
||||||
if (game.getState().getZone(card.getId()) == Zone.EXILED
|
&& card.getZoneChangeCounter(game) == cardMap.getOrDefault(card.getId(), -5) + 1)).forEachOrdered((card) -> {
|
||||||
&& card.getZoneChangeCounter(game) == cardMap.getOrDefault(card.getId(), -5) + 1) {
|
|
||||||
cardsToReturn.add(card);
|
cardsToReturn.add(card);
|
||||||
}
|
});
|
||||||
}
|
|
||||||
return player.moveCards(cardsToReturn, Zone.GRAVEYARD, source, game);
|
return player.moveCards(cardsToReturn, Zone.GRAVEYARD, source, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
60
Mage.Sets/src/mage/cards/m/MoggBombers.java
Normal file
60
Mage.Sets/src/mage/cards/m/MoggBombers.java
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
package mage.cards.m;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.common.DamageTargetEffect;
|
||||||
|
import mage.abilities.effects.common.SacrificeSourceEffect;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
import mage.filter.predicate.permanent.AnotherPredicate;
|
||||||
|
import mage.target.TargetPlayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeffwadsworth
|
||||||
|
*/
|
||||||
|
public final class MoggBombers extends CardImpl {
|
||||||
|
|
||||||
|
private static final String rule = "When another creature enters the battlefield, sacrifice {this} and it deals 3 damage to target player.";
|
||||||
|
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(new AnotherPredicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public MoggBombers(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.GOBLIN);
|
||||||
|
this.power = new MageInt(3);
|
||||||
|
this.toughness = new MageInt(4);
|
||||||
|
|
||||||
|
// When another creature enters the battlefield, sacrifice Mogg Bombers and it deals 3 damage to target player.
|
||||||
|
Effect sacrificeMoggBombers = new SacrificeSourceEffect();
|
||||||
|
Effect damageTargetPlayer = new DamageTargetEffect(3);
|
||||||
|
Ability ability = new EntersBattlefieldAllTriggeredAbility(
|
||||||
|
Zone.BATTLEFIELD,
|
||||||
|
sacrificeMoggBombers,
|
||||||
|
filter, false, rule);
|
||||||
|
ability.addEffect(damageTargetPlayer);
|
||||||
|
ability.addTarget(new TargetPlayer());
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public MoggBombers(final MoggBombers card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoggBombers copy() {
|
||||||
|
return new MoggBombers(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
|
|
||||||
package mage.cards.m;
|
package mage.cards.m;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.abilities.effects.common.SkipNextCombatEffect;
|
import mage.abilities.effects.common.SkipCombatStepEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
import mage.target.TargetPlayer;
|
import mage.target.TargetPlayer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,10 +15,10 @@ import mage.target.TargetPlayer;
|
||||||
public final class MomentOfSilence extends CardImpl {
|
public final class MomentOfSilence extends CardImpl {
|
||||||
|
|
||||||
public MomentOfSilence(UUID ownerId, CardSetInfo setInfo) {
|
public MomentOfSilence(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}");
|
||||||
|
|
||||||
// Target player skips their next combat phase this turn.
|
// Target player skips their next combat phase this turn.
|
||||||
this.getSpellAbility().addEffect(new SkipNextCombatEffect());
|
this.getSpellAbility().addEffect(new SkipCombatStepEffect(Duration.EndOfTurn).setText("Target player skips their next combat this turn"));
|
||||||
this.getSpellAbility().addTarget(new TargetPlayer());
|
this.getSpellAbility().addTarget(new TargetPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,12 +54,18 @@ class OpalAvengerStateTriggeredAbility extends StateTriggeredAbility {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
|
if (game.getState().getPlayer(getControllerId()) != null) {
|
||||||
return game.getState().getPlayer(getControllerId()).getLife() <= 10;
|
return game.getState().getPlayer(getControllerId()).getLife() <= 10;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkInterveningIfClause(Game game) {
|
public boolean checkInterveningIfClause(Game game) {
|
||||||
return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT);
|
if (getSourcePermanentIfItStillExists(game) != null) {
|
||||||
|
return getSourcePermanentIfItStillExists(game).isEnchantment();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.o;
|
package mage.cards.o;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -30,12 +29,13 @@ public final class OuterRimSlaver extends CardImpl {
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
// When Outer Rim Slaver enters the battlefield, you may put a bounty counter on target creature. If you do, another target creature fights that creature
|
// When Outer Rim Slaver enters the battlefield, you may put a bounty counter on target creature. If you do, another target creature fights that creature
|
||||||
Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()), true);
|
Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.BOUNTY.createInstance())
|
||||||
ability.addEffect(new FightTargetsEffect("another target creature fights that creature"));
|
.setText("you may put a bounty counter on target creature"), true);
|
||||||
TargetCreaturePermanent target = new TargetCreaturePermanent();
|
ability.addEffect(new FightTargetsEffect("If you do, another target creature fights that creature"));
|
||||||
|
TargetCreaturePermanent target = new TargetCreaturePermanent(new FilterCreaturePermanent("creature to put a bounty counter on it"));
|
||||||
target.setTargetTag(1);
|
target.setTargetTag(1);
|
||||||
ability.addTarget(target);
|
ability.addTarget(target);
|
||||||
FilterCreaturePermanent filter = new FilterCreaturePermanent();
|
FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature to fight that creature that gets the bounty counter");
|
||||||
filter.add(new AnotherTargetPredicate(2));
|
filter.add(new AnotherTargetPredicate(2));
|
||||||
TargetCreaturePermanent target2 = new TargetCreaturePermanent(filter);
|
TargetCreaturePermanent target2 = new TargetCreaturePermanent(filter);
|
||||||
target2.setTargetTag(2);
|
target2.setTargetTag(2);
|
||||||
|
|
60
Mage.Sets/src/mage/cards/p/PrivateResearch.java
Normal file
60
Mage.Sets/src/mage/cards/p/PrivateResearch.java
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
package mage.cards.p;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||||
|
import mage.abilities.common.DiesAttachedTriggeredAbility;
|
||||||
|
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||||
|
import mage.abilities.effects.common.AttachEffect;
|
||||||
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
import mage.abilities.keyword.EnchantAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.TargetController;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.counters.CounterType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeffwadsworth
|
||||||
|
*/
|
||||||
|
public final class PrivateResearch extends CardImpl {
|
||||||
|
|
||||||
|
private static final String rule = "draw a card for each page counter on {this}.";
|
||||||
|
|
||||||
|
public PrivateResearch(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.AURA);
|
||||||
|
|
||||||
|
// Enchant creature
|
||||||
|
TargetPermanent auraTarget = new TargetCreaturePermanent();
|
||||||
|
this.getSpellAbility().addTarget(auraTarget);
|
||||||
|
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
|
||||||
|
Ability ability = new EnchantAbility(auraTarget.getTargetName());
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
// At the beginning of your upkeep, you may put a page counter on Private Research.
|
||||||
|
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
|
||||||
|
new AddCountersSourceEffect(CounterType.PAGE.createInstance(), true), TargetController.YOU, true));
|
||||||
|
|
||||||
|
// When enchanted creature dies, draw a card for each page counter on Private Research.
|
||||||
|
this.addAbility(new DiesAttachedTriggeredAbility(new DrawCardSourceControllerEffect(new CountersSourceCount(CounterType.PAGE)).setText(rule), "enchanted creature"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrivateResearch(final PrivateResearch card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PrivateResearch copy() {
|
||||||
|
return new PrivateResearch(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.p;
|
package mage.cards.p;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -11,8 +10,8 @@ import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.SubType;
|
||||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
@ -26,7 +25,7 @@ import mage.target.common.TargetControlledPermanent;
|
||||||
public final class ProwlingPangolin extends CardImpl {
|
public final class ProwlingPangolin extends CardImpl {
|
||||||
|
|
||||||
public ProwlingPangolin(UUID ownerId, CardSetInfo setInfo) {
|
public ProwlingPangolin(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
|
||||||
this.subtype.add(SubType.BEAST, SubType.PANGOLIN);
|
this.subtype.add(SubType.BEAST, SubType.PANGOLIN);
|
||||||
this.power = new MageInt(6);
|
this.power = new MageInt(6);
|
||||||
this.toughness = new MageInt(5);
|
this.toughness = new MageInt(5);
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.r;
|
package mage.cards.r;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -8,12 +7,13 @@ import mage.abilities.common.CantBlockAbility;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.condition.common.ManaWasSpentCondition;
|
import mage.abilities.condition.common.ManaWasSpentCondition;
|
||||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||||
import mage.abilities.effects.common.SkipNextCombatEffect;
|
import mage.abilities.effects.common.SkipCombatStepEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.ColoredManaSymbol;
|
import mage.constants.ColoredManaSymbol;
|
||||||
|
import mage.constants.Duration;
|
||||||
import mage.target.TargetPlayer;
|
import mage.target.TargetPlayer;
|
||||||
import mage.watchers.common.ManaSpentToCastWatcher;
|
import mage.watchers.common.ManaSpentToCastWatcher;
|
||||||
|
|
||||||
|
@ -24,13 +24,13 @@ import mage.watchers.common.ManaSpentToCastWatcher;
|
||||||
public final class RevenantPatriarch extends CardImpl {
|
public final class RevenantPatriarch extends CardImpl {
|
||||||
|
|
||||||
public RevenantPatriarch(UUID ownerId, CardSetInfo setInfo) {
|
public RevenantPatriarch(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
|
||||||
this.subtype.add(SubType.SPIRIT);
|
this.subtype.add(SubType.SPIRIT);
|
||||||
this.power = new MageInt(4);
|
this.power = new MageInt(4);
|
||||||
this.toughness = new MageInt(3);
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
// When Revenant Patriarch enters the battlefield, if {W} was spent to cast it, target player skips their next combat phase.
|
// When Revenant Patriarch enters the battlefield, if {W} was spent to cast it, target player skips their next combat phase.
|
||||||
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new SkipNextCombatEffect(), false);
|
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new SkipCombatStepEffect(Duration.OneUse).setText("target player skips their next combat phase."), false);
|
||||||
ability.addTarget(new TargetPlayer());
|
ability.addTarget(new TargetPlayer());
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new ManaWasSpentCondition(ColoredManaSymbol.W),
|
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new ManaWasSpentCondition(ColoredManaSymbol.W),
|
||||||
"if {W} was spent to cast it, target player skips their next combat phase."), new ManaSpentToCastWatcher());
|
"if {W} was spent to cast it, target player skips their next combat phase."), new ManaSpentToCastWatcher());
|
||||||
|
|
105
Mage.Sets/src/mage/cards/r/Reverberation.java
Normal file
105
Mage.Sets/src/mage/cards/r/Reverberation.java
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
|
||||||
|
package mage.cards.r;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.effects.ReplacementEffectImpl;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.filter.FilterSpell;
|
||||||
|
import mage.filter.predicate.mageobject.CardTypePredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.DamageEvent;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.stack.Spell;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.TargetSpell;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author L_J
|
||||||
|
*/
|
||||||
|
public final class Reverberation extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterSpell filter = new FilterSpell("sorcery spell");
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(new CardTypePredicate(CardType.SORCERY));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Reverberation(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{U}");
|
||||||
|
|
||||||
|
// All damage that would be dealt this turn by target sorcery spell is dealt to that spell’s controller instead.
|
||||||
|
this.getSpellAbility().addEffect(new ReverberationEffect());
|
||||||
|
this.getSpellAbility().addTarget(new TargetSpell(filter));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Reverberation(final Reverberation card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Reverberation copy() {
|
||||||
|
return new Reverberation(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReverberationEffect extends ReplacementEffectImpl {
|
||||||
|
|
||||||
|
public ReverberationEffect() {
|
||||||
|
super(Duration.EndOfTurn, Outcome.RedirectDamage);
|
||||||
|
staticText = "All damage that would be dealt this turn by target sorcery spell is dealt to that spell’s controller instead";
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReverberationEffect(final ReverberationEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReverberationEffect copy() {
|
||||||
|
return new ReverberationEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checksEventType(GameEvent event, Game game) {
|
||||||
|
return event.getType() == GameEvent.EventType.DAMAGE_CREATURE ||
|
||||||
|
event.getType() == GameEvent.EventType.DAMAGE_PLANESWALKER ||
|
||||||
|
event.getType() == GameEvent.EventType.DAMAGE_PLAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
DamageEvent damageEvent = (DamageEvent) event;
|
||||||
|
if (controller != null) {
|
||||||
|
Spell targetSpell = game.getStack().getSpell(source.getFirstTarget());
|
||||||
|
if (targetSpell != null) {
|
||||||
|
Player targetsController = game.getPlayer(targetSpell.getControllerId());
|
||||||
|
if (targetsController != null) {
|
||||||
|
targetsController.damage(damageEvent.getAmount(), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), damageEvent.getAppliedEffects());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||||
|
DamageEvent damageEvent = (DamageEvent) event;
|
||||||
|
Spell targetSpell = game.getStack().getSpell(source.getFirstTarget());
|
||||||
|
if (targetSpell != null) {
|
||||||
|
return damageEvent.getAmount() > 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
87
Mage.Sets/src/mage/cards/s/ScryingGlass.java
Normal file
87
Mage.Sets/src/mage/cards/s/ScryingGlass.java
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
package mage.cards.s;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.costs.common.TapSourceCost;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.choices.ChoiceColor;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.FilterCard;
|
||||||
|
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.common.TargetOpponent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeffwadsworth
|
||||||
|
*/
|
||||||
|
public final class ScryingGlass extends CardImpl {
|
||||||
|
|
||||||
|
public ScryingGlass(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
|
||||||
|
|
||||||
|
// {3}, {tap}: Choose a number greater than 0 and a color. Target opponent reveals his or her hand. If that opponent reveals exactly the chosen number of cards of the chosen color, you draw a card.
|
||||||
|
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ScryingGlassEffect(), new ManaCostsImpl("{3}"));
|
||||||
|
ability.addCost(new TapSourceCost());
|
||||||
|
ability.addTarget(new TargetOpponent());
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScryingGlass(final ScryingGlass card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScryingGlass copy() {
|
||||||
|
return new ScryingGlass(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ScryingGlassEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
public ScryingGlassEffect() {
|
||||||
|
super(Outcome.Neutral);
|
||||||
|
staticText = "Choose a number greater than 0 and a color. Target opponent reveals his or her hand. If that opponent reveals exactly the chosen number of cards of the chosen color, you draw a card";
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScryingGlassEffect(final ScryingGlassEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
Player targetOpponent = game.getPlayer(source.getFirstTarget());
|
||||||
|
ChoiceColor color = new ChoiceColor();
|
||||||
|
int amount = 0;
|
||||||
|
if (controller != null
|
||||||
|
&& targetOpponent != null) {
|
||||||
|
amount = controller.getAmount(1, Integer.MAX_VALUE, "Choose a number", game);
|
||||||
|
controller.choose(Outcome.Discard, color, game);
|
||||||
|
FilterCard filter = new FilterCard();
|
||||||
|
filter.add(new ColorPredicate(color.getColor()));
|
||||||
|
targetOpponent.revealCards(source, targetOpponent.getHand(), game);
|
||||||
|
if (targetOpponent.getHand().count(filter, game) == amount) {
|
||||||
|
game.informPlayers(controller.getName() + " has chosen the exact number and color of the revealed cards from " + targetOpponent.getName() + "'s hand. They draw a card.");
|
||||||
|
controller.drawCards(1, game);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
game.informPlayers(controller.getName() + " has chosen incorrectly and will not draw a card.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScryingGlassEffect copy() {
|
||||||
|
return new ScryingGlassEffect(this);
|
||||||
|
}
|
||||||
|
}
|
129
Mage.Sets/src/mage/cards/s/SkeletonScavengers.java
Normal file
129
Mage.Sets/src/mage/cards/s/SkeletonScavengers.java
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
package mage.cards.s;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.AsEntersBattlefieldAbility;
|
||||||
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
|
import mage.abilities.costs.Cost;
|
||||||
|
import mage.abilities.costs.CostImpl;
|
||||||
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
|
import mage.abilities.dynamicvalue.DynamicValue;
|
||||||
|
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.RegenerateSourceEffect;
|
||||||
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.counters.CounterType;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.players.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeffwadsworth
|
||||||
|
*/
|
||||||
|
public final class SkeletonScavengers extends CardImpl {
|
||||||
|
|
||||||
|
public SkeletonScavengers(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.SKELETON);
|
||||||
|
this.power = new MageInt(0);
|
||||||
|
this.toughness = new MageInt(0);
|
||||||
|
|
||||||
|
// Skeleton Scavengers enters the battlefield with a +1/+1 counter on it.
|
||||||
|
this.addAbility(new AsEntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance())));
|
||||||
|
|
||||||
|
// Pay {1} for each +1/+1 counter on Skeleton Scavengers: Regenerate Skeleton Scavengers. When it regenerates this way, put a +1/+1 counter on it.
|
||||||
|
this.addAbility(new SimpleActivatedAbility(new SkeletonScavengersEffect(), new DynamicValueGenericManaCost(new CountersSourceCount(CounterType.P1P1))));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public SkeletonScavengers(final SkeletonScavengers card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkeletonScavengers copy() {
|
||||||
|
return new SkeletonScavengers(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DynamicValueGenericManaCost extends CostImpl {
|
||||||
|
|
||||||
|
DynamicValue amount;
|
||||||
|
|
||||||
|
public DynamicValueGenericManaCost(DynamicValue amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
setText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DynamicValueGenericManaCost(DynamicValueGenericManaCost cost) {
|
||||||
|
super(cost);
|
||||||
|
this.amount = cost.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
|
||||||
|
Player controller = game.getPlayer(controllerId);
|
||||||
|
if (controller == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int convertedCost = amount.calculate(game, ability, null);
|
||||||
|
Cost cost = new GenericManaCost(convertedCost);
|
||||||
|
return cost.canPay(ability, sourceId, controllerId, game);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||||
|
Player controller = game.getPlayer(controllerId);
|
||||||
|
int convertedCost = amount.calculate(game, ability, null);
|
||||||
|
Cost cost = new GenericManaCost(convertedCost);
|
||||||
|
if (controller != null) {
|
||||||
|
paid = cost.pay(ability, game, sourceId, controllerId, noMana);
|
||||||
|
}
|
||||||
|
return paid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DynamicValueGenericManaCost copy() {
|
||||||
|
return new DynamicValueGenericManaCost(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setText() {
|
||||||
|
text = ("Pay {1} for each +1/+1 counter on {this}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SkeletonScavengersEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
SkeletonScavengersEffect() {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
this.staticText = "Regenerate {this}. When it regenerates this way, put a +1/+1 counter on it";
|
||||||
|
}
|
||||||
|
|
||||||
|
SkeletonScavengersEffect(final SkeletonScavengersEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkeletonScavengersEffect copy() {
|
||||||
|
return new SkeletonScavengersEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Permanent skeletonScavengers = game.getPermanent(source.getSourceId());
|
||||||
|
if (skeletonScavengers != null) {
|
||||||
|
if (new RegenerateSourceEffect().apply(game, source)) {
|
||||||
|
return new AddCountersSourceEffect(CounterType.P1P1.createInstance()).apply(game, source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package mage.cards.s;
|
package mage.cards.s;
|
||||||
|
|
||||||
import mage.abilities.costs.mana.VariableManaCost;
|
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
import mage.abilities.effects.common.DoUnlessAnyPlayerPaysEffect;
|
import mage.abilities.effects.common.DoUnlessAnyPlayerPaysEffect;
|
||||||
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
|
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
|
||||||
|
@ -11,6 +10,7 @@ import mage.filter.common.FilterCreatureCard;
|
||||||
import mage.target.common.TargetCardInYourGraveyard;
|
import mage.target.common.TargetCardInYourGraveyard;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author jmharmon
|
* @author jmharmon
|
||||||
|
@ -23,8 +23,7 @@ public final class SoulStrings extends CardImpl {
|
||||||
|
|
||||||
// Return two target creature cards from your graveyard to your hand unless any player pays {X}.
|
// Return two target creature cards from your graveyard to your hand unless any player pays {X}.
|
||||||
Effect effect = new DoUnlessAnyPlayerPaysEffect(
|
Effect effect = new DoUnlessAnyPlayerPaysEffect(
|
||||||
new ReturnFromGraveyardToHandTargetEffect(), new VariableManaCost()
|
new ReturnFromGraveyardToHandTargetEffect(), new ManacostVariableValue());
|
||||||
);
|
|
||||||
this.getSpellAbility().addEffect(effect);
|
this.getSpellAbility().addEffect(effect);
|
||||||
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(2, new FilterCreatureCard("creature cards from your graveyard")));
|
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(2, new FilterCreatureCard("creature cards from your graveyard")));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.s;
|
package mage.cards.s;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -65,21 +64,22 @@ class StadiumVendorsEffect extends OneShotEffect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Player controller = game.getPlayer(source.getSourceId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
if (controller == null) {
|
if (controller == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
TargetPlayer target = new TargetPlayer(1, 1, true);
|
TargetPlayer target = new TargetPlayer(1, 1, true);
|
||||||
if (!controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) {
|
if (controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Player player = game.getPlayer(target.getFirstTarget());
|
Player player = game.getPlayer(target.getFirstTarget());
|
||||||
ChoiceColor colorChoice = new ChoiceColor(true);
|
ChoiceColor colorChoice = new ChoiceColor(true);
|
||||||
if (player == null || !player.choose(Outcome.Benefit, colorChoice, game)) {
|
if (player == null
|
||||||
|
|| !player.choose(Outcome.Benefit, colorChoice, game)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Effect effect = new AddManaToManaPoolTargetControllerEffect(colorChoice.getMana(2), "that player's");
|
Effect effect = new AddManaToManaPoolTargetControllerEffect(colorChoice.getMana(2), "that player's");
|
||||||
effect.setTargetPointer(new FixedTarget(player.getId(), game));
|
effect.setTargetPointer(new FixedTarget(player.getId(), game));
|
||||||
return effect.apply(game, source);
|
return effect.apply(game, source);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
|
|
||||||
package mage.cards.s;
|
package mage.cards.s;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
import mage.abilities.effects.common.SkipNextCombatEffect;
|
import mage.abilities.effects.common.SkipCombatStepEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.target.common.TargetOpponent;
|
import mage.target.common.TargetOpponent;
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ import mage.target.common.TargetOpponent;
|
||||||
public final class StonehornDignitary extends CardImpl {
|
public final class StonehornDignitary extends CardImpl {
|
||||||
|
|
||||||
public StonehornDignitary(UUID ownerId, CardSetInfo setInfo) {
|
public StonehornDignitary(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
|
||||||
this.subtype.add(SubType.RHINO);
|
this.subtype.add(SubType.RHINO);
|
||||||
this.subtype.add(SubType.SOLDIER);
|
this.subtype.add(SubType.SOLDIER);
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ public final class StonehornDignitary extends CardImpl {
|
||||||
this.toughness = new MageInt(4);
|
this.toughness = new MageInt(4);
|
||||||
|
|
||||||
// When Stonehorn Dignitary enters the battlefield, target opponent skips their next combat phase.
|
// When Stonehorn Dignitary enters the battlefield, target opponent skips their next combat phase.
|
||||||
Ability ability = new EntersBattlefieldTriggeredAbility(new SkipNextCombatEffect());
|
Ability ability = new EntersBattlefieldTriggeredAbility(new SkipCombatStepEffect(Duration.OneUse).setText("target opponent skips their next combat phase."));
|
||||||
ability.addTarget(new TargetOpponent());
|
ability.addTarget(new TargetOpponent());
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
39
Mage.Sets/src/mage/cards/s/Subdue.java
Normal file
39
Mage.Sets/src/mage/cards/s/Subdue.java
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
package mage.cards.s;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||||
|
import mage.abilities.dynamicvalue.common.TargetConvertedManaCost;
|
||||||
|
import mage.abilities.effects.common.PreventDamageByTargetEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.Duration;
|
||||||
|
import mage.target.common.TargetCreaturePermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author L_J
|
||||||
|
*/
|
||||||
|
public final class Subdue extends CardImpl {
|
||||||
|
|
||||||
|
public Subdue(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}");
|
||||||
|
|
||||||
|
// Prevent all combat damage that would be dealt by target creature this turn. That creature gets +0/+X until end of turn, where X is its converted mana cost.
|
||||||
|
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||||
|
this.getSpellAbility().addEffect(new PreventDamageByTargetEffect(Duration.EndOfTurn, true));
|
||||||
|
this.getSpellAbility().addEffect(new BoostTargetEffect(new StaticValue(0), new TargetConvertedManaCost(), Duration.EndOfTurn, true)
|
||||||
|
.setText("That creature gets +0/+X until end of turn, where X is its converted mana cost"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Subdue(final Subdue card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Subdue copy() {
|
||||||
|
return new Subdue(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.t;
|
package mage.cards.t;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -13,7 +12,6 @@ import mage.constants.SagaChapter;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
import mage.constants.TargetController;
|
import mage.constants.TargetController;
|
||||||
import mage.filter.FilterCard;
|
import mage.filter.FilterCard;
|
||||||
import mage.filter.StaticFilters;
|
|
||||||
import mage.filter.common.FilterControlledPermanent;
|
import mage.filter.common.FilterControlledPermanent;
|
||||||
import mage.filter.predicate.Predicates;
|
import mage.filter.predicate.Predicates;
|
||||||
import mage.filter.predicate.mageobject.CardTypePredicate;
|
import mage.filter.predicate.mageobject.CardTypePredicate;
|
||||||
|
@ -35,6 +33,7 @@ public final class TheEldestReborn extends CardImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final FilterControlledPermanent filterSacrifice = new FilterControlledPermanent("creature or planeswalker");
|
private static final FilterControlledPermanent filterSacrifice = new FilterControlledPermanent("creature or planeswalker");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
filterSacrifice.add(Predicates.or(
|
filterSacrifice.add(Predicates.or(
|
||||||
new CardTypePredicate(CardType.CREATURE),
|
new CardTypePredicate(CardType.CREATURE),
|
||||||
|
|
|
@ -67,7 +67,10 @@ class VeiledCrocodileStateTriggeredAbility extends StateTriggeredAbility {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkInterveningIfClause(Game game) {
|
public boolean checkInterveningIfClause(Game game) {
|
||||||
return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT);
|
if (getSourcePermanentIfItStillExists(game) != null) {
|
||||||
|
return getSourcePermanentIfItStillExists(game).isEnchantment();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -79,7 +79,9 @@ class ViashinoBeyEffect extends OneShotEffect {
|
||||||
} else {
|
} else {
|
||||||
targetDefender.add(game.getOpponents(controller.getId()).iterator().next(), game);
|
targetDefender.add(game.getOpponents(controller.getId()).iterator().next(), game);
|
||||||
}
|
}
|
||||||
|
if (permanent.canAttack(targetDefender.getFirstTarget(), game)) {
|
||||||
controller.declareAttacker(permanent.getId(), targetDefender.getFirstTarget(), game, false);
|
controller.declareAttacker(permanent.getId(), targetDefender.getFirstTarget(), game, false);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
59
Mage.Sets/src/mage/cards/w/WalkingDream.java
Normal file
59
Mage.Sets/src/mage/cards/w/WalkingDream.java
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package mage.cards.w;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
import mage.abilities.condition.common.OpponentControlsPermanentCondition;
|
||||||
|
import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect;
|
||||||
|
import mage.abilities.effects.ContinuousRuleModifyingEffect;
|
||||||
|
import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect;
|
||||||
|
import mage.abilities.keyword.CantBeBlockedSourceAbility;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.ComparisonType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeffwadsworth
|
||||||
|
*/
|
||||||
|
public final class WalkingDream extends CardImpl {
|
||||||
|
|
||||||
|
private static final String rule = "{this} doesn't untap during your untap step if an opponent controls two or more creatures.";
|
||||||
|
|
||||||
|
public WalkingDream(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.ILLUSION);
|
||||||
|
this.power = new MageInt(3);
|
||||||
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
|
// Walking Dream is unblockable.
|
||||||
|
this.addAbility(new CantBeBlockedSourceAbility());
|
||||||
|
|
||||||
|
// Walking Dream doesn't untap during your untap step if an opponent controls two or more creatures.
|
||||||
|
ContinuousRuleModifyingEffect dontUntap = new DontUntapInControllersUntapStepSourceEffect(false, true);
|
||||||
|
dontUntap.setText(rule);
|
||||||
|
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD,
|
||||||
|
new ConditionalContinuousRuleModifyingEffect(
|
||||||
|
dontUntap,
|
||||||
|
new OpponentControlsPermanentCondition(
|
||||||
|
new FilterCreaturePermanent(),
|
||||||
|
ComparisonType.MORE_THAN, 1)));
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public WalkingDream(final WalkingDream card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WalkingDream copy() {
|
||||||
|
return new WalkingDream(this);
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue