mirror of
https://github.com/correl/mage.git
synced 2025-04-14 09:09:38 -09:00
Merge origin/master
This commit is contained in:
commit
02f6ce7639
67 changed files with 3282 additions and 278 deletions
Mage.Client/src
main/java
mage/client
MageFrame.java
constants
deckeditor
dialog
AddLandDialog.javaConnectDialog.javaMageDialog.javaNewTournamentDialog.javaPickChoiceDialog.javaPickNumberDialog.javaPickPileDialog.javaShowCardsDialog.java
game
util/stats
org/mage/card/arcane
test/java/mage/client/util
Mage.Sets/src/mage
cards
a
b
d
f
g
h
j
k
m
p
r
t
v
sets
Mage/src/main/java/mage
abilities
condition/common
decorator
effects
keyword
constants
counters
filter
game/permanent
watchers
Utils
|
@ -50,6 +50,7 @@ import mage.client.chat.ChatPanelBasic;
|
|||
import mage.client.components.*;
|
||||
import mage.client.components.ext.dlg.DialogManager;
|
||||
import mage.client.components.tray.MageTray;
|
||||
import mage.client.constants.Constants;
|
||||
import mage.client.constants.Constants.DeckEditorMode;
|
||||
import mage.client.deckeditor.DeckEditorPane;
|
||||
import mage.client.deckeditor.collection.viewer.CollectionViewerPane;
|
||||
|
@ -92,8 +93,6 @@ import org.mage.plugins.card.images.DownloadPictures;
|
|||
import org.mage.plugins.card.info.CardInfoPaneImpl;
|
||||
import org.mage.plugins.card.utils.impl.ImageManagerImpl;
|
||||
|
||||
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
@ -239,10 +238,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
SessionHandler.startSession(this);
|
||||
callbackClient = new CallbackClientImpl(this);
|
||||
connectDialog = new ConnectDialog();
|
||||
desktopPane.add(connectDialog, JLayeredPane.POPUP_LAYER);
|
||||
desktopPane.add(connectDialog, JLayeredPane.MODAL_LAYER);
|
||||
errorDialog = new ErrorDialog();
|
||||
errorDialog.setLocation(100, 100);
|
||||
desktopPane.add(errorDialog, JLayeredPane.POPUP_LAYER);
|
||||
desktopPane.add(errorDialog, JLayeredPane.MODAL_LAYER);
|
||||
UI.addComponent(MageComponents.DESKTOP_PANE, desktopPane);
|
||||
|
||||
PING_TASK_EXECUTOR.scheduleAtFixedRate(() -> SessionHandler.ping(), 60, 60, TimeUnit.SECONDS);
|
||||
|
@ -285,6 +284,9 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
balloonTip.setPositioner(new LeftAbovePositioner(0, 0));
|
||||
balloonTip.setVisible(false);
|
||||
|
||||
// tooltips delay in ms
|
||||
ToolTipManager.sharedInstance().setDismissDelay(Constants.TOOLTIPS_DELAY_MS);
|
||||
|
||||
mageToolbar.add(createSwitchPanelsButton(), 0);
|
||||
mageToolbar.add(new javax.swing.JToolBar.Separator(), 1);
|
||||
|
||||
|
@ -429,16 +431,21 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isChrismasTime(){
|
||||
public static boolean isChrismasTime(Date currentTime){
|
||||
// from december 15 to january 15
|
||||
Calendar cal = Calendar.getInstance();
|
||||
Calendar cal = new GregorianCalendar();
|
||||
cal.setTime(currentTime);
|
||||
|
||||
int currentYear = cal.get(Calendar.YEAR);
|
||||
Date currentTime = cal.getTime();
|
||||
if (cal.get(Calendar.MONTH) == Calendar.JANUARY){
|
||||
currentYear = currentYear - 1;
|
||||
}
|
||||
|
||||
Date chrisFrom = new GregorianCalendar(currentYear, Calendar.DECEMBER, 15).getTime();
|
||||
Date chrisTo = new GregorianCalendar(currentYear + 1, Calendar.JANUARY, 15 + 1).getTime();
|
||||
Date chrisTo = new GregorianCalendar(currentYear + 1, Calendar.JANUARY, 15 + 1).getTime(); // end of the 15 day
|
||||
|
||||
return currentTime.after(chrisFrom) && currentTime.before(chrisTo);
|
||||
return ((currentTime.equals(chrisFrom) || currentTime.after(chrisFrom))
|
||||
&& currentTime.before(chrisTo));
|
||||
}
|
||||
|
||||
private void addMageLabel() {
|
||||
|
@ -448,7 +455,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
|
||||
String filename;
|
||||
float ratio;
|
||||
if (isChrismasTime()){
|
||||
if (isChrismasTime(Calendar.getInstance().getTime())){
|
||||
// chrismass logo
|
||||
LOGGER.info("Yo Ho Ho, Merry Christmas and a Happy New Year");
|
||||
filename = "/label-xmage-christmas.png";
|
||||
|
@ -945,7 +952,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
}//GEN-LAST:event_btnConnectActionPerformed
|
||||
|
||||
public void btnAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAboutActionPerformed
|
||||
JInternalFrame[] windows = desktopPane.getAllFramesInLayer(JLayeredPane.POPUP_LAYER);
|
||||
JInternalFrame[] windows = desktopPane.getAllFramesInLayer(JLayeredPane.MODAL_LAYER);
|
||||
for (JInternalFrame window : windows) {
|
||||
if (window instanceof AboutDialog) {
|
||||
// don't open the window twice.
|
||||
|
@ -953,7 +960,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
}
|
||||
}
|
||||
AboutDialog aboutDialog = new AboutDialog();
|
||||
desktopPane.add(aboutDialog, JLayeredPane.POPUP_LAYER);
|
||||
desktopPane.add(aboutDialog, JLayeredPane.MODAL_LAYER);
|
||||
aboutDialog.showDialog(VERSION);
|
||||
}//GEN-LAST:event_btnAboutActionPerformed
|
||||
|
||||
|
@ -1096,7 +1103,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
public void showUserRequestDialog(final UserRequestMessage userRequestMessage) {
|
||||
final UserRequestDialog userRequestDialog = new UserRequestDialog();
|
||||
userRequestDialog.setLocation(100, 100);
|
||||
desktopPane.add(userRequestDialog, JLayeredPane.POPUP_LAYER);
|
||||
desktopPane.add(userRequestDialog, JLayeredPane.MODAL_LAYER);
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
userRequestDialog.showDialog(userRequestMessage);
|
||||
} else {
|
||||
|
|
|
@ -69,6 +69,9 @@ public final class Constants {
|
|||
public static final int POWBOX_TEXT_MAX_LEFT = 212;
|
||||
public static final int DAMAGE_MAX_LEFT = 180;
|
||||
|
||||
// tooltip hints delay in ms (need more time to display long hints withour hiding)
|
||||
public static final int TOOLTIPS_DELAY_MS = 60 * 1000;
|
||||
|
||||
public static final Border EMPTY_BORDER = BorderFactory.createEmptyBorder(2, 2, 2, 2);
|
||||
|
||||
public static final double SCALE_FACTOR = 0.5;
|
||||
|
|
|
@ -500,6 +500,109 @@
|
|||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jToggleCardViewActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JToolBar$Separator" name="jSeparator5">
|
||||
</Component>
|
||||
<Container class="javax.swing.JToolBar" name="tbRarities">
|
||||
<Properties>
|
||||
<Property name="floatable" type="boolean" value="false"/>
|
||||
<Property name="rollover" type="boolean" value="true"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Hold the ALT-key while clicking to deselect all other card rarities or hold the CTRL-key to only select all other card rarities."/>
|
||||
</Properties>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JToggleButton" name="tbCommon">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/buttons/rarity_common_20.png"/>
|
||||
</Property>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code=""<html><strong>Common</strong><br/>" 
+ tbRarities.getToolTipText()" type="code"/>
|
||||
</Property>
|
||||
<Property name="actionCommand" type="java.lang.String" value="Common"/>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tbCommonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JToggleButton" name="tbUncommon">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/buttons/rarity_uncommon_20.png"/>
|
||||
</Property>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code=""<html><strong>Uncommon</strong><br/>" 
+ tbUncommon.getToolTipText()" type="code"/>
|
||||
</Property>
|
||||
<Property name="actionCommand" type="java.lang.String" value="Uncommon"/>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tbUncommonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JToggleButton" name="tbRare">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/buttons/rarity_rare_20.png"/>
|
||||
</Property>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code=""<html><strong>Rare</strong><br/>" 
+ tbRarities.getToolTipText()" type="code"/>
|
||||
</Property>
|
||||
<Property name="actionCommand" type="java.lang.String" value="Rare"/>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tbRareActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JToggleButton" name="tbMythic">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/buttons/rarity_mythic_20.png"/>
|
||||
</Property>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code=""<html><strong>Mythic</strong><br/>" 
+ tbRarities.getToolTipText()" type="code"/>
|
||||
</Property>
|
||||
<Property name="actionCommand" type="java.lang.String" value="Mythic"/>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tbMythicActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JToggleButton" name="tbSpecial">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/buttons/rarity_special_20.png"/>
|
||||
</Property>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code=""<html><strong>Special</strong><br/>" 
+ tbRarities.getToolTipText()" type="code"/>
|
||||
</Property>
|
||||
<Property name="actionCommand" type="java.lang.String" value="Special"/>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tbSpecialActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JScrollPane" name="cardSelectorScrollPane">
|
||||
|
|
|
@ -55,6 +55,7 @@ import mage.client.util.GUISizeHelper;
|
|||
import mage.client.util.gui.FastSearchUtil;
|
||||
import mage.client.util.sets.ConstructedFormats;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Rarity;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.filter.predicate.Predicates;
|
||||
|
@ -214,8 +215,8 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
this.cards.add(card);
|
||||
}
|
||||
filterCards();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void loadCards(BigCard bigCard) {
|
||||
this.bigCard = bigCard;
|
||||
this.btnBooster.setVisible(true);
|
||||
|
@ -225,7 +226,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
// cbExpansionSet.setModel(new DefaultComboBoxModel<>(ConstructedFormats.getTypes()));
|
||||
// Action event on Expansion set triggers loadCards method
|
||||
cbExpansionSet.setSelectedIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
private FilterCard buildFilter() {
|
||||
FilterCard filter = new FilterCard();
|
||||
|
@ -328,6 +329,24 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
// criteria.types(CardType.TRIBAL);
|
||||
// criteria.types(CardType.CONSPIRACY);
|
||||
|
||||
if (this.tbCommon.isSelected()) {
|
||||
criteria.rarities(Rarity.COMMON);
|
||||
criteria.rarities(Rarity.LAND);
|
||||
}
|
||||
if (this.tbUncommon.isSelected()) {
|
||||
criteria.rarities(Rarity.UNCOMMON);
|
||||
}
|
||||
if (this.tbRare.isSelected()) {
|
||||
criteria.rarities(Rarity.RARE);
|
||||
}
|
||||
if (this.tbMythic.isSelected()) {
|
||||
criteria.rarities(Rarity.MYTHIC);
|
||||
}
|
||||
if (this.tbSpecial.isSelected()) {
|
||||
criteria.rarities(Rarity.SPECIAL);
|
||||
criteria.rarities(Rarity.BONUS);
|
||||
}
|
||||
|
||||
if (this.cbExpansionSet.isVisible()) {
|
||||
String expansionSelection = this.cbExpansionSet.getSelectedItem().toString();
|
||||
if (!expansionSelection.equals("- All Sets")) {
|
||||
|
@ -376,6 +395,19 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
filterCards();
|
||||
}
|
||||
|
||||
private void filterCardsRarity(int modifiers, String actionCommand) {
|
||||
// ALT or CTRL button was pushed
|
||||
if ((modifiers & ActionEvent.ALT_MASK) == ActionEvent.ALT_MASK || (modifiers & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK) {
|
||||
boolean invert = (modifiers & ActionEvent.ALT_MASK) == ActionEvent.ALT_MASK;
|
||||
tbCommon.setSelected(inverter(invert, tbCommon.getActionCommand(), actionCommand));
|
||||
tbUncommon.setSelected(inverter(invert, tbUncommon.getActionCommand(), actionCommand));
|
||||
tbRare.setSelected(inverter(invert, tbRare.getActionCommand(), actionCommand));
|
||||
tbMythic.setSelected(inverter(invert, tbMythic.getActionCommand(), actionCommand));
|
||||
tbSpecial.setSelected(inverter(invert, tbSpecial.getActionCommand(), actionCommand));
|
||||
}
|
||||
filterCards();
|
||||
}
|
||||
|
||||
private void filterCards() {
|
||||
FilterCard filter = buildFilter();
|
||||
try {
|
||||
|
@ -494,6 +526,13 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
jSeparator4 = new javax.swing.JToolBar.Separator();
|
||||
jToggleListView = new javax.swing.JToggleButton();
|
||||
jToggleCardView = new javax.swing.JToggleButton();
|
||||
jSeparator5 = new javax.swing.JToolBar.Separator();
|
||||
tbRarities = new javax.swing.JToolBar();
|
||||
tbCommon = new javax.swing.JToggleButton();
|
||||
tbUncommon = new javax.swing.JToggleButton();
|
||||
tbRare = new javax.swing.JToggleButton();
|
||||
tbMythic = new javax.swing.JToggleButton();
|
||||
tbSpecial = new javax.swing.JToggleButton();
|
||||
cardSelectorScrollPane = new javax.swing.JScrollPane();
|
||||
cardSelectorBottomPanel = new javax.swing.JPanel();
|
||||
jButtonAddToMain = new javax.swing.JButton();
|
||||
|
@ -841,6 +880,88 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
}
|
||||
});
|
||||
tbTypes.add(jToggleCardView);
|
||||
tbTypes.add(jSeparator5);
|
||||
|
||||
tbRarities.setFloatable(false);
|
||||
tbRarities.setRollover(true);
|
||||
tbRarities.setToolTipText("Hold the ALT-key while clicking to deselect all other card rarities or hold the CTRL-key to only select all other card rarities.");
|
||||
|
||||
tbCommon.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/rarity_common_20.png"))); // NOI18N
|
||||
tbCommon.setSelected(true);
|
||||
tbCommon.setToolTipText("<html><strong>Common</strong><br/>"
|
||||
+ tbRarities.getToolTipText());
|
||||
tbCommon.setActionCommand("Common");
|
||||
tbCommon.setFocusable(false);
|
||||
tbCommon.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
|
||||
tbCommon.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
|
||||
tbCommon.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
tbCommonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
tbRarities.add(tbCommon);
|
||||
|
||||
tbUncommon.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/rarity_uncommon_20.png"))); // NOI18N
|
||||
tbUncommon.setSelected(true);
|
||||
tbUncommon.setToolTipText("<html><strong>Uncommon</strong><br/>"
|
||||
+ tbUncommon.getToolTipText());
|
||||
tbUncommon.setActionCommand("Uncommon");
|
||||
tbUncommon.setFocusable(false);
|
||||
tbUncommon.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
|
||||
tbUncommon.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
|
||||
tbUncommon.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
tbUncommonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
tbRarities.add(tbUncommon);
|
||||
|
||||
tbRare.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/rarity_rare_20.png"))); // NOI18N
|
||||
tbRare.setSelected(true);
|
||||
tbRare.setToolTipText("<html><strong>Rare</strong><br/>"
|
||||
+ tbRarities.getToolTipText());
|
||||
tbRare.setActionCommand("Rare");
|
||||
tbRare.setFocusable(false);
|
||||
tbRare.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
|
||||
tbRare.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
|
||||
tbRare.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
tbRareActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
tbRarities.add(tbRare);
|
||||
|
||||
tbMythic.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/rarity_mythic_20.png"))); // NOI18N
|
||||
tbMythic.setSelected(true);
|
||||
tbMythic.setToolTipText("<html><strong>Mythic</strong><br/>"
|
||||
+ tbRarities.getToolTipText());
|
||||
tbMythic.setActionCommand("Mythic");
|
||||
tbMythic.setFocusable(false);
|
||||
tbMythic.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
|
||||
tbMythic.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
|
||||
tbMythic.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
tbMythicActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
tbRarities.add(tbMythic);
|
||||
|
||||
tbSpecial.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/rarity_special_20.png"))); // NOI18N
|
||||
tbSpecial.setSelected(true);
|
||||
tbSpecial.setToolTipText("<html><strong>Special</strong><br/>"
|
||||
+ tbRarities.getToolTipText());
|
||||
tbSpecial.setActionCommand("Special");
|
||||
tbSpecial.setFocusable(false);
|
||||
tbSpecial.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
|
||||
tbSpecial.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
|
||||
tbSpecial.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
tbSpecialActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
tbRarities.add(tbSpecial);
|
||||
|
||||
tbTypes.add(tbRarities);
|
||||
|
||||
cardSelectorScrollPane.setToolTipText("<HTML>Double click to add the card to the main deck.<br/>\nALT + Double click to add the card to the sideboard.");
|
||||
|
||||
|
@ -1224,6 +1345,26 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
FastSearchUtil.showFastSearchForStringComboBox(cbExpansionSet, "Select set or expansion");
|
||||
}//GEN-LAST:event_btnExpansionSearchActionPerformed
|
||||
|
||||
private void tbCommonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tbCommonActionPerformed
|
||||
filterCardsRarity(evt.getModifiers(), evt.getActionCommand());
|
||||
}//GEN-LAST:event_tbCommonActionPerformed
|
||||
|
||||
private void tbUncommonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tbUncommonActionPerformed
|
||||
filterCardsRarity(evt.getModifiers(), evt.getActionCommand());
|
||||
}//GEN-LAST:event_tbUncommonActionPerformed
|
||||
|
||||
private void tbRareActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tbRareActionPerformed
|
||||
filterCardsRarity(evt.getModifiers(), evt.getActionCommand());
|
||||
}//GEN-LAST:event_tbRareActionPerformed
|
||||
|
||||
private void tbMythicActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tbMythicActionPerformed
|
||||
filterCardsRarity(evt.getModifiers(), evt.getActionCommand());
|
||||
}//GEN-LAST:event_tbMythicActionPerformed
|
||||
|
||||
private void tbSpecialActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tbSpecialActionPerformed
|
||||
filterCardsRarity(evt.getModifiers(), evt.getActionCommand());
|
||||
}//GEN-LAST:event_tbSpecialActionPerformed
|
||||
|
||||
private void toggleViewMode() {
|
||||
if (currentView instanceof CardGrid) {
|
||||
jToggleListView.setSelected(true);
|
||||
|
@ -1288,6 +1429,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
private javax.swing.JToolBar.Separator jSeparator2;
|
||||
private javax.swing.JToolBar.Separator jSeparator3;
|
||||
private javax.swing.JToolBar.Separator jSeparator4;
|
||||
private javax.swing.JToolBar.Separator jSeparator5;
|
||||
private javax.swing.JToolBar.Separator jSeparator6;
|
||||
private javax.swing.JTextField jTextFieldSearch;
|
||||
private javax.swing.JToggleButton jToggleCardView;
|
||||
|
@ -1297,15 +1439,21 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
|
|||
private javax.swing.JToggleButton tbBlue;
|
||||
private javax.swing.JToolBar tbColor;
|
||||
private javax.swing.JToggleButton tbColorless;
|
||||
private javax.swing.JToggleButton tbCommon;
|
||||
private javax.swing.JToggleButton tbCreatures;
|
||||
private javax.swing.JToggleButton tbEnchantments;
|
||||
private javax.swing.JToggleButton tbGreen;
|
||||
private javax.swing.JToggleButton tbInstants;
|
||||
private javax.swing.JToggleButton tbLand;
|
||||
private javax.swing.JToggleButton tbMythic;
|
||||
private javax.swing.JToggleButton tbPlaneswalkers;
|
||||
private javax.swing.JToggleButton tbRare;
|
||||
private javax.swing.JToolBar tbRarities;
|
||||
private javax.swing.JToggleButton tbRed;
|
||||
private javax.swing.JToggleButton tbSorceries;
|
||||
private javax.swing.JToggleButton tbSpecial;
|
||||
private javax.swing.JToolBar tbTypes;
|
||||
private javax.swing.JToggleButton tbUncommon;
|
||||
private javax.swing.JToggleButton tbWhite;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
|
|
|
@ -114,7 +114,14 @@ public class AddLandDialog extends MageDialog {
|
|||
}
|
||||
cbLandSet.setModel(new DefaultComboBoxModel(landSetNames.toArray()));
|
||||
|
||||
MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER);
|
||||
|
||||
// windows settings
|
||||
if (this.isModal()){
|
||||
MageFrame.getDesktop().add(this, JLayeredPane.MODAL_LAYER);
|
||||
}else{
|
||||
MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER);
|
||||
}
|
||||
|
||||
this.setVisible(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -102,10 +102,10 @@ public class ConnectDialog extends MageDialog {
|
|||
this.txtPassword.addActionListener(connectAction);
|
||||
|
||||
registerUserDialog = new RegisterUserDialog(this);
|
||||
MageFrame.getDesktop().add(registerUserDialog, JLayeredPane.POPUP_LAYER);
|
||||
MageFrame.getDesktop().add(registerUserDialog, JLayeredPane.MODAL_LAYER);
|
||||
|
||||
resetPasswordDialog = new ResetPasswordDialog(this);
|
||||
MageFrame.getDesktop().add(resetPasswordDialog, JLayeredPane.POPUP_LAYER);
|
||||
MageFrame.getDesktop().add(resetPasswordDialog, JLayeredPane.MODAL_LAYER);
|
||||
}
|
||||
|
||||
public void showDialog() {
|
||||
|
|
|
@ -45,8 +45,8 @@ import java.awt.event.MouseEvent;
|
|||
import java.beans.PropertyVetoException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.*;
|
||||
|
||||
import mage.client.MageFrame;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
@ -74,11 +74,34 @@ public class MageDialog extends javax.swing.JInternalFrame {
|
|||
@Override
|
||||
public void show() {
|
||||
super.show();
|
||||
this.toFront();
|
||||
|
||||
// frames desktop ordering
|
||||
// more info https://docs.oracle.com/javase/7/docs/api/javax/swing/JLayeredPane.html
|
||||
// WARNING, use
|
||||
// - JLayeredPane.DEFAULT_LAYER: tables and games (tabs)
|
||||
// - JLayeredPane.PALETTE_LAYER: toolbars and info windows like cards list, not modal dialogs (not required user actions)
|
||||
// - JLayeredPane.MODAL_LAYER: all modal dialogs (user required actions - select cards in game, new game window, error windows)
|
||||
// - JLayeredPane.POPUP_LAYER: hints and other top level graphics
|
||||
// - JLayeredPane.DRAG_LAYER: top most layer for critical actions and user controls
|
||||
/*
|
||||
JInternalFrame[] frames = MageFrame.getDesktop().getAllFrames();
|
||||
System.out.println("---");
|
||||
for(JInternalFrame frame: frames){
|
||||
int zorder = -1;
|
||||
if (frame.getParent() != null){
|
||||
frame.getParent().getComponentZOrder(frame);
|
||||
}
|
||||
System.out.println(frame.getClass() + " (" + frame.getTitle() + ") : layer = " + frame.getLayer() + ", zorder = " + zorder);
|
||||
}
|
||||
*/
|
||||
|
||||
if (modal) {
|
||||
this.setClosable(false);
|
||||
}
|
||||
if (this.modal) {
|
||||
|
||||
this.toFront();
|
||||
|
||||
if (modal){
|
||||
startModal();
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +131,6 @@ public class MageDialog extends javax.swing.JInternalFrame {
|
|||
}
|
||||
|
||||
private synchronized void startModal() {
|
||||
|
||||
try {
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
EventQueue theQueue = getToolkit().getSystemEventQueue();
|
||||
|
|
|
@ -47,6 +47,7 @@ import mage.cards.repository.ExpansionRepository;
|
|||
import mage.client.MageFrame;
|
||||
import mage.client.SessionHandler;
|
||||
import mage.client.table.TournamentPlayerPanel;
|
||||
import mage.client.util.gui.FastSearchUtil;
|
||||
import mage.constants.MatchTimeLimit;
|
||||
import mage.constants.MultiplayerAttackOption;
|
||||
import mage.constants.RangeOfInfluence;
|
||||
|
@ -76,7 +77,7 @@ public class NewTournamentDialog extends MageDialog {
|
|||
private RandomPacksSelectorDialog randomPackSelector;
|
||||
private JTextArea txtRandomPacks;
|
||||
private final List<TournamentPlayerPanel> players = new ArrayList<>();
|
||||
private final List<JComboBox> packs = new ArrayList<>();
|
||||
private final List<JPanel> packPanels = new ArrayList<>();
|
||||
private static final int CONSTRUCTION_TIME_MIN = 6;
|
||||
private static final int CONSTRUCTION_TIME_MAX = 30;
|
||||
private boolean isRandom = false;
|
||||
|
@ -586,8 +587,13 @@ public class NewTournamentDialog extends MageDialog {
|
|||
tOptions.getLimitedOptions().getSetCodes().addAll(selected);
|
||||
}
|
||||
} else {
|
||||
for (JComboBox pack : packs) {
|
||||
tOptions.getLimitedOptions().getSetCodes().add(((ExpansionInfo) pack.getSelectedItem()).getCode());
|
||||
for (JPanel panel : packPanels) {
|
||||
JComboBox combo = findComboInComponent(panel);
|
||||
if(combo != null) {
|
||||
tOptions.getLimitedOptions().getSetCodes().add(((ExpansionInfo) combo.getSelectedItem()).getCode());
|
||||
}else{
|
||||
logger.error("Can't find combo component in " + panel.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
tOptions.getMatchOptions().setDeckType("Limited");
|
||||
|
@ -884,35 +890,89 @@ public class NewTournamentDialog extends MageDialog {
|
|||
}
|
||||
|
||||
private void createPacks(int numPacks) {
|
||||
while (packs.size() > numPacks) {
|
||||
pnlPacks.remove(packs.get(packs.size() - 1));
|
||||
packs.remove(packs.size() - 1);
|
||||
while (packPanels.size() > numPacks) {
|
||||
pnlPacks.remove(packPanels.get(packPanels.size() - 1));
|
||||
packPanels.remove(packPanels.size() - 1);
|
||||
}
|
||||
while (packs.size() < numPacks) {
|
||||
while (packPanels.size() < numPacks) {
|
||||
// SELECT PACK
|
||||
// panel
|
||||
JPanel setPanel = new JPanel();
|
||||
setPanel.setLayout(new javax.swing.BoxLayout(setPanel, javax.swing.BoxLayout.LINE_AXIS));
|
||||
setPanel.setOpaque(false);
|
||||
//setPanel.setPreferredSize(new Dimension(200, 25));
|
||||
//setPanel.setMaximumSize(new Dimension(200, 25));
|
||||
pnlPacks.add(setPanel);
|
||||
packPanels.add(setPanel); // for later access
|
||||
// combo set
|
||||
JComboBox pack = new JComboBox();
|
||||
pack = new JComboBox();
|
||||
pack.setModel(new DefaultComboBoxModel(ExpansionRepository.instance.getWithBoostersSortedByReleaseDate()));
|
||||
pnlPacks.add(pack);
|
||||
packs.add(pack);
|
||||
pack.addActionListener(evt -> packActionPerformed(evt));
|
||||
pack.setAlignmentX(0.0F);
|
||||
pack.setMinimumSize(new Dimension(50, 25));
|
||||
pack.setPreferredSize(new Dimension(50, 25));
|
||||
pack.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
|
||||
setPanel.add(pack);
|
||||
// search button
|
||||
JButton searchButton = new JButton();
|
||||
searchButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/search_24.png")));
|
||||
searchButton.setToolTipText("Search and select from list");
|
||||
searchButton.setAlignmentX(1.0F);
|
||||
searchButton.setMinimumSize(new java.awt.Dimension(24, 24));
|
||||
searchButton.setPreferredSize(new java.awt.Dimension(32, 32));
|
||||
searchButton.setMaximumSize(new java.awt.Dimension(32, 32));
|
||||
searchButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
|
||||
// search combo box near button (must be only one combo in panel)
|
||||
JButton button = (JButton)evt.getSource();
|
||||
JComboBox combo = findComboInComponent(button.getParent());
|
||||
|
||||
if (combo != null) {
|
||||
FastSearchUtil.showFastSearchForStringComboBox(combo, "Select value");
|
||||
}
|
||||
}
|
||||
});
|
||||
setPanel.add(searchButton);
|
||||
}
|
||||
this.pack();
|
||||
this.revalidate();
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
private void packActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
boolean start = false;
|
||||
int selectedIndex = 0;
|
||||
for (JComboBox pack : packs) {
|
||||
if (!start) {
|
||||
if (evt.getSource().equals(pack)) {
|
||||
start = true;
|
||||
selectedIndex = pack.getSelectedIndex();
|
||||
}
|
||||
} else {
|
||||
pack.setSelectedIndex(selectedIndex);
|
||||
private JComboBox findComboInComponent(Container panel){
|
||||
// search combo box near button (must be only one combo in panel)
|
||||
JComboBox combo = null;
|
||||
for(Component comp: panel.getComponents()){
|
||||
if (comp instanceof JComboBox){
|
||||
combo = (JComboBox)comp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return combo;
|
||||
}
|
||||
|
||||
private void packActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
// fill all bottom combobox with same value
|
||||
JComboBox curentCombo = (JComboBox)evt.getSource();
|
||||
int newValue = curentCombo.getSelectedIndex();
|
||||
|
||||
// search start index
|
||||
int startIndex = 0;
|
||||
for(int i = 0; i < packPanels.size(); i++){
|
||||
JComboBox pack = findComboInComponent(packPanels.get(i));
|
||||
if (pack.equals(curentCombo)){
|
||||
startIndex = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// change all from start index
|
||||
for(int i = startIndex; i < packPanels.size(); i++){
|
||||
JComboBox pack = findComboInComponent(packPanels.get(i));
|
||||
pack.setSelectedIndex(newValue);
|
||||
}
|
||||
}
|
||||
|
||||
private void createPlayers(int numPlayers) {
|
||||
|
@ -1054,16 +1114,22 @@ public class NewTournamentDialog extends MageDialog {
|
|||
int packNumber = 0;
|
||||
for (String pack : packsArray) {
|
||||
packNumber++;
|
||||
if (this.packs.size() >= packNumber - 1) {
|
||||
JComboBox comboBox = this.packs.get(packNumber - 1);
|
||||
ComboBoxModel model = comboBox.getModel();
|
||||
int size = model.getSize();
|
||||
for (int i = 0; i < size; i++) {
|
||||
ExpansionInfo element = (ExpansionInfo) model.getElementAt(i);
|
||||
if (element.getCode().equals(pack.trim())) {
|
||||
comboBox.setSelectedIndex(i);
|
||||
break;
|
||||
if (this.packPanels.size() >= packNumber - 1) {
|
||||
JPanel panel = packPanels.get(packNumber - 1);
|
||||
JComboBox comboBox = findComboInComponent(panel);
|
||||
|
||||
if (comboBox != null) {
|
||||
ComboBoxModel model = comboBox.getModel();
|
||||
int size = model.getSize();
|
||||
for (int i = 0; i < size; i++) {
|
||||
ExpansionInfo element = (ExpansionInfo) model.getElementAt(i);
|
||||
if (element.getCode().equals(pack.trim())) {
|
||||
comboBox.setSelectedIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
logger.error("Can't find combo component in " + panel.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -165,7 +165,11 @@ public class PickChoiceDialog extends MageDialog {
|
|||
}
|
||||
|
||||
// window settings
|
||||
MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER);
|
||||
if (this.isModal()){
|
||||
MageFrame.getDesktop().add(this, JLayeredPane.MODAL_LAYER);
|
||||
}else{
|
||||
MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER);
|
||||
}
|
||||
if (mageDialogState != null) {
|
||||
mageDialogState.setStateToDialog(this);
|
||||
|
||||
|
@ -174,7 +178,7 @@ public class PickChoiceDialog extends MageDialog {
|
|||
this.setLocation(centered.x, centered.y);
|
||||
GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, this);
|
||||
}
|
||||
|
||||
|
||||
// final load
|
||||
loadData();
|
||||
|
||||
|
|
|
@ -35,7 +35,9 @@
|
|||
package mage.client.dialog;
|
||||
|
||||
import java.awt.Point;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
import javax.swing.*;
|
||||
|
||||
import mage.client.MageFrame;
|
||||
import mage.client.util.SettingsManager;
|
||||
import mage.client.util.gui.GuiDisplayUtil;
|
||||
|
||||
|
@ -60,6 +62,13 @@ public class PickNumberDialog extends MageDialog {
|
|||
this.btnCancel.setVisible(false);
|
||||
this.pack();
|
||||
|
||||
// window settings
|
||||
if (this.isModal()){
|
||||
MageFrame.getDesktop().add(this, JLayeredPane.MODAL_LAYER);
|
||||
}else{
|
||||
MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER);
|
||||
}
|
||||
|
||||
Point centered = SettingsManager.instance.getComponentPosition(getWidth(), getHeight());
|
||||
this.setLocation(centered.x, centered.y);
|
||||
GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, this);
|
||||
|
|
|
@ -114,6 +114,14 @@ public class PickPileDialog extends MageDialog {
|
|||
this.revalidate();
|
||||
this.repaint();
|
||||
this.setModal(true);
|
||||
|
||||
// window settings
|
||||
if (this.isModal()){
|
||||
MageFrame.getDesktop().add(this, JLayeredPane.MODAL_LAYER);
|
||||
}else{
|
||||
MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER);
|
||||
}
|
||||
|
||||
this.setVisible(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -120,15 +120,19 @@ public class ShowCardsDialog extends MageDialog {
|
|||
this.cardArea.addCardEventListener(eventListener);
|
||||
}
|
||||
|
||||
if (getParent() != MageFrame.getDesktop() /*|| this.isClosed*/) {
|
||||
MageFrame.getDesktop().add(this, JLayeredPane.DEFAULT_LAYER);
|
||||
}
|
||||
pack();
|
||||
|
||||
this.revalidate();
|
||||
this.repaint();
|
||||
this.setModal(modal);
|
||||
|
||||
// window settings
|
||||
if (this.isModal()){
|
||||
MageFrame.getDesktop().add(this, JLayeredPane.MODAL_LAYER);
|
||||
}else{
|
||||
MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER);
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (!positioned) {
|
||||
int width = ShowCardsDialog.this.getWidth();
|
||||
|
|
|
@ -1115,7 +1115,7 @@ public final class GamePanel extends javax.swing.JPanel {
|
|||
}
|
||||
this.feedbackPanel.getFeedback(required ? FeedbackMode.INFORM : FeedbackMode.CANCEL, message, gameView.getSpecial(), options0, messageId);
|
||||
if (dialog != null) {
|
||||
this.pickTarget.add(dialog);
|
||||
this.pickTarget.add(dialog); // TODO: 01.01.2018, JayDi85: why feedbackPanel saved to pickTarget list? Need to research
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,9 @@ import javax.swing.UIManager;
|
|||
|
||||
import mage.client.SessionHandler;
|
||||
import mage.client.components.MageTextArea;
|
||||
import mage.client.constants.Constants;
|
||||
import mage.client.game.FeedbackPanel.FeedbackMode;
|
||||
|
||||
import static mage.client.game.FeedbackPanel.FeedbackMode.QUESTION;
|
||||
import mage.client.util.GUISizeHelper;
|
||||
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_ID_NO;
|
||||
|
@ -82,7 +84,6 @@ public class HelperPanel extends JPanel {
|
|||
private javax.swing.JButton linkSpecial;
|
||||
private javax.swing.JButton linkUndo;
|
||||
|
||||
private final int defaultDismissTimeout = ToolTipManager.sharedInstance().getDismissDelay();
|
||||
private final Object tooltipBackground = UIManager.get("info");
|
||||
|
||||
private static final String CMD_AUTO_ANSWER_ID_YES = "cmdAutoAnswerIdYes";
|
||||
|
@ -232,13 +233,13 @@ public class HelperPanel extends JPanel {
|
|||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent me) {
|
||||
ToolTipManager.sharedInstance().setDismissDelay(100000);
|
||||
ToolTipManager.sharedInstance().setDismissDelay(100 * 1000);
|
||||
UIManager.put("info", Color.DARK_GRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent me) {
|
||||
ToolTipManager.sharedInstance().setDismissDelay(defaultDismissTimeout);
|
||||
ToolTipManager.sharedInstance().setDismissDelay(Constants.TOOLTIPS_DELAY_MS);
|
||||
UIManager.put("info", tooltipBackground);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package mage.client.util.stats;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class MemoryStats {
|
||||
|
||||
private float Available = 0;
|
||||
private float MaxAvailable = 0;
|
||||
private float Used = 0;
|
||||
private float Free = 0;
|
||||
|
||||
public MemoryStats(float MaxAvailable, float Available, float Used, float Free){
|
||||
this.setMaxAvailable(MaxAvailable);
|
||||
this.setAvailable(Available);
|
||||
this.setUsed(Used);
|
||||
this.setFree(Free);
|
||||
}
|
||||
|
||||
public float getAvailable() {
|
||||
return Available;
|
||||
}
|
||||
|
||||
public void setAvailable(float available) {
|
||||
Available = available;
|
||||
}
|
||||
|
||||
public float getUsed() {
|
||||
return Used;
|
||||
}
|
||||
|
||||
public void setUsed(float used) {
|
||||
Used = used;
|
||||
}
|
||||
|
||||
public float getFree() {
|
||||
return Free;
|
||||
}
|
||||
|
||||
public void setFree(float free) {
|
||||
Free = free;
|
||||
}
|
||||
|
||||
public float getMaxAvailable() {
|
||||
return MaxAvailable;
|
||||
}
|
||||
|
||||
public void setMaxAvailable(float maxAvailable) {
|
||||
MaxAvailable = maxAvailable;
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package mage.client.util.stats;
|
||||
|
||||
/**
|
||||
* @author noxx
|
||||
*/
|
||||
public final class MemoryUsageStatUtil {
|
||||
|
||||
private MemoryUsageStatUtil() {}
|
||||
|
||||
/**
|
||||
* Returns percentage of available memory used at runtime.
|
||||
* If not possible to determine, returns -1.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static float getMemoryFreeStatPercentage() {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
if (runtime.maxMemory() != 0) {
|
||||
long usedMem = runtime.totalMemory() - runtime.freeMemory();
|
||||
return (1 - (1.0f*usedMem)/runtime.maxMemory())*100;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package mage.client.util.stats;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
@ -11,11 +12,13 @@ import org.apache.log4j.Logger;
|
|||
* This updates the mem usage info in the Mage client every
|
||||
* MEM_USAGE_UPDATE_TIME ms.
|
||||
*
|
||||
* @author noxx
|
||||
* @author noxx, JayDi85
|
||||
*/
|
||||
public class UpdateMemUsageTask extends SwingWorker<Void, Float> {
|
||||
|
||||
public class UpdateMemUsageTask extends SwingWorker<Void, MemoryStats> {
|
||||
|
||||
private static final int MEM_USAGE_UPDATE_TIME = 2000;
|
||||
private static final int MEM_USAGE_WARNING_PERCENT = 80; // red color for mem used more than xx%
|
||||
|
||||
private final JLabel jLabelToDisplayInfo;
|
||||
|
||||
|
@ -23,24 +26,60 @@ public class UpdateMemUsageTask extends SwingWorker<Void, Float> {
|
|||
|
||||
public UpdateMemUsageTask(JLabel jLabelToDisplayInfo) {
|
||||
this.jLabelToDisplayInfo = jLabelToDisplayInfo;
|
||||
this.jLabelToDisplayInfo.setToolTipText("<html>Memory usage statistics");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground() throws Exception {
|
||||
while (!isCancelled()) {
|
||||
float memUsage = MemoryUsageStatUtil.getMemoryFreeStatPercentage();
|
||||
this.publish(memUsage >= 0 ? memUsage : null);
|
||||
MemoryStats memoryStats = new MemoryStats(0, 0, 0, 0);
|
||||
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
if (runtime.maxMemory() != 0) {
|
||||
memoryStats.setMaxAvailable(runtime.maxMemory());
|
||||
memoryStats.setAvailable(runtime.totalMemory());
|
||||
memoryStats.setFree(runtime.freeMemory());
|
||||
memoryStats.setUsed(runtime.totalMemory() - runtime.freeMemory());
|
||||
}
|
||||
|
||||
this.publish(memoryStats);
|
||||
TimeUnit.MILLISECONDS.sleep(MEM_USAGE_UPDATE_TIME);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void process(List<Float> chunks) {
|
||||
protected void process(List<MemoryStats> chunks) {
|
||||
if (chunks != null && !chunks.isEmpty()) {
|
||||
Float memUsage = chunks.get(chunks.size() - 1);
|
||||
if (memUsage != null) {
|
||||
jLabelToDisplayInfo.setText(Math.round(memUsage) + "% Mem free");
|
||||
MemoryStats memoryStats = chunks.get(chunks.size() - 1);
|
||||
if (memoryStats != null) {
|
||||
int max = Math.round(memoryStats.getMaxAvailable() / (1000 * 1000));
|
||||
int used = Math.round(memoryStats.getUsed() / (1000 * 1000));
|
||||
int total = Math.round(memoryStats.getAvailable() / (1000 * 1000));
|
||||
int percent = 0;
|
||||
if(max != 0){
|
||||
percent = Math.round((used * 100) / max);
|
||||
}
|
||||
|
||||
jLabelToDisplayInfo.setText("Memory used: " + percent + "% (" + used + " of " + max + " MB)");
|
||||
String warning = "";
|
||||
String optimizeHint = "<br><br>If you see low memory warning and have free system memory then try to increase max limit in launcher settings:<br>"
|
||||
+ " - Go to <i>launcher -> settings -> java tab</i>;<br>"
|
||||
+ " - Find <i>client java options</i> (it's may contain many commands);<br>"
|
||||
+ " - Find max available memory setting: <i>-Xmx256m</i> (it's must start with <b>-Xmx</b>);<br>"
|
||||
+ " - Increase number in that value from 256 to 512, or 512 to 1024;<br>"
|
||||
+ " - Save new settings and restart application.";
|
||||
if(percent >= MEM_USAGE_WARNING_PERCENT){
|
||||
jLabelToDisplayInfo.setForeground(Color.red);
|
||||
warning = "<br><br><b>WARNING</b><br>"
|
||||
+ "Application memory limit almost reached. Errors and freezes are very possible.";
|
||||
|
||||
}else{
|
||||
jLabelToDisplayInfo.setForeground(Color.black);
|
||||
}
|
||||
|
||||
this.jLabelToDisplayInfo.setToolTipText("<html>Memory usage statistics" + warning + optimizeHint);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,28 +35,30 @@ public final class ManaSymbolsCellRenderer extends DefaultTableCellRenderer {
|
|||
String manaCost = (String)value;
|
||||
manaPanel.removeAll();
|
||||
manaPanel.setLayout(new BoxLayout(manaPanel, BoxLayout.X_AXIS));
|
||||
StringTokenizer tok = new StringTokenizer(manaCost, " ");
|
||||
while (tok.hasMoreTokens()) {
|
||||
String symbol = tok.nextToken();
|
||||
if(manaCost != null){
|
||||
StringTokenizer tok = new StringTokenizer(manaCost, " ");
|
||||
while (tok.hasMoreTokens()) {
|
||||
String symbol = tok.nextToken();
|
||||
|
||||
JLabel symbolLabel = new JLabel();
|
||||
//symbolLabel.setBorder(new LineBorder(new Color(150, 150, 150))); // debug
|
||||
symbolLabel.setBorder(new EmptyBorder(0, symbolHorizontalMargin,0, 0));
|
||||
JLabel symbolLabel = new JLabel();
|
||||
//symbolLabel.setBorder(new LineBorder(new Color(150, 150, 150))); // debug
|
||||
symbolLabel.setBorder(new EmptyBorder(0, symbolHorizontalMargin,0, 0));
|
||||
|
||||
BufferedImage image = ManaSymbols.getSizedManaSymbol(symbol, symbolWidth);
|
||||
if (image != null){
|
||||
// icon
|
||||
symbolLabel.setIcon(new ImageIcon(image));
|
||||
}else
|
||||
{
|
||||
// text
|
||||
symbolLabel.setText("{" + symbol + "}");
|
||||
symbolLabel.setOpaque(baseLabel.isOpaque());
|
||||
symbolLabel.setForeground(baseLabel.getForeground());
|
||||
symbolLabel.setBackground(baseLabel.getBackground());
|
||||
BufferedImage image = ManaSymbols.getSizedManaSymbol(symbol, symbolWidth);
|
||||
if (image != null){
|
||||
// icon
|
||||
symbolLabel.setIcon(new ImageIcon(image));
|
||||
}else
|
||||
{
|
||||
// text
|
||||
symbolLabel.setText("{" + symbol + "}");
|
||||
symbolLabel.setOpaque(baseLabel.isOpaque());
|
||||
symbolLabel.setForeground(baseLabel.getForeground());
|
||||
symbolLabel.setBackground(baseLabel.getBackground());
|
||||
}
|
||||
|
||||
manaPanel.add(symbolLabel);
|
||||
}
|
||||
|
||||
manaPanel.add(symbolLabel);
|
||||
}
|
||||
|
||||
return manaPanel;
|
||||
|
|
42
Mage.Client/src/test/java/mage/client/util/ChrismasTest.java
Normal file
42
Mage.Client/src/test/java/mage/client/util/ChrismasTest.java
Normal file
|
@ -0,0 +1,42 @@
|
|||
package mage.client.util;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import static mage.client.MageFrame.isChrismasTime;
|
||||
|
||||
public class ChrismasTest {
|
||||
|
||||
private Date getDate(int Year, int Month, int Day){
|
||||
Calendar cal = new GregorianCalendar(Year, Month - 1, Day);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ignoreDefaultResponse() throws Exception {
|
||||
// chrismas from 15 december to 15 january
|
||||
Assert.assertEquals(false, isChrismasTime(getDate(2017, 11, 1)));
|
||||
Assert.assertEquals(false, isChrismasTime(getDate(2017, 11, 15)));
|
||||
Assert.assertEquals(false, isChrismasTime(getDate(2017, 11, 30)));
|
||||
Assert.assertEquals(false, isChrismasTime(getDate(2017, 12, 1)));
|
||||
Assert.assertEquals(false, isChrismasTime(getDate(2017, 12, 14)));
|
||||
Assert.assertEquals(true, isChrismasTime(getDate(2017, 12, 15)));
|
||||
Assert.assertEquals(true, isChrismasTime(getDate(2017, 12, 16)));
|
||||
Assert.assertEquals(true, isChrismasTime(getDate(2017, 12, 31)));
|
||||
Assert.assertEquals(true, isChrismasTime(getDate(2018, 1, 1)));
|
||||
Assert.assertEquals(true, isChrismasTime(getDate(2018, 1, 14)));
|
||||
Assert.assertEquals(true, isChrismasTime(getDate(2018, 1, 15)));
|
||||
Assert.assertEquals(false, isChrismasTime(getDate(2018, 1, 16)));
|
||||
Assert.assertEquals(false, isChrismasTime(getDate(2018, 1, 31)));
|
||||
Assert.assertEquals(false, isChrismasTime(getDate(2018, 2, 1)));
|
||||
Assert.assertEquals(false, isChrismasTime(getDate(2018, 12, 1)));
|
||||
Assert.assertEquals(true, isChrismasTime(getDate(2018, 12, 20)));
|
||||
Assert.assertEquals(true, isChrismasTime(getDate(2019, 1, 10)));
|
||||
Assert.assertEquals(false, isChrismasTime(getDate(2019, 1, 25)));
|
||||
}
|
||||
|
||||
}
|
79
Mage.Sets/src/mage/cards/a/ApocalypseChime.java
Normal file
79
Mage.Sets/src/mage/cards/a/ApocalypseChime.java
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.SacrificeSourceCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.DestroyAllEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.other.ExpansionSetPredicate;
|
||||
import mage.filter.predicate.permanent.TokenPredicate;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class ApocalypseChime extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterPermanent("nontoken permanents with a name originally printed in the Homelands expansion");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.and(
|
||||
Predicates.not(new TokenPredicate()),
|
||||
new ExpansionSetPredicate("HML")
|
||||
));
|
||||
}
|
||||
|
||||
public ApocalypseChime(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
|
||||
|
||||
// {2}, {T}, Sacrifice Apocalypse Chime: Destroy all nontoken permanents with a name originally printed in the Homelands expansion. They can't be regenerated.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyAllEffect(filter, true), new ManaCostsImpl("{2}"));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addCost(new SacrificeSourceCost());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
public ApocalypseChime(final ApocalypseChime card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApocalypseChime copy() {
|
||||
return new ApocalypseChime(this);
|
||||
}
|
||||
}
|
|
@ -25,7 +25,6 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -46,14 +45,17 @@ import mage.constants.*;
|
|||
public class ArdentRecruit extends CardImpl {
|
||||
|
||||
public ArdentRecruit(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}");
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.SOLDIER);
|
||||
|
||||
this.power = new MageInt(1);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
// Metalcraft — Ardent Recruit gets +2/+2 as long as you control three or more artifacts.
|
||||
ContinuousEffect boostSource = new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield);
|
||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(boostSource, MetalcraftCondition.instance, "Ardent Recruit gets +2/+2 as long as you control three or more artifacts");
|
||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(boostSource, MetalcraftCondition.instance,
|
||||
"{this} gets +2/+2 as long as you control three or more artifacts");
|
||||
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
|
||||
ability.setAbilityWord(AbilityWord.METALCRAFT);
|
||||
this.addAbility(ability);
|
||||
|
|
110
Mage.Sets/src/mage/cards/a/AutumnWillow.java
Normal file
110
Mage.Sets/src/mage/cards/a/AutumnWillow.java
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.abilities.keyword.ShroudAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.TargetPlayer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class AutumnWillow extends CardImpl {
|
||||
|
||||
public AutumnWillow(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}");
|
||||
addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.AVATAR);
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(4);
|
||||
|
||||
// Shroud
|
||||
this.addAbility(ShroudAbility.getInstance());
|
||||
|
||||
// {G}: Until end of turn, Autumn Willow can be the target of spells and abilities controlled by target player as though it didn't have shroud.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AutumnWillowEffect(), new ManaCostsImpl("{G}"));
|
||||
ability.addTarget(new TargetPlayer());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
public AutumnWillow(final AutumnWillow card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AutumnWillow copy() {
|
||||
return new AutumnWillow(this);
|
||||
}
|
||||
}
|
||||
|
||||
class AutumnWillowEffect extends AsThoughEffectImpl {
|
||||
|
||||
public AutumnWillowEffect() {
|
||||
super(AsThoughEffectType.SHROUD, Duration.EndOfTurn, Outcome.Benefit);
|
||||
staticText = "Until end of turn, Autumn Willow can be the target of spells and abilities controlled by target player as though it didn't have shroud";
|
||||
}
|
||||
|
||||
public AutumnWillowEffect(final AutumnWillowEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AutumnWillowEffect copy() {
|
||||
return new AutumnWillowEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
|
||||
if (affectedControllerId.equals(source.getFirstTarget())) {
|
||||
Permanent creature = game.getPermanent(sourceId);
|
||||
if (creature != null) {
|
||||
if (sourceId.equals(source.getSourceId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
117
Mage.Sets/src/mage/cards/b/BrokenVisage.java
Normal file
117
Mage.Sets/src/mage/cards/b/BrokenVisage.java
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.b;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.DelayedTriggeredAbility;
|
||||
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.SacrificeTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.CardTypePredicate;
|
||||
import mage.filter.predicate.permanent.AttackingPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.BrokenVisageSpiritToken;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class BrokenVisage extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonartifact attacking creature");
|
||||
static {
|
||||
filter.add(Predicates.not(new CardTypePredicate(CardType.ARTIFACT)));
|
||||
filter.add(new AttackingPredicate());
|
||||
}
|
||||
|
||||
public BrokenVisage(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{B}");
|
||||
|
||||
// Destroy target nonartifact attacking creature. It can't be regenerated. Create a black Spirit creature token. Its power is equal to that creature's power and its toughness is equal to that creature's toughness. Sacrifice the token at the beginning of the next end step.
|
||||
this.getSpellAbility().addEffect(new BrokenVisageEffect());
|
||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
|
||||
}
|
||||
|
||||
public BrokenVisage(final BrokenVisage card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BrokenVisage copy() {
|
||||
return new BrokenVisage(this);
|
||||
}
|
||||
}
|
||||
|
||||
class BrokenVisageEffect extends OneShotEffect {
|
||||
|
||||
public BrokenVisageEffect() {
|
||||
super(Outcome.DestroyPermanent);
|
||||
this.staticText = "Destroy target nonartifact attacking creature. It can't be regenerated. Create a black Spirit creature token. Its power is equal to that creature's power and its toughness is equal to that creature's toughness. Sacrifice the token at the beginning of the next end step";
|
||||
}
|
||||
|
||||
public BrokenVisageEffect(final BrokenVisageEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BrokenVisageEffect copy() {
|
||||
return new BrokenVisageEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanentOrLKIBattlefield(this.getTargetPointer().getFirst(game, source));
|
||||
if (permanent != null) {
|
||||
permanent.destroy(source.getSourceId(), game, true);
|
||||
CreateTokenEffect effect = new CreateTokenEffect(new BrokenVisageSpiritToken(permanent.getPower().getValue(), permanent.getToughness().getValue()));
|
||||
effect.apply(game, source);
|
||||
for (UUID tokenId : effect.getLastAddedTokenIds()) {
|
||||
Permanent tokenPermanent = game.getPermanent(tokenId);
|
||||
if (tokenPermanent != null) {
|
||||
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("Sacrifice the token at the beginning of the next end step", source.getControllerId());
|
||||
sacrificeEffect.setTargetPointer(new FixedTarget(tokenPermanent, game));
|
||||
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect);
|
||||
game.addDelayedTriggeredAbility(delayedAbility, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -72,6 +72,7 @@ public class DaughterOfAutumn extends CardImpl {
|
|||
// {W}: The next 1 damage that would be dealt to target white creature this turn is dealt to Daughter of Autumn instead.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DaughterOfAutumnPreventDamageTargetEffect(Duration.EndOfTurn, 1), new ManaCostsImpl("{W}"));
|
||||
ability.addTarget(new TargetCreaturePermanent(filter));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
public DaughterOfAutumn(final DaughterOfAutumn card) {
|
||||
|
|
78
Mage.Sets/src/mage/cards/d/DuskCharger.java
Normal file
78
Mage.Sets/src/mage/cards/d/DuskCharger.java
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.d;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.CitysBlessingCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.keyword.AscendAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class DuskCharger extends CardImpl {
|
||||
|
||||
public DuskCharger(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
|
||||
|
||||
this.subtype.add(SubType.HORSE);
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
// Ascend
|
||||
this.addAbility(new AscendAbility());
|
||||
|
||||
// Dusk Charger gets +2/+2 as long as you have the city's blessing.
|
||||
ContinuousEffect boostSource = new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield);
|
||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(boostSource, CitysBlessingCondition.instance,
|
||||
"{this} gets +2/+2 as long as you have the city's blessing");
|
||||
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
public DuskCharger(final DuskCharger card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DuskCharger copy() {
|
||||
return new DuskCharger(this);
|
||||
}
|
||||
}
|
77
Mage.Sets/src/mage/cards/f/FeastOfFlesh.java
Normal file
77
Mage.Sets/src/mage/cards/f/FeastOfFlesh.java
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.f;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.dynamicvalue.IntPlusDynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.CardsInAllGraveyardsCount;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class FeastOfFlesh extends CardImpl {
|
||||
|
||||
private static final FilterCard filter = new FilterCard("cards named Feast of Flesh");
|
||||
|
||||
static {
|
||||
filter.add(new NamePredicate("Feast of Flesh"));
|
||||
}
|
||||
|
||||
public FeastOfFlesh(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}");
|
||||
|
||||
// Feast of Flesh deals X damage to target creature and you gain X life, where X is 1 plus the number of cards named Feast of Flesh in all graveyards.
|
||||
IntPlusDynamicValue value = new IntPlusDynamicValue(1, new CardsInAllGraveyardsCount(filter));
|
||||
Effect effect1 = new DamageTargetEffect(value);
|
||||
effect1.setText("Feast of Flesh deals X damage to target creature");
|
||||
Effect effect2 = new GainLifeEffect(value);
|
||||
effect2.setText("and you gain X life, where X is 1 plus the number of cards named {source} in all graveyards");
|
||||
this.getSpellAbility().addEffect(effect1);
|
||||
this.getSpellAbility().addEffect(effect2);
|
||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||
}
|
||||
|
||||
public FeastOfFlesh(final FeastOfFlesh card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeastOfFlesh copy() {
|
||||
return new FeastOfFlesh(this);
|
||||
}
|
||||
}
|
|
@ -28,18 +28,15 @@
|
|||
package mage.cards.f;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.condition.common.LiveLostLastTurnCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TargetController;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.token.SoldierToken;
|
||||
import mage.watchers.common.PlayerLostLifeWatcher;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -51,8 +48,10 @@ public class FirstResponse extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}");
|
||||
|
||||
// At the beginning of each upkeep, if you lost life last turn, create a 1/1 white Soldier creature token.
|
||||
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new FirstResponseEffect(), TargetController.ANY, false), new PlayerLostLifeWatcher());
|
||||
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
new BeginningOfUpkeepTriggeredAbility(new CreateTokenEffect(new SoldierToken()), TargetController.ANY, false),
|
||||
LiveLostLastTurnCondition.instance,
|
||||
"At the beginning of each upkeep, if you lost life last turn, create a 1/1 white Soldier creature token."));
|
||||
}
|
||||
|
||||
public FirstResponse(final FirstResponse card) {
|
||||
|
@ -64,32 +63,3 @@ public class FirstResponse extends CardImpl {
|
|||
return new FirstResponse(this);
|
||||
}
|
||||
}
|
||||
|
||||
class FirstResponseEffect extends OneShotEffect {
|
||||
|
||||
public FirstResponseEffect() {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
this.staticText = "if you lost life last turn, create a 1/1 white Soldier creature token";
|
||||
}
|
||||
|
||||
public FirstResponseEffect(final FirstResponseEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirstResponseEffect copy() {
|
||||
return new FirstResponseEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
PlayerLostLifeWatcher watcher = (PlayerLostLifeWatcher) game.getState().getWatchers().get(PlayerLostLifeWatcher.class.getSimpleName());
|
||||
if (watcher != null) {
|
||||
if (watcher.getLiveLostLastTurn(source.getControllerId()) > 0) {
|
||||
return new CreateTokenEffect(new SoldierToken()).apply(game, source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
92
Mage.Sets/src/mage/cards/g/GloriousDestiny.java
Normal file
92
Mage.Sets/src/mage/cards/g/GloriousDestiny.java
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.g;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AsEntersBattlefieldAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.CitysBlessingCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.common.ChooseCreatureTypeEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostAllOfChosenSubtypeEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityAllOfChosenSubtypeEffect;
|
||||
import mage.abilities.keyword.AscendAbility;
|
||||
import mage.abilities.keyword.VigilanceAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES_CONTROLLED;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.ControllerPredicate;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class GloriousDestiny extends CardImpl {
|
||||
|
||||
private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures you control of the chosen type");
|
||||
|
||||
static {
|
||||
filter.add(new ControllerPredicate(TargetController.YOU));
|
||||
}
|
||||
|
||||
public GloriousDestiny(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
|
||||
|
||||
// Ascend
|
||||
this.addAbility(new AscendAbility());
|
||||
|
||||
// As Glorious Destiny enters the battlefield, choose a creature type.
|
||||
this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.BoostCreature)));
|
||||
|
||||
// Creatures you control of the chosen type get +1/+1. They have vigilance as long as you have the city's blessing.
|
||||
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllOfChosenSubtypeEffect(1, 1, Duration.WhileOnBattlefield, filter, true));
|
||||
ContinuousEffect effect = new ConditionalContinuousEffect(
|
||||
new GainAbilityAllOfChosenSubtypeEffect(VigilanceAbility.getInstance(), Duration.WhileOnBattlefield, FILTER_PERMANENT_CREATURES_CONTROLLED),
|
||||
CitysBlessingCondition.instance,
|
||||
"They have vigilance as long as you have the city's blessing");
|
||||
ability.addEffect(effect);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
public GloriousDestiny(final GloriousDestiny card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GloriousDestiny copy() {
|
||||
return new GloriousDestiny(this);
|
||||
}
|
||||
}
|
130
Mage.Sets/src/mage/cards/h/HazduhrTheAbbot.java
Normal file
130
Mage.Sets/src/mage/cards/h/HazduhrTheAbbot.java
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.h;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.ObjectColor;
|
||||
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.RedirectionEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801 & L_J
|
||||
*/
|
||||
public class HazduhrTheAbbot extends CardImpl {
|
||||
|
||||
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("white creature you control");
|
||||
|
||||
static {
|
||||
filter.add(new ColorPredicate(ObjectColor.WHITE));
|
||||
}
|
||||
|
||||
public HazduhrTheAbbot(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}");
|
||||
addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.CLERIC);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(5);
|
||||
|
||||
// {X}, {T}: The next X damage that would be dealt this turn to target white creature you control is dealt to Hazduhr the Abbot instead.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HazduhrTheAbbotRedirectDamageEffect(Duration.EndOfTurn), new ManaCostsImpl("{X}"));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addTarget(new TargetControlledCreaturePermanent(filter));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
public HazduhrTheAbbot(final HazduhrTheAbbot card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HazduhrTheAbbot copy() {
|
||||
return new HazduhrTheAbbot(this);
|
||||
}
|
||||
}
|
||||
|
||||
class HazduhrTheAbbotRedirectDamageEffect extends RedirectionEffect {
|
||||
|
||||
private static FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
|
||||
|
||||
public HazduhrTheAbbotRedirectDamageEffect(Duration duration) {
|
||||
super(duration, 0, true);
|
||||
this.staticText = "The next X damage that would be dealt this turn to target white creature you control is dealt to {this} instead";
|
||||
}
|
||||
|
||||
public HazduhrTheAbbotRedirectDamageEffect(final HazduhrTheAbbotRedirectDamageEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
amountToRedirect = source.getManaCostsToPay().getX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HazduhrTheAbbotRedirectDamageEffect copy() {
|
||||
return new HazduhrTheAbbotRedirectDamageEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId());
|
||||
if (permanent != null) {
|
||||
if (filter.match(permanent, permanent.getId(), permanent.getControllerId(), game)) {
|
||||
if (event.getTargetId().equals(getTargetPointer().getFirst(game, source))) {
|
||||
if (event.getTargetId() != null) {
|
||||
TargetPermanent target = new TargetPermanent();
|
||||
target.add(source.getSourceId(), game);
|
||||
redirectTarget = target;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -27,7 +27,6 @@
|
|||
*/
|
||||
package mage.cards.h;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AsEntersBattlefieldAbility;
|
||||
|
@ -35,12 +34,8 @@ import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
|||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.ChooseCreatureTypeEffect;
|
||||
import mage.abilities.effects.common.cost.SpellsCostReductionAllOfChosenSubtypeEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect;
|
||||
import mage.cards.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TargetController;
|
||||
|
@ -50,6 +45,8 @@ import mage.filter.predicate.mageobject.ChosenSubtypePredicate;
|
|||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Saga
|
||||
|
@ -64,7 +61,7 @@ public class HeraldsHorn extends CardImpl {
|
|||
|
||||
// Creature spells you cast of the chosen type cost {1} less to cast.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
|
||||
new SpellsCostReductionAllOfChosenSubtypeEffect(new FilterCreatureCard("Creature spells you cast of the chosen type"), 1)));
|
||||
new SpellsCostReductionControllerEffect(new FilterCreatureCard("Creature spells you cast of the chosen type"), 1)));
|
||||
|
||||
// At the beginning of your upkeep, look at the top card of your library. If it's a creature card of the chosen type, you may reveal it and put it into your hand.
|
||||
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new HeraldsHornEffect(), TargetController.YOU, false));
|
||||
|
|
|
@ -112,6 +112,7 @@ class HeroismEffect extends OneShotEffect {
|
|||
Cost cost = new ManaCostsImpl("{2}{R}");
|
||||
List<Permanent> permanentsToPrevent = new ArrayList<>();
|
||||
for (Permanent permanent : game.getState().getBattlefield().getAllActivePermanents(filter, player.getId(), game)) {
|
||||
cost.clearPaid();
|
||||
String message = "Pay " + cost.getText() + "? If you don't, " + permanent.getLogName() + "'s combat damage will be prevented this turn.";
|
||||
if (player != null && player.chooseUse(Outcome.Neutral, message, source, game)) {
|
||||
if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) {
|
||||
|
|
76
Mage.Sets/src/mage/cards/j/JovensTools.java
Normal file
76
Mage.Sets/src/mage/cards/j/JovensTools.java
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.j;
|
||||
|
||||
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.effects.common.combat.CantBeBlockedByAllTargetEffect;
|
||||
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.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class JovensTools extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("except by walls");
|
||||
static {
|
||||
filter.add(Predicates.not(new SubtypePredicate(SubType.WALL)));
|
||||
}
|
||||
|
||||
public JovensTools(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{6}");
|
||||
|
||||
// {4}, {T}: Target creature can't be blocked this turn except by Walls.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantBeBlockedByAllTargetEffect(filter, Duration.EndOfTurn), new GenericManaCost(4));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addTarget(new TargetCreaturePermanent());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
public JovensTools(final JovensTools card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JovensTools copy() {
|
||||
return new JovensTools(this);
|
||||
}
|
||||
}
|
73
Mage.Sets/src/mage/cards/k/KjeldoranWarCry.java
Normal file
73
Mage.Sets/src/mage/cards/k/KjeldoranWarCry.java
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.k;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.dynamicvalue.IntPlusDynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.CardsInAllGraveyardsCount;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class KjeldoranWarCry extends CardImpl {
|
||||
|
||||
private static final FilterCard filter = new FilterCard("cards named Kjeldoran War Cry");
|
||||
|
||||
static {
|
||||
filter.add(new NamePredicate("Kjeldoran War Cry"));
|
||||
}
|
||||
|
||||
public KjeldoranWarCry(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}");
|
||||
|
||||
// Creatures you control get +X/+X until end of turn, where X is 1 plus the number of cards named Kjeldoran War Cry in all graveyards.
|
||||
IntPlusDynamicValue value = new IntPlusDynamicValue(1, new CardsInAllGraveyardsCount(filter));
|
||||
Effect effect = new BoostControlledEffect(value, value, Duration.EndOfTurn, new FilterCreaturePermanent("creatures"), false, true);
|
||||
effect.setText("Creatures you control get +X/+X until end of turn, where X is 1 plus the number of cards named {source} in all graveyards");
|
||||
this.getSpellAbility().addEffect(effect);
|
||||
}
|
||||
|
||||
public KjeldoranWarCry(final KjeldoranWarCry card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KjeldoranWarCry copy() {
|
||||
return new KjeldoranWarCry(this);
|
||||
}
|
||||
}
|
135
Mage.Sets/src/mage/cards/m/MammothHarness.java
Normal file
135
Mage.Sets/src/mage/cards/m/MammothHarness.java
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.m;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BlocksOrBecomesBlockedTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.common.AttachEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||
import mage.abilities.effects.common.continuous.LoseAbilityAttachedEffect;
|
||||
import mage.abilities.keyword.EnchantAbility;
|
||||
import mage.abilities.keyword.FirstStrikeAbility;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AttachmentType;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class MammothHarness extends CardImpl {
|
||||
|
||||
public MammothHarness(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{G}");
|
||||
this.subtype.add(SubType.AURA);
|
||||
|
||||
// Enchant creature
|
||||
TargetPermanent auraTarget = new TargetCreaturePermanent();
|
||||
this.getSpellAbility().addTarget(auraTarget);
|
||||
this.getSpellAbility().addEffect(new AttachEffect(Outcome.LoseAbility));
|
||||
Ability ability = new EnchantAbility(auraTarget.getTargetName());
|
||||
this.addAbility(ability);
|
||||
|
||||
// Enchanted creature loses flying.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LoseAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA)));
|
||||
|
||||
// Whenever enchanted creature blocks or becomes blocked by a creature, the other creature gains first strike until end of turn.
|
||||
this.addAbility(new MammothHarnessTriggeredAbility());
|
||||
}
|
||||
|
||||
public MammothHarness(final MammothHarness card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MammothHarness copy() {
|
||||
return new MammothHarness(this);
|
||||
}
|
||||
}
|
||||
|
||||
class MammothHarnessTriggeredAbility extends BlocksOrBecomesBlockedTriggeredAbility {
|
||||
|
||||
public MammothHarnessTriggeredAbility() {
|
||||
super(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn), StaticFilters.FILTER_PERMANENT_CREATURE, false, null, false);
|
||||
}
|
||||
|
||||
public MammothHarnessTriggeredAbility(final MammothHarnessTriggeredAbility ability) {
|
||||
super(ability);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(this.getSourceId());
|
||||
if (sourcePermanent != null) {
|
||||
Permanent attachedTo = game.getPermanentOrLKIBattlefield(sourcePermanent.getAttachedTo());
|
||||
if (sourcePermanent != null) {
|
||||
if (event.getSourceId().equals(attachedTo.getId())) {
|
||||
Permanent blocked = game.getPermanent(event.getTargetId());
|
||||
if (blocked != null && filter.match(blocked, game)) {
|
||||
this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (event.getTargetId().equals(attachedTo.getId())) {
|
||||
Permanent blocker = game.getPermanent(event.getSourceId());
|
||||
if (blocker != null) {
|
||||
this.getEffects().setTargetPointer(new FixedTarget(event.getSourceId()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return " Whenever enchanted creature blocks or becomes blocked by a creature, the other creature gains first strike until end of turn.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public MammothHarnessTriggeredAbility copy() {
|
||||
return new MammothHarnessTriggeredAbility(this);
|
||||
}
|
||||
}
|
172
Mage.Sets/src/mage/cards/m/Merseine.java
Normal file
172
Mage.Sets/src/mage/cards/m/Merseine.java
Normal file
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.m;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.SourceHasCounterCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.Effects;
|
||||
import mage.abilities.effects.common.AttachEffect;
|
||||
import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
|
||||
import mage.abilities.keyword.EnchantAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class Merseine extends CardImpl {
|
||||
|
||||
public Merseine(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.Detriment));
|
||||
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
|
||||
|
||||
// Merseine enters the battlefield with three net counters on it.
|
||||
Effect effect = new AddCountersSourceEffect(CounterType.NET.createInstance(3));
|
||||
effect.setText("with three net counters on it");
|
||||
this.addAbility(new EntersBattlefieldAbility(effect));
|
||||
|
||||
// Enchanted creature doesn't untap during its controller's untap step if Merseine has a net counter on it.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepEnchantedEffect(),
|
||||
new SourceHasCounterCondition(CounterType.NET)).setText("Enchanted creature doesn't untap during its controller's untap step if Merseine has a net counter on it")));
|
||||
|
||||
// Pay enchanted creature's mana cost: Remove a net counter from Merseine. Any player may activate this ability, but only if he or she controls the enchanted creature.
|
||||
SimpleActivatedAbility ability = new MerseineActivatedAbility();
|
||||
ability.setMayActivate(TargetController.ANY);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
public Merseine(final Merseine card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Merseine copy() {
|
||||
return new Merseine(this);
|
||||
}
|
||||
}
|
||||
|
||||
class MerseineActivatedAbility extends SimpleActivatedAbility {
|
||||
|
||||
public MerseineActivatedAbility() {
|
||||
super(Zone.BATTLEFIELD, new RemoveCounterSourceEffect(CounterType.NET.createInstance()), new MerseineCost());
|
||||
}
|
||||
|
||||
private MerseineActivatedAbility(final MerseineActivatedAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Effects getEffects(Game game, EffectType effectType) {
|
||||
return super.getEffects(game, effectType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canActivate(UUID playerId, Game game) {
|
||||
Permanent sourcePermanent = game.getBattlefield().getPermanent(this.getSourceId());
|
||||
if (sourcePermanent != null) {
|
||||
Permanent attachedTo = game.getPermanent(sourcePermanent.getAttachedTo());
|
||||
if (attachedTo != null) {
|
||||
return super.canActivate(attachedTo.getControllerId(), game);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MerseineActivatedAbility copy() {
|
||||
return new MerseineActivatedAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Pay enchanted creature's mana cost: Remove a net counter from Merseine. Any player may activate this ability, but only if he or she controls the enchanted creature.";
|
||||
}
|
||||
}
|
||||
|
||||
class MerseineCost extends CostImpl {
|
||||
|
||||
public MerseineCost() {
|
||||
this.text = "Pay enchanted creature's mana cost";
|
||||
}
|
||||
|
||||
public MerseineCost(final MerseineCost cost) {
|
||||
super(cost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MerseineCost copy() {
|
||||
return new MerseineCost(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
|
||||
Permanent sourcePermanent = game.getBattlefield().getPermanent(sourceId);
|
||||
if (sourcePermanent != null) {
|
||||
Permanent attachedTo = game.getPermanent(sourcePermanent.getAttachedTo());
|
||||
if (attachedTo != null) {
|
||||
return attachedTo.getManaCost().canPay(ability, sourceId, controllerId, game);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||
Permanent sourcePermanent = game.getBattlefield().getPermanent(sourceId);
|
||||
if (sourcePermanent != null) {
|
||||
Permanent attachedTo = game.getPermanent(sourcePermanent.getAttachedTo());
|
||||
if (attachedTo != null) {
|
||||
paid = attachedTo.getManaCost().pay(ability, game, sourceId, controllerId, noMana);
|
||||
}
|
||||
}
|
||||
return paid;
|
||||
}
|
||||
}
|
79
Mage.Sets/src/mage/cards/p/PaladinOfAtonement.java
Normal file
79
Mage.Sets/src/mage/cards/p/PaladinOfAtonement.java
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.p;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.common.DiesTriggeredAbility;
|
||||
import mage.abilities.condition.common.LiveLostLastTurnCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.common.SourcePermanentToughnessValue;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.counters.CounterType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class PaladinOfAtonement extends CardImpl {
|
||||
|
||||
public PaladinOfAtonement(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
|
||||
|
||||
this.subtype.add(SubType.VAMPIRE);
|
||||
this.subtype.add(SubType.KNIGHT);
|
||||
this.power = new MageInt(1);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
// At the beginning of each upkeep, if you lost life last turn, put a +1/+1 counter on Paladin of Atonement.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), TargetController.ANY, false),
|
||||
LiveLostLastTurnCondition.instance,
|
||||
"At the beginning of each upkeep, if you lost life last turn, put a +1/+1 counter on {this}"));
|
||||
|
||||
// When Paladin of Atonement dies, you gain life equal to it's toughness.
|
||||
this.addAbility(new DiesTriggeredAbility(new GainLifeEffect(SourcePermanentToughnessValue.getInstance(),
|
||||
"you gain life equal to it's toughness")));
|
||||
}
|
||||
|
||||
public PaladinOfAtonement(final PaladinOfAtonement card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaladinOfAtonement copy() {
|
||||
return new PaladinOfAtonement(this);
|
||||
}
|
||||
}
|
164
Mage.Sets/src/mage/cards/r/RaidingParty.java
Normal file
164
Mage.Sets/src/mage/cards/r/RaidingParty.java
Normal file
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.r;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.common.SacrificeTargetCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CantBeTargetedSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterObject;
|
||||
import mage.filter.FilterStackObject;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||
import mage.filter.predicate.permanent.TappedPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class RaidingParty extends CardImpl {
|
||||
|
||||
private static final FilterObject filterWhite = new FilterStackObject("white spells or abilities from white sources");
|
||||
private static final FilterControlledCreaturePermanent filterOrc = new FilterControlledCreaturePermanent("an Orc");
|
||||
|
||||
static {
|
||||
filterWhite.add(new ColorPredicate(ObjectColor.WHITE));
|
||||
filterOrc.add(new SubtypePredicate(SubType.ORC));
|
||||
}
|
||||
|
||||
public RaidingParty(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}");
|
||||
|
||||
// Raiding Party can't be the target of white spells or abilities from white sources.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeTargetedSourceEffect(filterWhite, Duration.WhileOnBattlefield)));
|
||||
|
||||
// Sacrifice an Orc: Each player may tap any number of untapped white creatures he or she controls. For each creature tapped this way, that player chooses up to two Plains. Then destroy all Plains that weren't chosen this way by any player.
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RaidingPartyEffect(), new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, filterOrc, true))));
|
||||
}
|
||||
|
||||
public RaidingParty(final RaidingParty card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaidingParty copy() {
|
||||
return new RaidingParty(this);
|
||||
}
|
||||
}
|
||||
|
||||
class RaidingPartyEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped white creatures");
|
||||
private static final FilterPermanent filter2 = new FilterPermanent("Plains");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(new TappedPredicate()));
|
||||
filter.add(new ColorPredicate(ObjectColor.WHITE));
|
||||
filter2.add(new SubtypePredicate(SubType.PLAINS));
|
||||
}
|
||||
|
||||
RaidingPartyEffect() {
|
||||
super(Outcome.Detriment);
|
||||
staticText = "Each player may tap any number of untapped white creatures he or she controls. For each creature tapped this way, that player chooses up to two Plains. Then destroy all Plains that weren't chosen this way by any player";
|
||||
}
|
||||
|
||||
RaidingPartyEffect(RaidingPartyEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaidingPartyEffect copy() {
|
||||
return new RaidingPartyEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||
if (sourcePermanent != null) {
|
||||
Set<UUID> plainsToSave = new HashSet<>();
|
||||
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
int countBattlefield = game.getBattlefield().getAllActivePermanents(filter, game.getActivePlayerId(), game).size();
|
||||
int tappedCount = 0;
|
||||
Target untappedCreatureTarget = new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, filter, true);
|
||||
if (player.choose(Outcome.Benefit, untappedCreatureTarget, source.getSourceId(), game)) {
|
||||
tappedCount = untappedCreatureTarget.getTargets().size();
|
||||
for (UUID creatureId : untappedCreatureTarget.getTargets()) {
|
||||
Permanent creature = game.getPermanentOrLKIBattlefield(creatureId);
|
||||
if (creature != null) {
|
||||
creature.tap(game);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tappedCount > 0) {
|
||||
Target plainsToSaveTarget = new TargetPermanent(0, tappedCount * 2, filter2, true);
|
||||
if (player.choose(Outcome.Benefit, plainsToSaveTarget, source.getSourceId(), game)) {
|
||||
for (UUID plainsId : plainsToSaveTarget.getTargets()) {
|
||||
plainsToSave.add(plainsId);
|
||||
Permanent plains = game.getPermanent(plainsId);
|
||||
if (plains != null) {
|
||||
game.informPlayers(player.getLogName() + " chose " + plains.getLogName() + " to not be destroyed by " + sourcePermanent.getLogName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Permanent plains : game.getBattlefield().getActivePermanents(filter2, source.getControllerId(), source.getSourceId(), game)) {
|
||||
if (!plainsToSave.contains(plains.getId())) {
|
||||
plains.destroy(source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
127
Mage.Sets/src/mage/cards/r/RashkaTheSlayer.java
Normal file
127
Mage.Sets/src/mage/cards/r/RashkaTheSlayer.java
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.r;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.keyword.ReachAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class RashkaTheSlayer extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("black creature");
|
||||
|
||||
static {
|
||||
filter.add(new ColorPredicate(ObjectColor.BLACK));
|
||||
}
|
||||
|
||||
public RashkaTheSlayer(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}");
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.ARCHER);
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
// Reach
|
||||
this.addAbility(ReachAbility.getInstance());
|
||||
|
||||
// Whenever Rashka the Slayer blocks one or more black creatures, Rashka gets +1/+2 until end of turn.
|
||||
this.addAbility(new RashkaTheSlayerTriggeredAbility(new BoostSourceEffect(1, 2, Duration.EndOfTurn), filter, false));
|
||||
}
|
||||
|
||||
public RashkaTheSlayer(final RashkaTheSlayer card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RashkaTheSlayer copy() {
|
||||
return new RashkaTheSlayer(this);
|
||||
}
|
||||
}
|
||||
|
||||
class RashkaTheSlayerTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
protected FilterPermanent filter;
|
||||
|
||||
public RashkaTheSlayerTriggeredAbility(Effect effect, FilterPermanent filter, boolean optional) {
|
||||
super(Zone.BATTLEFIELD, effect, optional);
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public RashkaTheSlayerTriggeredAbility(final RashkaTheSlayerTriggeredAbility ability) {
|
||||
super(ability);
|
||||
this.filter = ability.filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.BLOCKER_DECLARED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getSourceId().equals(this.getSourceId())) {
|
||||
Permanent blocked = game.getPermanent(event.getTargetId());
|
||||
if (blocked != null && filter.match(blocked, game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever {this} blocks a " + filter.getMessage() + ", " + super.getRule();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RashkaTheSlayerTriggeredAbility copy() {
|
||||
return new RashkaTheSlayerTriggeredAbility(this);
|
||||
}
|
||||
}
|
|
@ -62,7 +62,7 @@ public class TheImmortalSun extends CardImpl {
|
|||
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
|
||||
// Players can't activate loyalty abilities of planeswalkers.
|
||||
// Players can't activate planeswalkers' loyalty abilities.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TheImmortalSunCantActivateEffect()));
|
||||
// At the beginning of your draw step, draw an additional card.
|
||||
this.addAbility(new BeginningOfDrawTriggeredAbility(new DrawCardSourceControllerEffect(1), TargetController.YOU, false));
|
||||
|
@ -86,7 +86,7 @@ class TheImmortalSunCantActivateEffect extends ContinuousRuleModifyingEffectImpl
|
|||
|
||||
public TheImmortalSunCantActivateEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Detriment);
|
||||
staticText = "Players can't activate loyalty abilities of planeswalkers";
|
||||
staticText = "Players can't activate planeswalkers' loyalty abilities";
|
||||
}
|
||||
|
||||
public TheImmortalSunCantActivateEffect(final TheImmortalSunCantActivateEffect effect) {
|
||||
|
|
126
Mage.Sets/src/mage/cards/t/ThelonsChant.java
Normal file
126
Mage.Sets/src/mage/cards/t/ThelonsChant.java
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.t;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SetTargetPointer;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class ThelonsChant extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterPermanent("a Swamp");
|
||||
|
||||
static{
|
||||
filter.add(new SubtypePredicate(SubType.SWAMP));
|
||||
}
|
||||
|
||||
public ThelonsChant(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}{G}");
|
||||
|
||||
// At the beginning of your upkeep, sacrifice Thelon's Chant unless you pay {G}.
|
||||
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl("{G}")), TargetController.YOU, false));
|
||||
|
||||
// Whenever a player puts a Swamp onto the battlefield, Thelon's Chant deals 3 damage to that player unless he or she puts a -1/-1 counter on a creature he or she controls.
|
||||
this.addAbility(new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new ThelonsChantEffect(), filter, false, SetTargetPointer.PLAYER,
|
||||
"Whenever a player puts a Swamp onto the battlefield, {this} deals 3 damage to that player unless he or she puts a -1/-1 counter on a creature he or she controls."));
|
||||
}
|
||||
|
||||
public ThelonsChant(final ThelonsChant card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThelonsChant copy() {
|
||||
return new ThelonsChant(this);
|
||||
}
|
||||
}
|
||||
|
||||
class ThelonsChantEffect extends OneShotEffect {
|
||||
|
||||
public ThelonsChantEffect() {
|
||||
super(Outcome.Damage);
|
||||
staticText = "{this} deals 3 damage to that player unless he or she puts a -1/-1 counter on a creature he or she controls";
|
||||
}
|
||||
|
||||
public ThelonsChantEffect(final ThelonsChantEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThelonsChantEffect copy() {
|
||||
return new ThelonsChantEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(targetPointer.getFirst(game, source));
|
||||
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||
if (player != null && sourcePermanent != null) {
|
||||
boolean paid = false;
|
||||
TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent();
|
||||
target.setNotTarget(true);
|
||||
if (player.chooseUse(Outcome.Detriment, "Put a -1/-1 counter on a creature you control? (otherwise " + sourcePermanent.getLogName() + " deals 3 damage to you)", source, game)
|
||||
&& player.choose(Outcome.UnboostCreature, target, source.getSourceId(), game)) {
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
if (permanent != null) {
|
||||
permanent.addCounters(CounterType.M1M1.createInstance(), source, game);
|
||||
paid = true;
|
||||
}
|
||||
}
|
||||
if (!paid) {
|
||||
player.damage(3, source.getSourceId(), game, false, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
129
Mage.Sets/src/mage/cards/t/ThermalFlux.java
Normal file
129
Mage.Sets/src/mage/cards/t/ThermalFlux.java
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.t;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.common.delayed.AtTheBeginOfNextUpkeepDelayedTriggeredAbility;
|
||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.constants.SuperType;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Layer;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubLayer;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.SupertypePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801 & L_J
|
||||
*/
|
||||
public class ThermalFlux extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filterNonsnow = new FilterPermanent("nonsnow permanent");
|
||||
private static final FilterPermanent filterSnow = new FilterPermanent("snow permanent");
|
||||
|
||||
static {
|
||||
filterNonsnow.add(Predicates.not(new SupertypePredicate(SuperType.SNOW)));
|
||||
filterSnow.add(new SupertypePredicate(SuperType.SNOW));
|
||||
}
|
||||
|
||||
public ThermalFlux(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}");
|
||||
|
||||
// Choose one -
|
||||
// Target nonsnow permanent becomes snow until end of turn.
|
||||
// Draw a card at the beginning of the next turn's upkeep.
|
||||
this.getSpellAbility().addTarget(new TargetPermanent(filterNonsnow));
|
||||
this.getSpellAbility().addEffect(new ThermalFluxEffect(true));
|
||||
this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(
|
||||
new AtTheBeginOfNextUpkeepDelayedTriggeredAbility(new DrawCardSourceControllerEffect(1)), false));
|
||||
// Target snow permanent isn't snow until end of turn.
|
||||
// Draw a card at the beginning of the next turn's upkeep.
|
||||
Mode mode = new Mode();
|
||||
mode.getTargets().add(new TargetPermanent(filterSnow));
|
||||
mode.getEffects().add(new ThermalFluxEffect(false));
|
||||
mode.getEffects().add(new CreateDelayedTriggeredAbilityEffect(
|
||||
new AtTheBeginOfNextUpkeepDelayedTriggeredAbility(new DrawCardSourceControllerEffect(1)), false));
|
||||
this.getSpellAbility().addMode(mode);
|
||||
|
||||
}
|
||||
|
||||
public ThermalFlux(final ThermalFlux card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThermalFlux copy() {
|
||||
return new ThermalFlux(this);
|
||||
}
|
||||
}
|
||||
|
||||
class ThermalFluxEffect extends ContinuousEffectImpl {
|
||||
|
||||
private final boolean addSnow;
|
||||
|
||||
public ThermalFluxEffect(boolean addSnow) {
|
||||
super(Duration.EndOfTurn, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment);
|
||||
this.addSnow = addSnow;
|
||||
this.staticText = "Target " + (addSnow ? "non" : "") + "snow permanent " + (addSnow ? "becomes" : "isn't") + " snow until end of turn";
|
||||
}
|
||||
|
||||
public ThermalFluxEffect(final ThermalFluxEffect effect) {
|
||||
super(effect);
|
||||
this.addSnow = effect.addSnow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThermalFluxEffect copy() {
|
||||
return new ThermalFluxEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||
if (permanent != null) {
|
||||
if (addSnow) {
|
||||
permanent.addSuperType(SuperType.SNOW);
|
||||
} else {
|
||||
permanent.getSuperType().remove(SuperType.SNOW);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
144
Mage.Sets/src/mage/cards/t/TidalFlats.java
Normal file
144
Mage.Sets/src/mage/cards/t/TidalFlats.java
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.t;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||
import mage.abilities.keyword.FirstStrikeAbility;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterAttackingCreature;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.AbilityPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.combat.CombatGroup;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class TidalFlats extends CardImpl {
|
||||
|
||||
public TidalFlats(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{U}");
|
||||
|
||||
// {U}{U}: For each attacking creature without flying, its controller may pay {1}. If he or she doesn't, creatures you control blocking that creature gain first strike until end of turn.
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new TidalFlatsEffect(), new ManaCostsImpl("{U}{U}")));
|
||||
}
|
||||
|
||||
public TidalFlats(final TidalFlats card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TidalFlats copy() {
|
||||
return new TidalFlats(this);
|
||||
}
|
||||
}
|
||||
|
||||
class TidalFlatsEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterAttackingCreature filter = new FilterAttackingCreature("attacking creature without flying");
|
||||
static {
|
||||
filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
|
||||
}
|
||||
|
||||
public TidalFlatsEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "For each attacking creature without flying, its controller may pay {1}. If he or she doesn't, creatures you control blocking that creature gain first strike until end of turn";
|
||||
}
|
||||
|
||||
public TidalFlatsEffect(final TidalFlatsEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TidalFlatsEffect copy() {
|
||||
return new TidalFlatsEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
game.getPlayerList();
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
Player player = game.getPlayer(game.getActivePlayerId());
|
||||
Cost cost = new ManaCostsImpl("{1}");
|
||||
List<Permanent> affectedPermanents = new ArrayList<>();
|
||||
for (Permanent permanent : game.getState().getBattlefield().getAllActivePermanents(filter, player.getId(), game)) {
|
||||
cost.clearPaid();
|
||||
String message = "Pay " + cost.getText() + " for " + permanent.getLogName() + "? If you don't, creatures " + controller.getLogName() + " controls blocking it gain first strike until end of turn.";
|
||||
if (player != null && player.chooseUse(Outcome.Benefit, message, source, game)) {
|
||||
if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) {
|
||||
game.informPlayers(player.getLogName() + " paid " + cost.getText() + " for " + permanent.getLogName());
|
||||
continue;
|
||||
} else {
|
||||
game.informPlayers(player.getLogName() + " didn't pay " + cost.getText() + " for " + permanent.getLogName());
|
||||
affectedPermanents.add(permanent);
|
||||
}
|
||||
} else {
|
||||
game.informPlayers(player.getLogName() + " didn't pay " + cost.getText() + " for " + permanent.getLogName());
|
||||
affectedPermanents.add(permanent);
|
||||
}
|
||||
}
|
||||
|
||||
for (Permanent permanent : affectedPermanents) {
|
||||
CombatGroup group = game.getCombat().findGroup(permanent.getId());
|
||||
if (group != null) {
|
||||
for (UUID blockerId : group.getBlockers()) {
|
||||
Permanent blocker = game.getPermanent(blockerId);
|
||||
if (blocker != null && blocker.getControllerId() == controller.getId()) {
|
||||
ContinuousEffect effect = new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn);
|
||||
effect.setTargetPointer(new FixedTarget(blocker.getId()));
|
||||
game.addEffect(effect, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
126
Mage.Sets/src/mage/cards/t/TourachsChant.java
Normal file
126
Mage.Sets/src/mage/cards/t/TourachsChant.java
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.t;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SetTargetPointer;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class TourachsChant extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterPermanent("a Forest");
|
||||
|
||||
static{
|
||||
filter.add(new SubtypePredicate(SubType.FOREST));
|
||||
}
|
||||
|
||||
public TourachsChant(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{B}");
|
||||
|
||||
// At the beginning of your upkeep, sacrifice Tourach's Chant unless you pay {B}.
|
||||
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl("{B}")), TargetController.YOU, false));
|
||||
|
||||
// Whenever a player puts a Forest onto the battlefield, Tourach's Chant deals 3 damage to that player unless he or she puts a -1/-1 counter on a creature he or she controls.
|
||||
this.addAbility(new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new TourachsChantEffect(), filter, false, SetTargetPointer.PLAYER,
|
||||
"Whenever a player puts a Forest onto the battlefield, {this} deals 3 damage to that player unless he or she puts a -1/-1 counter on a creature he or she controls."));
|
||||
}
|
||||
|
||||
public TourachsChant(final TourachsChant card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TourachsChant copy() {
|
||||
return new TourachsChant(this);
|
||||
}
|
||||
}
|
||||
|
||||
class TourachsChantEffect extends OneShotEffect {
|
||||
|
||||
public TourachsChantEffect() {
|
||||
super(Outcome.Damage);
|
||||
staticText = "{this} deals 3 damage to that player unless he or she puts a -1/-1 counter on a creature he or she controls";
|
||||
}
|
||||
|
||||
public TourachsChantEffect(final TourachsChantEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TourachsChantEffect copy() {
|
||||
return new TourachsChantEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(targetPointer.getFirst(game, source));
|
||||
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||
if (player != null && sourcePermanent != null) {
|
||||
boolean paid = false;
|
||||
TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent();
|
||||
target.setNotTarget(true);
|
||||
if (player.chooseUse(Outcome.Detriment, "Put a -1/-1 counter on a creature you control? (otherwise " + sourcePermanent.getLogName() + " deals 3 damage to you)", source, game)
|
||||
&& player.choose(Outcome.UnboostCreature, target, source.getSourceId(), game)) {
|
||||
Permanent permanent = game.getPermanent(target.getFirstTarget());
|
||||
if (permanent != null) {
|
||||
permanent.addCounters(CounterType.M1M1.createInstance(), source, game);
|
||||
paid = true;
|
||||
}
|
||||
}
|
||||
if (!paid) {
|
||||
player.damage(3, source.getSourceId(), game, false, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -51,7 +51,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
|
|||
public class Victimize extends CardImpl {
|
||||
|
||||
public Victimize(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}");
|
||||
|
||||
// Choose two target creature cards in your graveyard. Sacrifice a creature. If you do, return the chosen cards to the battlefield tapped.
|
||||
this.getSpellAbility().addEffect(new VictimizeEffect());
|
||||
|
@ -90,6 +90,7 @@ class VictimizeEffect extends OneShotEffect {
|
|||
if (controller != null) {
|
||||
SacrificeTargetCost cost = new SacrificeTargetCost(new TargetControlledCreaturePermanent(new FilterControlledCreaturePermanent("a creature")));
|
||||
if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false, null)) {
|
||||
game.applyEffects(); // To end effects of the sacrificed creature
|
||||
controller.moveCards(new CardsImpl(getTargetPointer().getTargets(game, source)).getCards(game),
|
||||
Zone.BATTLEFIELD, source, game, true, false, false, null);
|
||||
}
|
||||
|
|
190
Mage.Sets/src/mage/cards/v/VoidMaw.java
Normal file
190
Mage.Sets/src/mage/cards/v/VoidMaw.java
Normal file
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.cards.v;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.Cards;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInExile;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
* @author jeffwadsworth & L_J
|
||||
*/
|
||||
public class VoidMaw extends CardImpl {
|
||||
|
||||
public VoidMaw(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}");
|
||||
this.subtype.add(SubType.HORROR);
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(5);
|
||||
|
||||
// Trample
|
||||
this.addAbility(TrampleAbility.getInstance());
|
||||
|
||||
// If another creature would die, exile it instead.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new VoidMawEffect()));
|
||||
|
||||
// Put a card exiled with Void Maw into its owner's graveyard: Void Maw gets +2/+2 until end of turn.
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2, 2, Duration.EndOfTurn), new VoidMawCost()));
|
||||
}
|
||||
|
||||
public VoidMaw(final VoidMaw card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoidMaw copy() {
|
||||
return new VoidMaw(this);
|
||||
}
|
||||
}
|
||||
|
||||
class VoidMawEffect extends ReplacementEffectImpl {
|
||||
|
||||
public VoidMawEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
staticText = "If another creature would die, exile it instead";
|
||||
}
|
||||
|
||||
public VoidMawEffect(final VoidMawEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoidMawEffect copy() {
|
||||
return new VoidMawEffect(this);
|
||||
}
|
||||
|
||||
@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());
|
||||
MageObject sourceObject = source.getSourceObject(game);
|
||||
if (controller != null && sourceObject != null) {
|
||||
if (((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) {
|
||||
Permanent permanent = ((ZoneChangeEvent) event).getTarget();
|
||||
if (permanent != null) {
|
||||
UUID exileZoneId = CardUtil.getCardExileZoneId(game, source);
|
||||
if (controller.moveCardsToExile(permanent, source, game, false, exileZoneId, sourceObject.getIdName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checksEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
if (zEvent.getToZone() == Zone.GRAVEYARD) {
|
||||
Permanent permanent = ((ZoneChangeEvent) event).getTarget();
|
||||
if (permanent != null && permanent.getId() != source.getSourceId()) {
|
||||
if (zEvent.getTarget() != null) { // if it comes from permanent, check if it was a creature on the battlefield
|
||||
if (zEvent.getTarget().isCreature()) {
|
||||
return true;
|
||||
}
|
||||
} else if (permanent.isCreature()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class VoidMawCost extends CostImpl {
|
||||
|
||||
public VoidMawCost() {
|
||||
this.text = "Put a card exiled with {this} into its owner's graveyard";
|
||||
}
|
||||
|
||||
public VoidMawCost(VoidMawCost cost) {
|
||||
super(cost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
if (controller != null) {
|
||||
TargetCardInExile target = new TargetCardInExile(new FilterCard(), CardUtil.getCardExileZoneId(game, ability));
|
||||
target.setNotTarget(true);
|
||||
Cards cards = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, ability));
|
||||
if (!cards.isEmpty()
|
||||
&& controller.choose(Outcome.Benefit, cards, target, game)) {
|
||||
Card card = game.getCard(target.getFirstTarget());
|
||||
if (card != null) {
|
||||
if (controller.moveCardToGraveyardWithInfo(card, sourceId, game, Zone.EXILED)) {
|
||||
paid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return paid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
|
||||
Player player = game.getPlayer(controllerId);
|
||||
return player != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoidMawCost copy() {
|
||||
return new VoidMawCost(this);
|
||||
}
|
||||
}
|
|
@ -87,6 +87,7 @@ public class Coldsnap extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Disciple of Tevesh Szat", 55, Rarity.COMMON, mage.cards.d.DiscipleOfTeveshSzat.class));
|
||||
cards.add(new SetCardInfo("Drelnoch", 32, Rarity.COMMON, mage.cards.d.Drelnoch.class));
|
||||
cards.add(new SetCardInfo("Earthen Goo", 80, Rarity.UNCOMMON, mage.cards.e.EarthenGoo.class));
|
||||
cards.add(new SetCardInfo("Feast of Flesh", 56, Rarity.COMMON, mage.cards.f.FeastOfFlesh.class));
|
||||
cards.add(new SetCardInfo("Field Marshal", 5, Rarity.RARE, mage.cards.f.FieldMarshal.class));
|
||||
cards.add(new SetCardInfo("Flashfreeze", 33, Rarity.UNCOMMON, mage.cards.f.Flashfreeze.class));
|
||||
cards.add(new SetCardInfo("Freyalise's Radiance", 108, Rarity.UNCOMMON, mage.cards.f.FreyalisesRadiance.class));
|
||||
|
@ -123,6 +124,7 @@ public class Coldsnap extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Kjeldoran Gargoyle", 10, Rarity.UNCOMMON, mage.cards.k.KjeldoranGargoyle.class));
|
||||
cards.add(new SetCardInfo("Kjeldoran Javelineer", 11, Rarity.COMMON, mage.cards.k.KjeldoranJavelineer.class));
|
||||
cards.add(new SetCardInfo("Kjeldoran Outrider", 12, Rarity.COMMON, mage.cards.k.KjeldoranOutrider.class));
|
||||
cards.add(new SetCardInfo("Kjeldoran War Cry", 13, Rarity.COMMON, mage.cards.k.KjeldoranWarCry.class));
|
||||
cards.add(new SetCardInfo("Krovikan Mist", 38, Rarity.COMMON, mage.cards.k.KrovikanMist.class));
|
||||
cards.add(new SetCardInfo("Krovikan Rot", 63, Rarity.UNCOMMON, mage.cards.k.KrovikanRot.class));
|
||||
cards.add(new SetCardInfo("Krovikan Scoundrel", 64, Rarity.COMMON, mage.cards.k.KrovikanScoundrel.class));
|
||||
|
@ -189,6 +191,7 @@ public class Coldsnap extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Survivor of the Unseen", 48, Rarity.COMMON, mage.cards.s.SurvivorOfTheUnseen.class));
|
||||
cards.add(new SetCardInfo("Swift Maneuver", 21, Rarity.COMMON, mage.cards.s.SwiftManeuver.class));
|
||||
cards.add(new SetCardInfo("Tamanoa", 132, Rarity.RARE, mage.cards.t.Tamanoa.class));
|
||||
cards.add(new SetCardInfo("Thermal Flux", 49, Rarity.COMMON, mage.cards.t.ThermalFlux.class));
|
||||
cards.add(new SetCardInfo("Thermopod", 100, Rarity.COMMON, mage.cards.t.Thermopod.class));
|
||||
cards.add(new SetCardInfo("Thrumming Stone", 142, Rarity.RARE, mage.cards.t.ThrummingStone.class));
|
||||
cards.add(new SetCardInfo("Tresserhorn Sinks", 150, Rarity.UNCOMMON, mage.cards.t.TresserhornSinks.class));
|
||||
|
@ -196,6 +199,7 @@ public class Coldsnap extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Ursine Fylgja", 22, Rarity.UNCOMMON, mage.cards.u.UrsineFylgja.class));
|
||||
cards.add(new SetCardInfo("Vanish into Memory", 133, Rarity.UNCOMMON, mage.cards.v.VanishIntoMemory.class));
|
||||
cards.add(new SetCardInfo("Vexing Sphinx", 50, Rarity.RARE, mage.cards.v.VexingSphinx.class));
|
||||
cards.add(new SetCardInfo("Void Maw", 74, Rarity.RARE, mage.cards.v.VoidMaw.class));
|
||||
cards.add(new SetCardInfo("Wall of Shards", 23, Rarity.UNCOMMON, mage.cards.w.WallOfShards.class));
|
||||
cards.add(new SetCardInfo("White Shield Crusader", 24, Rarity.UNCOMMON, mage.cards.w.WhiteShieldCrusader.class));
|
||||
cards.add(new SetCardInfo("Wilderness Elemental", 134, Rarity.UNCOMMON, mage.cards.w.WildernessElemental.class));
|
||||
|
|
|
@ -188,6 +188,10 @@ public class FallenEmpires extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Initiates of the Ebon Hand", 16, Rarity.COMMON, InitiatesOfTheEbonHand.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Initiates of the Ebon Hand", 17, Rarity.COMMON, InitiatesOfTheEbonHand.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Initiates of the Ebon Hand", 18, Rarity.COMMON, InitiatesOfTheEbonHand.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Merseine", 47, Rarity.COMMON, mage.cards.m.Merseine.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Merseine", 48, Rarity.COMMON, mage.cards.m.Merseine.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Merseine", 49, Rarity.COMMON, mage.cards.m.Merseine.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Merseine", 50, Rarity.COMMON, mage.cards.m.Merseine.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Mindstab Thrull", 19, Rarity.COMMON, MindstabThrull.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Mindstab Thrull", 20, Rarity.COMMON, MindstabThrull.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Mindstab Thrull", 21, Rarity.COMMON, MindstabThrull.class, NON_FULL_USE_VARIOUS));
|
||||
|
@ -212,6 +216,7 @@ public class FallenEmpires extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Order of the Ebon Hand", 26, Rarity.COMMON, OrderOfTheEbonHand.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Order of the Ebon Hand", 27, Rarity.COMMON, OrderOfTheEbonHand.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Orgg", 131, Rarity.RARE, mage.cards.o.Orgg.class));
|
||||
cards.add(new SetCardInfo("Raiding Party", 132, Rarity.UNCOMMON, mage.cards.r.RaidingParty.class));
|
||||
cards.add(new SetCardInfo("Rainbow Vale", 184, Rarity.RARE, mage.cards.r.RainbowVale.class));
|
||||
cards.add(new SetCardInfo("Ring of Renewal", 174, Rarity.RARE, mage.cards.r.RingOfRenewal.class));
|
||||
cards.add(new SetCardInfo("River Merfolk", 51, Rarity.RARE, mage.cards.r.RiverMerfolk.class));
|
||||
|
@ -233,6 +238,7 @@ public class FallenEmpires extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Thallid Devourer", 91, Rarity.UNCOMMON, mage.cards.t.ThallidDevourer.class));
|
||||
cards.add(new SetCardInfo("Thelonite Druid", 92, Rarity.UNCOMMON, mage.cards.t.TheloniteDruid.class));
|
||||
cards.add(new SetCardInfo("Thelonite Monk", 93, Rarity.RARE, mage.cards.t.TheloniteMonk.class));
|
||||
cards.add(new SetCardInfo("Thelon's Chant", 94, Rarity.UNCOMMON, mage.cards.t.ThelonsChant.class));
|
||||
cards.add(new SetCardInfo("Thelon's Curse", 95, Rarity.RARE, mage.cards.t.ThelonsCurse.class));
|
||||
cards.add(new SetCardInfo("Thorn Thallid", 96, Rarity.COMMON, ThornThallid.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Thorn Thallid", 97, Rarity.COMMON, ThornThallid.class, NON_FULL_USE_VARIOUS));
|
||||
|
@ -241,7 +247,11 @@ public class FallenEmpires extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Thrull Champion", 29, Rarity.RARE, mage.cards.t.ThrullChampion.class));
|
||||
cards.add(new SetCardInfo("Thrull Retainer", 30, Rarity.UNCOMMON, mage.cards.t.ThrullRetainer.class));
|
||||
cards.add(new SetCardInfo("Thrull Wizard", 31, Rarity.UNCOMMON, mage.cards.t.ThrullWizard.class));
|
||||
cards.add(new SetCardInfo("Tidal Flats", 54, Rarity.COMMON, mage.cards.t.TidalFlats.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Tidal Flats", 55, Rarity.COMMON, mage.cards.t.TidalFlats.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Tidal Flats", 56, Rarity.COMMON, mage.cards.t.TidalFlats.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Tidal Influence", 57, Rarity.UNCOMMON, mage.cards.t.TidalInfluence.class));
|
||||
cards.add(new SetCardInfo("Tourach's Chant", 32, Rarity.UNCOMMON, mage.cards.t.TourachsChant.class));
|
||||
cards.add(new SetCardInfo("Tourach's Gate", 33, Rarity.RARE, mage.cards.t.TourachsGate.class));
|
||||
cards.add(new SetCardInfo("Vodalian Knights", 58, Rarity.RARE, mage.cards.v.VodalianKnights.class));
|
||||
cards.add(new SetCardInfo("Vodalian Mage", 59, Rarity.COMMON, VodalianMage.class, NON_FULL_USE_VARIOUS));
|
||||
|
|
|
@ -80,6 +80,7 @@ public class FifthEdition extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Brainwash", 289, Rarity.COMMON, mage.cards.b.Brainwash.class));
|
||||
cards.add(new SetCardInfo("Brassclaw Orcs", 213, Rarity.COMMON, BrassclawOrcs.class));
|
||||
cards.add(new SetCardInfo("Breeding Pit", 10, Rarity.UNCOMMON, mage.cards.b.BreedingPit.class));
|
||||
cards.add(new SetCardInfo("Broken Visage", 11, Rarity.RARE, mage.cards.b.BrokenVisage.class));
|
||||
cards.add(new SetCardInfo("Brothers of Fire", 214, Rarity.COMMON, mage.cards.b.BrothersOfFire.class));
|
||||
cards.add(new SetCardInfo("Brushland", 412, Rarity.RARE, mage.cards.b.Brushland.class));
|
||||
cards.add(new SetCardInfo("Carapace", 143, Rarity.COMMON, mage.cards.c.Carapace.class));
|
||||
|
@ -242,6 +243,7 @@ public class FifthEdition extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Jester's Cap", 385, Rarity.RARE, mage.cards.j.JestersCap.class));
|
||||
cards.add(new SetCardInfo("Johtull Wurm", 168, Rarity.UNCOMMON, mage.cards.j.JohtullWurm.class));
|
||||
cards.add(new SetCardInfo("Jokulhaups", 246, Rarity.RARE, mage.cards.j.Jokulhaups.class));
|
||||
cards.add(new SetCardInfo("Joven's Tools", 386, Rarity.UNCOMMON, mage.cards.j.JovensTools.class));
|
||||
cards.add(new SetCardInfo("Justice", 317, Rarity.UNCOMMON, mage.cards.j.Justice.class));
|
||||
cards.add(new SetCardInfo("Juxtapose", 95, Rarity.RARE, mage.cards.j.Juxtapose.class));
|
||||
cards.add(new SetCardInfo("Karma", 318, Rarity.UNCOMMON, mage.cards.k.Karma.class));
|
||||
|
|
|
@ -83,6 +83,8 @@ public class Homelands extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("An-Havva Inn", 52, Rarity.UNCOMMON, mage.cards.a.AnHavvaInn.class));
|
||||
cards.add(new SetCardInfo("An-Havva Township", 136, Rarity.UNCOMMON, mage.cards.a.AnHavvaTownship.class));
|
||||
cards.add(new SetCardInfo("An-Zerrin Ruins", 87, Rarity.RARE, mage.cards.a.AnZerrinRuins.class));
|
||||
cards.add(new SetCardInfo("Apocalypse Chime", 126, Rarity.RARE, mage.cards.a.ApocalypseChime.class));
|
||||
cards.add(new SetCardInfo("Autumn Willow", 53, Rarity.RARE, mage.cards.a.AutumnWillow.class));
|
||||
cards.add(new SetCardInfo("Aysen Abbey", 137, Rarity.UNCOMMON, mage.cards.a.AysenAbbey.class));
|
||||
cards.add(new SetCardInfo("Aysen Bureaucrats", 104, Rarity.COMMON, mage.cards.a.AysenBureaucrats.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Aysen Bureaucrats", 105, Rarity.COMMON, mage.cards.a.AysenBureaucrats.class, NON_FULL_USE_VARIOUS));
|
||||
|
@ -91,6 +93,7 @@ public class Homelands extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Baki's Curse", 27, Rarity.RARE, mage.cards.b.BakisCurse.class));
|
||||
cards.add(new SetCardInfo("Baron Sengir", 1, Rarity.RARE, mage.cards.b.BaronSengir.class));
|
||||
cards.add(new SetCardInfo("Black Carriage", 2, Rarity.RARE, mage.cards.b.BlackCarriage.class));
|
||||
cards.add(new SetCardInfo("Broken Visage", 3, Rarity.RARE, mage.cards.b.BrokenVisage.class));
|
||||
cards.add(new SetCardInfo("Carapace", 54, Rarity.COMMON, mage.cards.c.Carapace.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Carapace", 55, Rarity.COMMON, mage.cards.c.Carapace.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Castle Sengir", 138, Rarity.UNCOMMON, mage.cards.c.CastleSengir.class));
|
||||
|
@ -124,6 +127,7 @@ public class Homelands extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Forget", 32, Rarity.RARE, mage.cards.f.Forget.class));
|
||||
cards.add(new SetCardInfo("Ghost Hounds", 12, Rarity.UNCOMMON, mage.cards.g.GhostHounds.class));
|
||||
cards.add(new SetCardInfo("Grandmother Sengir", 13, Rarity.RARE, mage.cards.g.GrandmotherSengir.class));
|
||||
cards.add(new SetCardInfo("Hazduhr the Abbot", 110, Rarity.RARE, mage.cards.h.HazduhrTheAbbot.class));
|
||||
cards.add(new SetCardInfo("Headstone", 15, Rarity.COMMON, mage.cards.h.Headstone.class));
|
||||
cards.add(new SetCardInfo("Hungry Mist", 60, Rarity.COMMON, mage.cards.h.HungryMist.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Hungry Mist", 61, Rarity.COMMON, mage.cards.h.HungryMist.class, NON_FULL_USE_VARIOUS));
|
||||
|
@ -131,11 +135,13 @@ public class Homelands extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Irini Sengir", 17, Rarity.UNCOMMON, mage.cards.i.IriniSengir.class));
|
||||
cards.add(new SetCardInfo("Jinx", 36, Rarity.COMMON, mage.cards.j.Jinx.class));
|
||||
cards.add(new SetCardInfo("Joven", 97, Rarity.COMMON, mage.cards.j.Joven.class));
|
||||
cards.add(new SetCardInfo("Joven's Tools", 133, Rarity.UNCOMMON, mage.cards.j.JovensTools.class));
|
||||
cards.add(new SetCardInfo("Koskun Falls", 18, Rarity.RARE, mage.cards.k.KoskunFalls.class));
|
||||
cards.add(new SetCardInfo("Koskun Keep", 139, Rarity.UNCOMMON, mage.cards.k.KoskunKeep.class));
|
||||
cards.add(new SetCardInfo("Labyrinth Minotaur", 38, Rarity.COMMON, mage.cards.l.LabyrinthMinotaur.class));
|
||||
cards.add(new SetCardInfo("Leaping Lizard", 63, Rarity.COMMON, mage.cards.l.LeapingLizard.class));
|
||||
cards.add(new SetCardInfo("Leeches", 111, Rarity.RARE, mage.cards.l.Leeches.class));
|
||||
cards.add(new SetCardInfo("Mammoth Harness", 64, Rarity.RARE, mage.cards.m.MammothHarness.class));
|
||||
cards.add(new SetCardInfo("Marjhan", 39, Rarity.RARE, mage.cards.m.Marjhan.class));
|
||||
cards.add(new SetCardInfo("Memory Lapse", 40, Rarity.COMMON, mage.cards.m.MemoryLapse.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Memory Lapse", 41, Rarity.COMMON, mage.cards.m.MemoryLapse.class, NON_FULL_USE_VARIOUS));
|
||||
|
@ -145,6 +151,7 @@ public class Homelands extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Mystic Decree", 43, Rarity.RARE, mage.cards.m.MysticDecree.class));
|
||||
cards.add(new SetCardInfo("Narwhal", 44, Rarity.RARE, mage.cards.n.Narwhal.class));
|
||||
cards.add(new SetCardInfo("Primal Order", 65, Rarity.RARE, mage.cards.p.PrimalOrder.class));
|
||||
cards.add(new SetCardInfo("Rashka the Slayer", 115, Rarity.RARE, mage.cards.r.RashkaTheSlayer.class));
|
||||
cards.add(new SetCardInfo("Reef Pirates", 45, Rarity.COMMON, ReefPirates.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Reef Pirates", 46, Rarity.COMMON, ReefPirates.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Renewal", 66, Rarity.COMMON, mage.cards.r.Renewal.class));
|
||||
|
|
|
@ -76,6 +76,7 @@ public class MastersEdition extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Armageddon", 4, Rarity.RARE, mage.cards.a.Armageddon.class));
|
||||
cards.add(new SetCardInfo("Artifact Blast", 85, Rarity.COMMON, mage.cards.a.ArtifactBlast.class));
|
||||
cards.add(new SetCardInfo("Ashnod's Transmogrant", 152, Rarity.COMMON, mage.cards.a.AshnodsTransmogrant.class));
|
||||
cards.add(new SetCardInfo("Autumn Willow", 113, Rarity.RARE, mage.cards.a.AutumnWillow.class));
|
||||
cards.add(new SetCardInfo("Balduvian Horde", 86, Rarity.RARE, mage.cards.b.BalduvianHorde.class));
|
||||
cards.add(new SetCardInfo("Ball Lightning", 87, Rarity.RARE, mage.cards.b.BallLightning.class));
|
||||
cards.add(new SetCardInfo("Baron Sengir", 58, Rarity.RARE, mage.cards.b.BaronSengir.class));
|
||||
|
|
|
@ -93,6 +93,7 @@ public class MastersEditionII extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Brassclaw Orcs", 119, Rarity.COMMON, BrassclawOrcs.class));
|
||||
cards.add(new SetCardInfo("Brimstone Dragon", 120, Rarity.RARE, mage.cards.b.BrimstoneDragon.class));
|
||||
cards.add(new SetCardInfo("Brine Shaman", 80, Rarity.COMMON, mage.cards.b.BrineShaman.class));
|
||||
cards.add(new SetCardInfo("Broken Visage", 81, Rarity.UNCOMMON, mage.cards.b.BrokenVisage.class));
|
||||
cards.add(new SetCardInfo("Browse", 43, Rarity.UNCOMMON, mage.cards.b.Browse.class));
|
||||
cards.add(new SetCardInfo("Burnout", 121, Rarity.UNCOMMON, mage.cards.b.Burnout.class));
|
||||
cards.add(new SetCardInfo("Carapace", 155, Rarity.COMMON, mage.cards.c.Carapace.class));
|
||||
|
|
|
@ -1,78 +1,81 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.sets;
|
||||
|
||||
import mage.cards.ExpansionSet;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.SetType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fireshoes
|
||||
*/
|
||||
public class RivalsOfIxalan extends ExpansionSet {
|
||||
|
||||
private static final RivalsOfIxalan instance = new RivalsOfIxalan();
|
||||
|
||||
public static RivalsOfIxalan getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private RivalsOfIxalan() {
|
||||
super("Rivals of Ixalan", "RIX", ExpansionSet.buildDate(2018, 1, 19), SetType.EXPANSION);
|
||||
this.blockName = "Ixalan";
|
||||
this.parentSet = Ixalan.getInstance();
|
||||
this.hasBoosters = true;
|
||||
this.hasBasicLands = false;
|
||||
this.numBoosterLands = 1;
|
||||
this.numBoosterCommon = 11;
|
||||
this.numBoosterUncommon = 3;
|
||||
this.numBoosterRare = 1;
|
||||
this.ratioBoosterMythic = 8;
|
||||
|
||||
cards.add(new SetCardInfo("Angrath's Ambusher", 202, Rarity.UNCOMMON, mage.cards.a.AngrathsAmbusher.class));
|
||||
cards.add(new SetCardInfo("Angrath's Fury", 204, Rarity.RARE, mage.cards.a.AngrathsFury.class));
|
||||
cards.add(new SetCardInfo("Angrath, Minotaur Pirate", 201, Rarity.MYTHIC, mage.cards.a.AngrathMinotaurPirate.class));
|
||||
cards.add(new SetCardInfo("Brass's Bounty", 94, Rarity.RARE, mage.cards.b.BrasssBounty.class));
|
||||
cards.add(new SetCardInfo("Captain's Hook", 177, Rarity.RARE, mage.cards.c.CaptainsHook.class));
|
||||
cards.add(new SetCardInfo("Cinder Barrens", 205, Rarity.RARE, mage.cards.c.CinderBarrens.class));
|
||||
cards.add(new SetCardInfo("Evolving Wilds", 186, Rarity.RARE, mage.cards.e.EvolvingWilds.class));
|
||||
cards.add(new SetCardInfo("Ghalta, Primal Hunger", 130, Rarity.RARE, mage.cards.g.GhaltaPrimalHunger.class));
|
||||
cards.add(new SetCardInfo("Silvergill Adept", 53, Rarity.UNCOMMON, mage.cards.s.SilvergillAdept.class));
|
||||
cards.add(new SetCardInfo("Storm the Vault", 173, Rarity.RARE, mage.cards.s.StormTheVault.class));
|
||||
cards.add(new SetCardInfo("Swab Goblin", 203, Rarity.COMMON, mage.cards.s.SwabGoblin.class));
|
||||
cards.add(new SetCardInfo("Tetzimoc, Primal Death", 86, Rarity.RARE, mage.cards.t.TetzimocPrimalDeath.class));
|
||||
cards.add(new SetCardInfo("The Immortal Sun", 180, Rarity.MYTHIC, mage.cards.t.TheImmortalSun.class));
|
||||
cards.add(new SetCardInfo("Vampire Champion", 198, Rarity.COMMON, mage.cards.v.VampireChampion.class));
|
||||
cards.add(new SetCardInfo("Vault of Catlacan", 173, Rarity.RARE, mage.cards.v.VaultOfCatlacan.class));
|
||||
cards.add(new SetCardInfo("Vona's Hunger", 90, Rarity.RARE, mage.cards.v.VonasHunger.class));
|
||||
cards.add(new SetCardInfo("Vraska's Conquistador", 199, Rarity.UNCOMMON, mage.cards.v.VraskasConquistador.class));
|
||||
cards.add(new SetCardInfo("Vraska's Scorn", 200, Rarity.RARE, mage.cards.v.VraskasScorn.class));
|
||||
cards.add(new SetCardInfo("Vraska, Scheming Gorgon", 197, Rarity.MYTHIC, mage.cards.v.VraskaSchemingGorgon.class));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.sets;
|
||||
|
||||
import mage.cards.ExpansionSet;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.SetType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fireshoes
|
||||
*/
|
||||
public class RivalsOfIxalan extends ExpansionSet {
|
||||
|
||||
private static final RivalsOfIxalan instance = new RivalsOfIxalan();
|
||||
|
||||
public static RivalsOfIxalan getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private RivalsOfIxalan() {
|
||||
super("Rivals of Ixalan", "RIX", ExpansionSet.buildDate(2018, 1, 19), SetType.EXPANSION);
|
||||
this.blockName = "Ixalan";
|
||||
this.parentSet = Ixalan.getInstance();
|
||||
this.hasBoosters = true;
|
||||
this.hasBasicLands = false;
|
||||
this.numBoosterLands = 1;
|
||||
this.numBoosterCommon = 11;
|
||||
this.numBoosterUncommon = 3;
|
||||
this.numBoosterRare = 1;
|
||||
this.ratioBoosterMythic = 8;
|
||||
|
||||
cards.add(new SetCardInfo("Angrath's Ambusher", 202, Rarity.UNCOMMON, mage.cards.a.AngrathsAmbusher.class));
|
||||
cards.add(new SetCardInfo("Angrath's Fury", 204, Rarity.RARE, mage.cards.a.AngrathsFury.class));
|
||||
cards.add(new SetCardInfo("Angrath, Minotaur Pirate", 201, Rarity.MYTHIC, mage.cards.a.AngrathMinotaurPirate.class));
|
||||
cards.add(new SetCardInfo("Brass's Bounty", 94, Rarity.RARE, mage.cards.b.BrasssBounty.class));
|
||||
cards.add(new SetCardInfo("Captain's Hook", 177, Rarity.RARE, mage.cards.c.CaptainsHook.class));
|
||||
cards.add(new SetCardInfo("Cinder Barrens", 205, Rarity.RARE, mage.cards.c.CinderBarrens.class));
|
||||
cards.add(new SetCardInfo("Dusk Charger", 69, Rarity.COMMON, mage.cards.d.DuskCharger.class));
|
||||
cards.add(new SetCardInfo("Evolving Wilds", 186, Rarity.RARE, mage.cards.e.EvolvingWilds.class));
|
||||
cards.add(new SetCardInfo("Ghalta, Primal Hunger", 130, Rarity.RARE, mage.cards.g.GhaltaPrimalHunger.class));
|
||||
cards.add(new SetCardInfo("Glorious Destiny", 18, Rarity.RARE, mage.cards.g.GloriousDestiny.class));
|
||||
cards.add(new SetCardInfo("Paladin of Atonement", 16, Rarity.RARE, mage.cards.p.PaladinOfAtonement.class));
|
||||
cards.add(new SetCardInfo("Silvergill Adept", 53, Rarity.UNCOMMON, mage.cards.s.SilvergillAdept.class));
|
||||
cards.add(new SetCardInfo("Storm the Vault", 173, Rarity.RARE, mage.cards.s.StormTheVault.class));
|
||||
cards.add(new SetCardInfo("Swab Goblin", 203, Rarity.COMMON, mage.cards.s.SwabGoblin.class));
|
||||
cards.add(new SetCardInfo("Tetzimoc, Primal Death", 86, Rarity.RARE, mage.cards.t.TetzimocPrimalDeath.class));
|
||||
cards.add(new SetCardInfo("The Immortal Sun", 180, Rarity.MYTHIC, mage.cards.t.TheImmortalSun.class));
|
||||
cards.add(new SetCardInfo("Vampire Champion", 198, Rarity.COMMON, mage.cards.v.VampireChampion.class));
|
||||
cards.add(new SetCardInfo("Vault of Catlacan", 173, Rarity.RARE, mage.cards.v.VaultOfCatlacan.class));
|
||||
cards.add(new SetCardInfo("Vona's Hunger", 90, Rarity.RARE, mage.cards.v.VonasHunger.class));
|
||||
cards.add(new SetCardInfo("Vraska's Conquistador", 199, Rarity.UNCOMMON, mage.cards.v.VraskasConquistador.class));
|
||||
cards.add(new SetCardInfo("Vraska's Scorn", 200, Rarity.RARE, mage.cards.v.VraskasScorn.class));
|
||||
cards.add(new SetCardInfo("Vraska, Scheming Gorgon", 197, Rarity.MYTHIC, mage.cards.v.VraskaSchemingGorgon.class));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.abilities.condition.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.game.Game;
|
||||
import mage.watchers.WatcherUtils;
|
||||
import mage.watchers.common.PlayerLostLifeWatcher;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX
|
||||
*/
|
||||
public enum LiveLostLastTurnCondition implements Condition {
|
||||
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
PlayerLostLifeWatcher watcher = (PlayerLostLifeWatcher) game.getState().getWatchers().get(PlayerLostLifeWatcher.class.getSimpleName());
|
||||
if (watcher != null) {
|
||||
return watcher.getLiveLostLastTurn(source.getControllerId()) > 0;
|
||||
} else {
|
||||
WatcherUtils.logMissingWatcher(game, source, PlayerLostLifeWatcher.class, this.getClass());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ public class ConditionalTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
protected TriggeredAbility ability;
|
||||
protected Condition condition;
|
||||
protected String text;
|
||||
protected String abilityText;
|
||||
|
||||
/**
|
||||
* Triggered ability with a condition. Set the optionality for the trigger
|
||||
|
@ -27,22 +27,22 @@ public class ConditionalTriggeredAbility extends TriggeredAbilityImpl {
|
|||
*
|
||||
* @param ability
|
||||
* @param condition
|
||||
* @param text if null or empty, the rule text of the triggered ability
|
||||
* itself is used.
|
||||
* @param text explicit rule text for the ability, if null or empty, the
|
||||
* rule text generated by the triggered ability itself is used.
|
||||
*/
|
||||
public ConditionalTriggeredAbility(TriggeredAbility ability, Condition condition, String text) {
|
||||
super(ability.getZone(), null);
|
||||
this.ability = ability;
|
||||
this.modes = ability.getModes();
|
||||
this.condition = condition;
|
||||
this.text = text;
|
||||
this.abilityText = text;
|
||||
}
|
||||
|
||||
public ConditionalTriggeredAbility(final ConditionalTriggeredAbility triggered) {
|
||||
super(triggered);
|
||||
this.ability = triggered.ability.copy();
|
||||
this.condition = triggered.condition;
|
||||
this.text = triggered.text;
|
||||
this.abilityText = triggered.abilityText;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -69,10 +69,10 @@ public class ConditionalTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
if (text == null || text.isEmpty()) {
|
||||
if (abilityText == null || abilityText.isEmpty()) {
|
||||
return ability.getRule();
|
||||
}
|
||||
return text;
|
||||
return abilityText;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -77,6 +77,7 @@ public class DoIfCostPaid extends OneShotEffect {
|
|||
&& (!optional || player.chooseUse(executingEffects.get(0).getOutcome(), message, source, game))) {
|
||||
cost.clearPaid();
|
||||
if (cost.pay(source, game, source.getSourceId(), player.getId(), false)) {
|
||||
game.applyEffects(); // To end effects e.g. of sacrificed permanents
|
||||
for (Effect effect : executingEffects) {
|
||||
effect.setTargetPointer(this.targetPointer);
|
||||
if (effect instanceof OneShotEffect) {
|
||||
|
@ -86,8 +87,7 @@ public class DoIfCostPaid extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
player.resetStoredBookmark(game); // otherwise you can e.g. undo card drawn with Mentor of the Meek
|
||||
}
|
||||
else if (!otherwiseEffects.isEmpty()) {
|
||||
} else if (!otherwiseEffects.isEmpty()) {
|
||||
for (Effect effect : otherwiseEffects) {
|
||||
effect.setTargetPointer(this.targetPointer);
|
||||
if (effect instanceof OneShotEffect) {
|
||||
|
@ -97,8 +97,7 @@ public class DoIfCostPaid extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!otherwiseEffects.isEmpty()) {
|
||||
} else if (!otherwiseEffects.isEmpty()) {
|
||||
for (Effect effect : otherwiseEffects) {
|
||||
effect.setTargetPointer(this.targetPointer);
|
||||
if (effect instanceof OneShotEffect) {
|
||||
|
|
|
@ -29,12 +29,9 @@ package mage.abilities.effects.keyword;
|
|||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.keyword.AscendAbility;
|
||||
import mage.constants.Outcome;
|
||||
import mage.designations.CitysBlessing;
|
||||
import mage.designations.DesignationType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -44,7 +41,7 @@ public class AscendEffect extends OneShotEffect {
|
|||
|
||||
public AscendEffect() {
|
||||
super(Outcome.Detriment);
|
||||
staticText = "Ascend (If you control ten or more permanents, you get the city's blessing for the rest of the game.)<br>";
|
||||
staticText = AscendAbility.ASCEND_RULE + "<br>";
|
||||
}
|
||||
|
||||
public AscendEffect(final AscendEffect effect) {
|
||||
|
@ -58,20 +55,6 @@ public class AscendEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
if (game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_ARTIFACT_CREATURE_ENCHANTMENT_OR_LAND, controller.getId(), game) > 9) {
|
||||
if (!controller.hasDesignation(DesignationType.CITYS_BLESSING)) {
|
||||
controller.addDesignation(new CitysBlessing());
|
||||
game.informPlayers(controller.getLogName() + " gets the city's blessing for the rest of the game.");
|
||||
} else {
|
||||
game.informPlayers(controller.getLogName() + " already has the city's blessing.");
|
||||
}
|
||||
} else {
|
||||
game.informPlayers(controller.getLogName() + " does not get the city's blessing.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return AscendAbility.checkAscend(game, source, true);
|
||||
}
|
||||
}
|
||||
|
|
115
Mage/src/main/java/mage/abilities/keyword/AscendAbility.java
Normal file
115
Mage/src/main/java/mage/abilities/keyword/AscendAbility.java
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import static mage.abilities.keyword.AscendAbility.ASCEND_RULE;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Layer;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubLayer;
|
||||
import mage.constants.Zone;
|
||||
import mage.designations.CitysBlessing;
|
||||
import mage.designations.DesignationType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class AscendAbility extends SimpleStaticAbility {
|
||||
|
||||
public static String ASCEND_RULE = "Ascend <i>(If you control ten or more permanents, you get the city's blessing for the rest of the game.)</i>";
|
||||
|
||||
public AscendAbility() {
|
||||
super(Zone.BATTLEFIELD, new AscendContinuousEffect());
|
||||
}
|
||||
|
||||
public AscendAbility(final AscendAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AscendAbility copy() {
|
||||
return new AscendAbility(this);
|
||||
}
|
||||
|
||||
public static boolean checkAscend(Game game, Ability source, boolean verbose) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
if (!controller.hasDesignation(DesignationType.CITYS_BLESSING)) {
|
||||
if (game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_ARTIFACT_CREATURE_ENCHANTMENT_OR_LAND, controller.getId(), game) > 9) {
|
||||
controller.addDesignation(new CitysBlessing());
|
||||
game.informPlayers(controller.getLogName() + " gets the city's blessing for the rest of the game.");
|
||||
} else {
|
||||
if (verbose) {
|
||||
game.informPlayers(controller.getLogName() + " does not get the city's blessing.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (verbose) {
|
||||
game.informPlayers(controller.getLogName() + " already has the city's blessing.");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return ASCEND_RULE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class AscendContinuousEffect extends ContinuousEffectImpl {
|
||||
|
||||
public AscendContinuousEffect() {
|
||||
super(Duration.WhileOnBattlefield, Layer.PlayerEffects, SubLayer.NA, Outcome.Benefit);
|
||||
staticText = ASCEND_RULE;
|
||||
}
|
||||
|
||||
public AscendContinuousEffect(final AscendContinuousEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return AscendAbility.checkAscend(game, source, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AscendContinuousEffect copy() {
|
||||
return new AscendContinuousEffect(this);
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ public enum AsThoughEffectType {
|
|||
CAST_AS_INSTANT,
|
||||
ACTIVATE_AS_INSTANT,
|
||||
DAMAGE,
|
||||
SHROUD,
|
||||
HEXPROOF,
|
||||
PAY,
|
||||
LOOK_AT_FACE_DOWN,
|
||||
|
|
|
@ -93,6 +93,7 @@ public enum CounterType {
|
|||
MINING("mining"),
|
||||
MIRE("mire"),
|
||||
MUSTER("muster"),
|
||||
NET("net"),
|
||||
P0P1(new BoostCounter(0, 1).name),
|
||||
P1P0(new BoostCounter(1, 0).name),
|
||||
P1P1(new BoostCounter(1, 1).name),
|
||||
|
|
|
@ -61,6 +61,7 @@ public final class StaticFilters {
|
|||
public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE = new FilterCreaturePermanent();
|
||||
public static final FilterCreaturePermanent FILTER_PERMANENT_A_CREATURE = new FilterCreaturePermanent("a creature");
|
||||
public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURES = new FilterCreaturePermanent("creatures");
|
||||
public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURES_CONTROLLED = new FilterCreaturePermanent("creatures you control");
|
||||
public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE_GOBLINS = new FilterCreaturePermanent(SubType.GOBLIN, "Goblin creatures");
|
||||
public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE_SLIVERS = new FilterCreaturePermanent(SubType.SLIVER, "all Sliver creatures");
|
||||
public static final FilterPlaneswalkerPermanent FILTER_PERMANENT_PLANESWALKER = new FilterPlaneswalkerPermanent();
|
||||
|
@ -108,6 +109,8 @@ public final class StaticFilters {
|
|||
|
||||
FILTER_ATTACKING_CREATURES.add(new AttackingPredicate());
|
||||
|
||||
FILTER_PERMANENT_CREATURES_CONTROLLED.add(new ControllerPredicate(TargetController.YOU));
|
||||
|
||||
FILTER_PERMANENT_ARTIFACT_OR_CREATURE.add(Predicates.or(
|
||||
new CardTypePredicate(CardType.ARTIFACT),
|
||||
new CardTypePredicate(CardType.CREATURE)
|
||||
|
|
|
@ -27,11 +27,12 @@
|
|||
*/
|
||||
package mage.filter.predicate.permanent;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author North
|
||||
|
@ -46,6 +47,12 @@ public class ControllerIdPredicate implements Predicate<Permanent> {
|
|||
|
||||
@Override
|
||||
public boolean apply(Permanent input, Game game) {
|
||||
if(controllerId == null){
|
||||
return false;
|
||||
}
|
||||
if(input.getControllerId() == null){
|
||||
return false;
|
||||
}
|
||||
return controllerId.equals(input.getControllerId());
|
||||
}
|
||||
|
||||
|
|
|
@ -965,7 +965,9 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
|
|||
public boolean canBeTargetedBy(MageObject source, UUID sourceControllerId, Game game) {
|
||||
if (source != null) {
|
||||
if (abilities.containsKey(ShroudAbility.getInstance().getId())) {
|
||||
return false;
|
||||
if (!game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.SHROUD, sourceControllerId, game)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (abilities.containsKey(HexproofAbility.getInstance().getId())) {
|
||||
if (game.getPlayer(this.getControllerId()).hasOpponent(sourceControllerId, game)
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com AS IS AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.game.permanent.token;
|
||||
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.MageInt;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author spjspj & L_J
|
||||
*/
|
||||
public class BrokenVisageSpiritToken extends Token {
|
||||
|
||||
public BrokenVisageSpiritToken() {
|
||||
this(0,0);
|
||||
}
|
||||
|
||||
public BrokenVisageSpiritToken(int tokenPower, int tokenToughness) {
|
||||
super("Spirit", new StringBuilder(tokenPower).append('/').append(tokenToughness).append(" black Spirit creature token").toString());
|
||||
cardType.add(CardType.CREATURE);
|
||||
color.setBlack(true);
|
||||
subtype.add(SubType.SPIRIT);
|
||||
power = new MageInt(tokenPower);
|
||||
toughness = new MageInt(tokenToughness);
|
||||
}
|
||||
}
|
46
Mage/src/main/java/mage/watchers/WatcherUtils.java
Normal file
46
Mage/src/main/java/mage/watchers/WatcherUtils.java
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.watchers;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.game.Game;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class WatcherUtils {
|
||||
|
||||
public static void logMissingWatcher(Game game, Ability source, Class watcherClass, Class usingClass) {
|
||||
MageObject sourceObject = source.getSourceObject(game);
|
||||
Logger.getLogger(usingClass).error("Needed watcher is not started " + watcherClass.getSimpleName()
|
||||
+ " - " + (sourceObject == null ? " no source object" : sourceObject.getName()));
|
||||
}
|
||||
}
|
|
@ -38,7 +38,7 @@ import mage.watchers.Watcher;
|
|||
|
||||
/*
|
||||
* Counts amount of life lost current or last turn by players.
|
||||
* This watcher is always added in gameImpl.init
|
||||
* This watcher is automatically started in gameImpl.init for each game
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
Afflict|number|
|
||||
Annihilator|number|
|
||||
Ascend|new|
|
||||
Basic landcycling|cost|
|
||||
Battle cry|new|
|
||||
Bestow|card, manaString|
|
||||
|
|
|
@ -32696,15 +32696,39 @@ Forest|Duel Decks: Mind vs. Might|65|L||Basic Land - Forest|||{T}: Add {G} to yo
|
|||
Chandra, Gremlin Wrangler|Heroes of the Realm|1|M|{2}{R}{R}|Legendary Planeswalker - Chandra|3||+1: Create a 2/2 red Gremlin creature token.$-2:Chandra, Gremlin Wrangler deals X damage to target creature or player, where X is the number of Gremlins you control.|
|
||||
Dungeon Master|Heroes of the Realm|1|M|{2}{W}{U}|Legendary Planeswalker - Dungeon Master|||+1: Target opponent creates a 1/1 black Skeleton creature token with “When this creature dies, each opponent loses 2 life.”$+1: Roll a d20. If you roll a 1, skip your next turn. If you roll a 12 or higher, draw a card.$-6: You get an adventuring party. (Your party is a 3/3 red Fighter with first strike, a 1/1 white Cleric with lifelink, a 2/2 black Rogue with hexproof, and a 1/1 blue Wizard with flying.)|
|
||||
Nira, Hellkite Duelist|Heroes of the Realm|3|M|{W}{U}{B}{R}{G}|Legendary Creature — Dragon|6|6|Flash$Flying, trample, haste$When Nira, Hellkite Duelist enters the battlefield, the next time you would lose the game this turn, instead draw three cards and your life total becomes 5.|
|
||||
Paladin of Atonement|Rivals of Ixalan|16|R|{1}{W}|Creature - Vampire Knight|1|1|At the beginning of each upkeep, if you lost life last turn, put a +1/+1 counter on Paladin of Atonement.$When Paladin of Atonement dies, you gain life equal to it's toughness.|
|
||||
Glorious Destiny|Rivals of Ixalan|18|R|{2}{W}|Enchantment|||Ascend <i>(If you control ten or more permanents, you get the city's blessing for the rest of the game.)</i>$As Glorious Destiny enters the battlefield, choose a creature type.$Creatures you control of the chosen type get +1/+1. They have vigilance as long as you have the city's blessing.|
|
||||
Shrine Altisaur|Rivals of Ixalan|28|R|{4}{W}|Creature - Dinosaur|3|4|If a source would deal damage to another Dinosaur you control, prevent all but 1 of that damage.|
|
||||
Zetalpa, Primal Dawn|Rivals of Ixalan|30|R|{6}{W}{W}|Legendary Creature - Elder Dinosaur|4|8|Flying, double strike, vigilance, trample, indestructible|
|
||||
River Darter|Rivals of Ixalan|47|C|{2}{U}|Creature - Merfolk Warrior|2|3|River Darter can't be blocked by Dinosaurs.|
|
||||
Seafloor Oracle|Rivals of Ixalan|51|R|{2}{W}{W}|Creature - Merfolk Wizard|2|3|Whenever a Merfolk you controls deals combat damage to a player, draw a card.|
|
||||
Secrets of the Golden City|Rivals of Ixalan|52|C|{1}{U}{U}|Sorcery|||Ascend <i>(If you control ten or more permanents, you get the city's blessing for the rest of the game.)</i>$Draw two cards. If you have the city's blessing, draw three cards instead.|
|
||||
Silvergill Adept|Rivals of Ixalan|53|U|{1}{U}|Creature - Merfolk Wizard|2|1|As an additional cost to cast Silvergill Adept, reveal a Merfolk card from your hand or pay {3}.$When Silvergill Adept enters the battlefield, draw a card.|
|
||||
Dusk Charger|Rivals of Ixalan|69|C|{3}{B}|Creature - Horse|3|3|Ascend <i>(If you control ten or more permanents, you get the city's blessing for the rest of the game.)</i>$Dusk Charger gets +2/+2 as long as you have the city's blessing.|
|
||||
Tetzimoc, Primal Death|Rivals of Ixalan|86|R|{4}{B}{B}|Legendary Creature - Elder Dinosaur|6|6|Deathtouch${B}, Reveal Tetzimoc, Primal Death from your hand: Put a prey counter on target creature. Activate this ability only during your turn.$When Tetzimoc, Primal Death enters the battlefield, destroy each creature your opponents control with a prey counter on it.|
|
||||
Vona's Hunger|Rivals of Ixalan|90|R|{2}{B}|Instant|||Ascend <i>(If you control ten or more permanents, you get the city's blessing for the rest of the game.)</i>$Each opponent sacrifices a creature. If you have the city's blessing, instead each opponent sacrifices half the creatures he or she controls rounded up.|
|
||||
Brass's Bounty|Rivals of Ixalan|94|R|{6}{R}|Sorcery|||For each land you control, create a colorless Treasure artifact token with "{t}, Sacrifice this artifact: Add one mana of any color to your mana pool."|
|
||||
Form of the Dinosaur|Rivals of Ixalan|103|R|{4}{R}{R}|Enchantment|||When Form of the Dinosaur enters the battlefield, your life total becomes 15.$At the beginning of your upkeep, Form of the Dinosaur deals 15 damage to target creature an opponent controls and that creature deals damage equal to its power to you.|
|
||||
Frilled Deathspitter|Rivals of Ixalan|104|C|{2}{R}|Creature - Dinosaur|3|2|<i>Enrage</i> — Whenever Frilled Deathspitter is dealt damage, it deals 2 damage to target opponent.|
|
||||
Swaggering Corsair|Rivals of Ixalan|119|C|{2}{R}|Creature - Human Pirate|2|2|<i>Raid</i> — Swaggering Corsair enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn.|
|
||||
Tilonalli's Summoner|Rivals of Ixalan|121|R|{1}{R}|Creature - Human Shaman|1|1|Ascend (If you control ten or more permanents, you get the city's blessing for the rest of the game.)$Whenever Tilonalli's Summoner attacks, you may pay {X}{R}. If you do, create X 1/1 Elemental creature tokens tapped and attacking. Exile them at the beginning of the next end step, unless you have the City's blessing.|
|
||||
Enter the Unknown|Rivals of Ixalan|128|U|{G}|Sorcery|||Target creature you control explores. <i>(Reveal the top card of your library. Put that card into your hand if it's a land. Otherwise, put a +1/+1 counter on this creature, then put the card back or put it into your graveyard.) </i>$You may play an additional land this turn.|
|
||||
Ghalta, Primal Hunger|Rivals of Ixalan|130|R|{1}{0}{G}{G}|Legendary Creature - Elder Dinosaur|12|12|Ghalta, Primal Hunger costs {X} less to cast, where X is the total power of creatures you control.$Trample|
|
||||
Path to Discovery|Rivals of Ixalan|142|R|{3}{G}|Enchantment|||Whenever a creature enters the battlefield under your control, it explores. (Reveal the top card of your library. Put that card into your hand if it's a land. Otherwise, put a +1/+1 counter on the creature, then put the card back or put it into your graveyard.)|
|
||||
Tendershoot Dryad|Rivals of Ixalan|147|R|{4}{G}|Creature - Dryad|2|2|Ascend <i>(If you control ten or more permanents, you get the city's blessing for the rest of the game.)</i>$At the beginning of each upkeep, create a 1/1 green Saproling creature token.$Saprolings you control get +2/+2 as long as you have the city's blessing.|
|
||||
Thrashing Brontodon|Rivals of Ixalan|148|U|{1}{G}{G}|Creature - Dinosaur|3|4|{1}, Sacrificing Thrashing Brontodon: Destroy target artifact or enchantment.|
|
||||
Angrath, the Flame-Chained|Rivals of Ixalan|152|M|{3}{B}{R}|Legendary Planeswalker - Angrath|4|+1: Each opponent discards a card and loses 2 life.$-3: Gain control of target creature until end of turn. Untap it. It gains haste until end of turn. Sacrifice it at the beginning of the next end step if it has converted mana cost 3 or less.$-8: Each opponent loses life equal to the number of cards in his or her graveyard.|
|
||||
Atzocan Seer|Rivals of Ixalan|153|U|{1}{G}{W}|Creature - Human Druid|2|3|{t}: Add one mana of any color to your manan pool.$Sacrifice Atzocan Seer: Return target Dinosaur card from your graveyard to your hand.|
|
||||
Elenda, the Dusk Rose|Rivals of Ixalan|157|M|{2}{W}{B}|Legendary Creature - Vampire Knight|1|1|Lifelink$Whenever another creature dies, put a +1/+1 counter on Elenda, the Dusk Rose.$When Elenda dies, create X 1/1 white Vampire creature tokens with lifelink, where X is Elenda's power|
|
||||
Journey to Eternity|Rivals of Ixalan|160|R|{1}{B}{G}|Legendary Enchantment - Aura|||Enchant creature you control$When enchanted creature dies, return it to the battlefield under your control, then return Journey to Eternity to the battlefield transformed under your control.|
|
||||
Atzal, Cave of Eternity|Rivals of Ixalan|160|R||Legendary Land|||<i>(Transforms from Journey to Eternity.)</i>${t}: Add one mana of any color to your mana pool.${3}{B}{G}, {t}: Return target creature card from your graveyard to the battlefield.|
|
||||
Kumena, Tyrant of Orzca|Rivals of Ixalan|162|M|{1}{G}{U}|Legendary Creature - Merfolk Shaman|2|4|Tap another untapped Merfolk you control: Kumena, Tyrant of Orzca can't be blocked this turn.$Tap three untapped Merfolk you control: Draw a card.$Tap five untapped Merfolk you control: Put a +1/+1 counter on each Merfolk you control.|
|
||||
Storm the Vault|Rivals of Ixalan|173|R|{2}{U}{R}|Legendary Enchantment|||Whenever one or more creatures you control deal combat damage to a player, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."$At the beginning of your end step, if you control five or more artifacts, transform Storm the Vault.|
|
||||
Vault of Catlacan|Rivals of Ixalan|173|R||Legendary Land|||<i>(Transforms from Storm the Vault.)</i>${T}: Add one mana of any color to your mana pool.${T}: Add {U} to your mana pool for each artifact you control.|
|
||||
Awakened Amalgamation|Rivals of Ixalan|175|R|{4}|Artifact Creature - Golem|0|0|Awakened Amalgamation's power and toughness are each equal to the number of lands you control with different names.|
|
||||
Captain's Hook|Rivals of Ixalan|177|R|{3}|Artifact - Equipment|||Equipped creature gets +2/+0, has menace, and is a Pirate in addition to its other creature types.$Whenever Captain's Hook becomes unattached from a permanent, destroy that permanent.$Equip {1}|
|
||||
The Immortal Sun|Rivals of Ixalan|180|M|{6}|Legendary Artifact|||Players can't activate loyalty abilities of planeswalkers.$At the beginning of your draw step, draw an additional card.$Spells you cast cost {1} less to cast.$Creatures you control get +1/+1.|
|
||||
Gleaming Barrier|Rivals of Ixalan|178|C|{2}|Artifact Creature - Wall|0|4|Defender$When Gleaming Barrier dies, create a colorless Treasure artifact token with "{t}, Sacrifice this artifact: Add one mana of any color to your mana pool."|
|
||||
The Immortal Sun|Rivals of Ixalan|180|M|{6}|Legendary Artifact|||Players can't activate planeswalkers' loyalty abilities.$At the beginning of your draw step, draw an additional card.$Spells you cast cost {1} less to cast.$Creatures you control get +1/+1.|
|
||||
Evolving Wilds|Rivals of Ixalan|186|C||Land|||{T}, Sacrifice Evolving Wilds: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library.|
|
||||
Vraska, Scheming Gorgon|Rivals of Ixalan|197|M|{4}{B}{B}|Legendary Planeswalker - Vraska|5|+2: Creatures you control get +1/+0 until end of turn.$-3: Destroy target creature.$-10: Until end of turn, creatures you control gain deathtouch and "Whenever this creature deals damage to an opponent, that player loses the game."|
|
||||
Vampire Champion|Rivals of Ixalan|198|C|{3}{B}|Creature - Vampire Soldier|3|3|Deathtouch <i>(Any amount of damage this deals to a creature is enough to destroy it.)</i>|
|
||||
|
|
Loading…
Add table
Reference in a new issue