mirror of
https://github.com/correl/mage.git
synced 2024-12-25 03:00:15 +00:00
Merge remote-tracking branch 'origin/master' into m21_test
This commit is contained in:
commit
41b7439403
95 changed files with 1935 additions and 1452 deletions
|
@ -881,7 +881,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
popupDebug.add(menuDebugTestCardRenderModesDialog);
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
setMinimumSize(new java.awt.Dimension(1024, 768));
|
||||
setMinimumSize(new java.awt.Dimension(1024, 500));
|
||||
|
||||
desktopPane.setBackground(new java.awt.Color(204, 204, 204));
|
||||
|
||||
|
|
|
@ -73,8 +73,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
}
|
||||
trimGrid();
|
||||
layoutGrid();
|
||||
cardScroll.revalidate();
|
||||
cardScroll.repaint();
|
||||
repaintGrid();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -315,8 +314,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
// Remove empty rows / cols / spaces in stacks
|
||||
trimGrid();
|
||||
layoutGrid();
|
||||
cardScroll.revalidate();
|
||||
cardScroll.repaint();
|
||||
repaintGrid();
|
||||
} else {
|
||||
// Add new cards to grid
|
||||
for (CardView card : cards) {
|
||||
|
@ -325,14 +323,14 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
eventSource.fireEvent(card, ClientEventType.ADD_SPECIFIC_CARD);
|
||||
}
|
||||
layoutGrid();
|
||||
cardContent.repaint();
|
||||
repaintGrid();
|
||||
}
|
||||
}
|
||||
|
||||
public void changeGUISize() {
|
||||
layoutGrid();
|
||||
cardScroll.getVerticalScrollBar().setUnitIncrement(CardRenderer.getCardTopHeight(getCardWidth()));
|
||||
cardContent.repaint();
|
||||
repaintGrid();
|
||||
}
|
||||
|
||||
public void cleanUp() {
|
||||
|
@ -386,7 +384,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
}
|
||||
trimGrid();
|
||||
layoutGrid();
|
||||
cardContent.repaint();
|
||||
repaintGrid();
|
||||
}
|
||||
|
||||
public DeckCardLayout getCardLayout() {
|
||||
|
@ -710,6 +708,47 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
// Editting mode
|
||||
this.mode = Constants.DeckEditorMode.LIMITED_BUILDING;
|
||||
|
||||
// Content
|
||||
cardContent = new JLayeredPane();
|
||||
cardContent.setLayout(null);
|
||||
cardContent.setOpaque(false);
|
||||
cardContent.addMouseListener(new MouseAdapter() {
|
||||
private boolean isDragging = false;
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (SwingUtilities.isLeftMouseButton(e)) {
|
||||
isDragging = true;
|
||||
beginSelectionDrag(e.getX(), e.getY(), e.isShiftDown());
|
||||
updateSelectionDrag(e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (isDragging) {
|
||||
isDragging = false;
|
||||
updateSelectionDrag(e.getX(), e.getY());
|
||||
endSelectionDrag(e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
});
|
||||
cardContent.addMouseMotionListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
updateSelectionDrag(e.getX(), e.getY());
|
||||
}
|
||||
});
|
||||
cardScroll = new JScrollPane(cardContent,
|
||||
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
|
||||
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
cardScroll.setOpaque(false);
|
||||
cardScroll.getViewport().setOpaque(false);
|
||||
cardScroll.setViewportBorder(BorderFactory.createEmptyBorder());
|
||||
cardScroll.setBorder(BorderFactory.createLineBorder(Color.gray, 1));
|
||||
cardScroll.getVerticalScrollBar().setUnitIncrement(CardRenderer.getCardTopHeight(getCardWidth()));
|
||||
this.add(cardScroll, BorderLayout.CENTER);
|
||||
|
||||
// Toolbar
|
||||
sortButton = new JButton("Sort");
|
||||
filterButton = new JButton("Filter");
|
||||
|
@ -757,56 +796,15 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
cardSizeMod = (float) Math.pow(2, sliderFrac);
|
||||
// Update grid
|
||||
layoutGrid();
|
||||
cardContent.repaint();
|
||||
repaintGrid();
|
||||
}
|
||||
});
|
||||
cardSizeSliderLabel = new JLabel("Card Size:");
|
||||
cardSizeSliderLabel = new JLabel("Card size:");
|
||||
sliderPanel.add(cardSizeSliderLabel);
|
||||
sliderPanel.add(cardSizeSlider);
|
||||
toolbar.add(sliderPanel, BorderLayout.EAST);
|
||||
this.add(toolbar, BorderLayout.NORTH);
|
||||
|
||||
// Content
|
||||
cardContent = new JLayeredPane();
|
||||
cardContent.setLayout(null);
|
||||
cardContent.setOpaque(false);
|
||||
cardContent.addMouseListener(new MouseAdapter() {
|
||||
private boolean isDragging = false;
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (SwingUtilities.isLeftMouseButton(e)) {
|
||||
isDragging = true;
|
||||
beginSelectionDrag(e.getX(), e.getY(), e.isShiftDown());
|
||||
updateSelectionDrag(e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (isDragging) {
|
||||
isDragging = false;
|
||||
updateSelectionDrag(e.getX(), e.getY());
|
||||
endSelectionDrag(e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
});
|
||||
cardContent.addMouseMotionListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
updateSelectionDrag(e.getX(), e.getY());
|
||||
}
|
||||
});
|
||||
cardScroll = new JScrollPane(cardContent,
|
||||
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
|
||||
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
cardScroll.setOpaque(false);
|
||||
cardScroll.getViewport().setOpaque(false);
|
||||
cardScroll.setViewportBorder(BorderFactory.createEmptyBorder());
|
||||
cardScroll.setBorder(BorderFactory.createLineBorder(Color.gray, 1));
|
||||
cardScroll.getVerticalScrollBar().setUnitIncrement(CardRenderer.getCardTopHeight(getCardWidth()));
|
||||
this.add(cardScroll, BorderLayout.CENTER);
|
||||
|
||||
// Insert arrow
|
||||
insertArrow = new JLabel();
|
||||
insertArrow.setSize(20, 20);
|
||||
|
@ -1230,7 +1228,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
|
||||
// And finally rerender
|
||||
layoutGrid();
|
||||
repaint();
|
||||
repaintGrid();
|
||||
}
|
||||
|
||||
public void reselectBy() {
|
||||
|
@ -1340,7 +1338,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
|
||||
// And finally rerender
|
||||
layoutGrid();
|
||||
repaint();
|
||||
repaintGrid();
|
||||
}
|
||||
|
||||
private static final Pattern pattern = Pattern.compile(".*Add(.*)(\\{[WUBRGXC]\\})");
|
||||
|
@ -1568,8 +1566,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
}
|
||||
|
||||
layoutGrid();
|
||||
cardScroll.revalidate();
|
||||
repaint();
|
||||
repaintGrid();
|
||||
JOptionPane.showMessageDialog(null, "Added " + pimpedCards.size() + " cards. You can select them and the originals by choosing 'Multiples'");
|
||||
}
|
||||
}
|
||||
|
@ -1609,8 +1606,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
}
|
||||
cardGrid = newCardGrid;
|
||||
layoutGrid();
|
||||
cardScroll.revalidate();
|
||||
repaint();
|
||||
repaintGrid();
|
||||
}
|
||||
|
||||
// Update the contents of the card grid
|
||||
|
@ -1734,10 +1730,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
if (didModify) {
|
||||
// Update layout
|
||||
layoutGrid();
|
||||
|
||||
// Update draw
|
||||
cardScroll.revalidate();
|
||||
repaint();
|
||||
repaintGrid();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1877,9 +1870,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
eventSource.fireEvent(card, ClientEventType.ADD_SPECIFIC_CARD);
|
||||
// Update layout
|
||||
layoutGrid();
|
||||
// Update draw
|
||||
cardScroll.revalidate();
|
||||
repaint();
|
||||
repaintGrid();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2083,6 +2074,12 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
return (int) (1.4 * getCardWidth());
|
||||
}
|
||||
|
||||
private void repaintGrid() {
|
||||
cardScroll.revalidate();
|
||||
cardScroll.repaint();
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Position all of the card views correctly
|
||||
*/
|
||||
|
|
|
@ -11,39 +11,45 @@
|
|||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,121,0,0,4,76"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="deckAreaSplitPane" alignment="0" pref="918" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="deckAreaSplitPane" alignment="0" pref="377" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JSplitPane" name="deckAreaSplitPane">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="null"/>
|
||||
</Property>
|
||||
<Property name="resizeWeight" type="double" value="0.6"/>
|
||||
<Property name="dividerSize" type="int" value="10"/>
|
||||
<Property name="resizeWeight" type="double" value="0.5"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Center"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="mage.client.cards.DragCardGrid" name="dragCardGrid1">
|
||||
<Component class="mage.client.cards.DragCardGrid" name="deckList">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[200, 56]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
||||
<JSplitPaneConstraints position="left"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="mage.client.cards.DragCardGrid" name="dragCardGrid2">
|
||||
<Component class="mage.client.cards.DragCardGrid" name="sideboardList">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[200, 56]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
||||
<JSplitPaneConstraints position="right"/>
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
|
||||
/*
|
||||
* DeckArea.java
|
||||
*
|
||||
* Created on Feb 18, 2010, 3:10:39 PM
|
||||
*/
|
||||
package mage.client.deckeditor;
|
||||
|
||||
import mage.cards.Card;
|
||||
|
@ -26,7 +20,6 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class DeckArea extends javax.swing.JPanel {
|
||||
|
@ -38,7 +31,6 @@ public class DeckArea extends javax.swing.JPanel {
|
|||
private BigCard lastBigCard = null;
|
||||
private int dividerLocationNormal = 0;
|
||||
private int dividerLocationLimited = 0;
|
||||
private static final boolean isLimitedBuildingOrientation = false;
|
||||
|
||||
public DeckCardLayout getCardLayout() {
|
||||
return deckList.getCardLayout();
|
||||
|
@ -170,7 +162,7 @@ public class DeckArea extends javax.swing.JPanel {
|
|||
});
|
||||
}
|
||||
|
||||
public Settings saveSettings() {
|
||||
public Settings saveSettings(boolean isLimitedBuildingOrientation) {
|
||||
Settings settings = new Settings();
|
||||
settings.maindeckSettings = deckList.saveSettings();
|
||||
settings.sideboardSetings = sideboardList.saveSettings();
|
||||
|
@ -184,7 +176,7 @@ public class DeckArea extends javax.swing.JPanel {
|
|||
return settings;
|
||||
}
|
||||
|
||||
public void loadSettings(Settings s) {
|
||||
public void loadSettings(Settings s, boolean isLimitedBuildingOrientation) {
|
||||
if (s != null) {
|
||||
deckList.loadSettings(s.maindeckSettings);
|
||||
sideboardList.loadSettings(s.sideboardSetings);
|
||||
|
@ -215,8 +207,8 @@ public class DeckArea extends javax.swing.JPanel {
|
|||
private void setGUISize() {
|
||||
}
|
||||
|
||||
public void setOrientation(boolean limitedBuildingOrientation) {
|
||||
if (limitedBuildingOrientation) {
|
||||
public void setOrientation(boolean isLimitedBuildingOrientation) {
|
||||
if (isLimitedBuildingOrientation) {
|
||||
deckAreaSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
|
||||
if (dividerLocationLimited != 0) {
|
||||
deckAreaSplitPane.setDividerLocation(dividerLocationLimited);
|
||||
|
@ -298,21 +290,19 @@ public class DeckArea extends javax.swing.JPanel {
|
|||
deckList = new mage.client.cards.DragCardGrid();
|
||||
sideboardList = new mage.client.cards.DragCardGrid();
|
||||
|
||||
setLayout(new java.awt.BorderLayout());
|
||||
|
||||
deckAreaSplitPane.setBorder(null);
|
||||
deckAreaSplitPane.setResizeWeight(0.6);
|
||||
deckAreaSplitPane.setDividerSize(10);
|
||||
deckAreaSplitPane.setResizeWeight(0.5);
|
||||
|
||||
deckList.setMinimumSize(new java.awt.Dimension(200, 56));
|
||||
deckAreaSplitPane.setLeftComponent(deckList);
|
||||
|
||||
sideboardList.setMinimumSize(new java.awt.Dimension(200, 56));
|
||||
deckAreaSplitPane.setRightComponent(sideboardList);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(deckAreaSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 918, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(deckAreaSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 377, Short.MAX_VALUE)
|
||||
);
|
||||
add(deckAreaSplitPane, java.awt.BorderLayout.CENTER);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
public DragCardGrid getDeckList() {
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="mage.client.deckeditor.DeckEditorPanel" name="deckEditorPanel1">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[1000, 500]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Center"/>
|
||||
|
|
|
@ -74,6 +74,7 @@ public class DeckEditorPane extends MagePane {
|
|||
deckEditorPanel1 = new mage.client.deckeditor.DeckEditorPanel();
|
||||
filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 10), new java.awt.Dimension(0, 32767));
|
||||
|
||||
deckEditorPanel1.setMinimumSize(new java.awt.Dimension(1000, 500));
|
||||
getContentPane().add(deckEditorPanel1, java.awt.BorderLayout.CENTER);
|
||||
getContentPane().add(filler1, java.awt.BorderLayout.NORTH);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<SubComponents>
|
||||
<Container class="javax.swing.JSplitPane" name="panelRight">
|
||||
<Properties>
|
||||
<Property name="dividerSize" type="int" value="10"/>
|
||||
<Property name="orientation" type="int" value="0"/>
|
||||
<Property name="resizeWeight" type="double" value="0.5"/>
|
||||
</Properties>
|
||||
|
@ -47,6 +48,11 @@
|
|||
</Constraints>
|
||||
</Component>
|
||||
<Component class="mage.client.deckeditor.DeckArea" name="deckArea">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[200, 56]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
||||
<JSplitPaneConstraints position="bottom"/>
|
||||
|
|
|
@ -78,7 +78,6 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
deckArea.setOpaque(false);
|
||||
panelLeft.setOpaque(false);
|
||||
panelRight.setOpaque(false);
|
||||
restoreDividerLocationsAndDeckAreaSettings();
|
||||
countdown = new javax.swing.Timer(1000,
|
||||
e -> {
|
||||
if (--timeout > 0) {
|
||||
|
@ -93,13 +92,18 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
}
|
||||
});
|
||||
|
||||
// Set up tracking to save the deck editor settings when the deck editor is hidden.
|
||||
// save editor settings dynamicly on hides (e.g. app close)
|
||||
addHierarchyListener((HierarchyEvent e) -> {
|
||||
if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {
|
||||
if (!isShowing()) {
|
||||
// It's bugged and called on sideboarding creates too (before load). So:
|
||||
// * for free mode - save here
|
||||
// * for draft/sideboarding - save on cleanup call
|
||||
if (mode == DeckEditorMode.FREE_BUILDING) {
|
||||
saveDividerLocationsAndDeckAreaSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -127,21 +131,32 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
}
|
||||
|
||||
private void saveDividerLocationsAndDeckAreaSettings() {
|
||||
PreferencesDialog.saveValue(PreferencesDialog.KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION, Integer.toString(panelRight.getDividerLocation()));
|
||||
PreferencesDialog.saveValue(PreferencesDialog.KEY_EDITOR_DECKAREA_SETTINGS, this.deckArea.saveSettings().toString());
|
||||
boolean isLimitedBuildingOrientation = (mode != DeckEditorMode.FREE_BUILDING);
|
||||
if (isLimitedBuildingOrientation) {
|
||||
PreferencesDialog.saveValue(PreferencesDialog.KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION_LIMITED, Integer.toString(panelRight.getDividerLocation()));
|
||||
} else {
|
||||
PreferencesDialog.saveValue(PreferencesDialog.KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION_NORMAL, Integer.toString(panelRight.getDividerLocation()));
|
||||
}
|
||||
|
||||
PreferencesDialog.saveValue(PreferencesDialog.KEY_EDITOR_DECKAREA_SETTINGS, this.deckArea.saveSettings(isLimitedBuildingOrientation).toString());
|
||||
}
|
||||
|
||||
private void restoreDividerLocationsAndDeckAreaSettings() {
|
||||
// Load horizontal split position setting
|
||||
String dividerLocation = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION, "");
|
||||
String dividerLocation = "";
|
||||
boolean isLimitedBuildingOrientation = (mode != DeckEditorMode.FREE_BUILDING);
|
||||
if (isLimitedBuildingOrientation) {
|
||||
dividerLocation = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION_LIMITED, "");
|
||||
} else {
|
||||
dividerLocation = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION_NORMAL, "");
|
||||
}
|
||||
if (!dividerLocation.isEmpty()) {
|
||||
panelRight.setDividerLocation(Integer.parseInt(dividerLocation));
|
||||
}
|
||||
|
||||
// Load deck area settings
|
||||
this.deckArea.loadSettings(
|
||||
DeckArea.Settings.parse(
|
||||
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_EDITOR_DECKAREA_SETTINGS, "")));
|
||||
DeckArea.Settings.parse(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_EDITOR_DECKAREA_SETTINGS, "")),
|
||||
isLimitedBuildingOrientation);
|
||||
}
|
||||
|
||||
public void changeGUISize() {
|
||||
|
@ -157,11 +172,12 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
this.mode = mode;
|
||||
this.btnAddLand.setVisible(false);
|
||||
|
||||
restoreDividerLocationsAndDeckAreaSettings();
|
||||
switch (mode) {
|
||||
case LIMITED_BUILDING:
|
||||
this.btnAddLand.setVisible(true);
|
||||
this.txtTimeRemaining.setVisible(true);
|
||||
// Fall through to sideboarding
|
||||
// Fall through to sideboarding (no break)
|
||||
case SIDEBOARDING:
|
||||
this.btnSubmit.setVisible(true);
|
||||
this.btnSubmitTimer.setVisible(true);
|
||||
|
@ -864,9 +880,12 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
txtTimeRemaining = new javax.swing.JTextField();
|
||||
deckLegalityDisplay = new mage.client.deckeditor.DeckLegalityPanel();
|
||||
|
||||
panelRight.setDividerSize(10);
|
||||
panelRight.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
|
||||
panelRight.setResizeWeight(0.5);
|
||||
panelRight.setTopComponent(cardSelector);
|
||||
|
||||
deckArea.setMinimumSize(new java.awt.Dimension(200, 56));
|
||||
panelRight.setBottomComponent(deckArea);
|
||||
|
||||
panelDeck.setOpaque(false);
|
||||
|
@ -1193,7 +1212,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(panelLeft, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(panelRight, javax.swing.GroupLayout.PREFERRED_SIZE, 890, Short.MAX_VALUE))
|
||||
.addComponent(panelRight, javax.swing.GroupLayout.DEFAULT_SIZE, 890, Short.MAX_VALUE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
|
|
|
@ -3,6 +3,7 @@ package mage.client.dialog;
|
|||
import mage.client.MageFrame;
|
||||
import mage.client.SessionHandler;
|
||||
import mage.client.components.KeyBindButton;
|
||||
import mage.client.themes.ThemeType;
|
||||
import mage.client.util.CardLanguage;
|
||||
import mage.client.util.ClientDefaultSettings;
|
||||
import mage.client.util.GUISizeHelper;
|
||||
|
@ -15,7 +16,6 @@ import mage.remote.Connection;
|
|||
import mage.remote.Connection.ProxyType;
|
||||
import mage.view.UserRequestMessage;
|
||||
import org.apache.log4j.Logger;
|
||||
import mage.client.themes.ThemeType;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
|
@ -160,7 +160,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
public static final String KEY_TABLES_DIVIDER_LOCATION_4 = "tablePanelDividerLocation4";
|
||||
|
||||
// Positions of deck editor divider bars
|
||||
public static final String KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION = "editorHorizontalDividerLocation";
|
||||
public static final String KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION_NORMAL = "editorHorizontalDividerLocationNormal";
|
||||
public static final String KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION_LIMITED = "editorHorizontalDividerLocationLimited";
|
||||
public static final String KEY_EDITOR_DECKAREA_SETTINGS = "editorDeckAreaSettings";
|
||||
|
||||
// user list
|
||||
|
|
|
@ -29,13 +29,13 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class AlpineHoundmaster extends CardImpl {
|
||||
|
||||
private static final FilterPermanent filter = new FilterAttackingCreature();
|
||||
private static final FilterPermanent filter = new FilterAttackingCreature("the number of other attacking creatures");
|
||||
|
||||
static {
|
||||
filter.add(AnotherPredicate.instance);
|
||||
}
|
||||
|
||||
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
|
||||
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter, null);
|
||||
|
||||
public AlpineHoundmaster(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{W}");
|
||||
|
@ -50,8 +50,8 @@ public final class AlpineHoundmaster extends CardImpl {
|
|||
|
||||
// Whenever Alpine Houndmaster attacks, it gets +X/+0 until end of turn, where X is the number of other attacking creatures.
|
||||
this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(
|
||||
xValue, StaticValue.get(0), Duration.EndOfTurn
|
||||
), false, "it gets +X/+0 until end of turn, where X is the number of other attacking creatures"));
|
||||
xValue, StaticValue.get(0), Duration.EndOfTurn, true
|
||||
), false));
|
||||
}
|
||||
|
||||
private AlpineHoundmaster(final AlpineHoundmaster card) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -19,8 +20,6 @@ import mage.game.Game;
|
|||
import mage.game.permanent.Permanent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
@ -82,9 +81,12 @@ class AnimarCostReductionEffect extends CostModificationEffectImpl {
|
|||
public boolean applies(Ability abilityToModify, Ability source, Game game) {
|
||||
if (abilityToModify instanceof SpellAbility) {
|
||||
if (abilityToModify.isControlledBy(source.getControllerId())) {
|
||||
Card card = ((SpellAbility) abilityToModify).getCharacteristics(game);
|
||||
if (card != null) {
|
||||
return card.isCreature();
|
||||
Card spellCard = ((SpellAbility) abilityToModify).getCharacteristics(game);
|
||||
if (spellCard != null) {
|
||||
if (((SpellAbility) abilityToModify).getSpellAbilityCastMode() != SpellAbilityCastMode.NORMAL) {
|
||||
spellCard = ((SpellAbility) abilityToModify).getSpellAbilityCastMode().getTypeModifiedCardObjectCopy(spellCard, game);
|
||||
}
|
||||
return spellCard.isCreature();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
|
@ -9,10 +7,13 @@ import mage.abilities.condition.common.MetalcraftCondition;
|
|||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author Loki
|
||||
*/
|
||||
|
@ -32,6 +33,7 @@ public final class ArdentRecruit extends CardImpl {
|
|||
"{this} gets +2/+2 as long as you control three or more artifacts");
|
||||
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
|
||||
ability.setAbilityWord(AbilityWord.METALCRAFT);
|
||||
ability.addHint(MetalcraftHint.instance);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -12,6 +10,7 @@ import mage.abilities.costs.mana.ManaCostsImpl;
|
|||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -20,8 +19,9 @@ import mage.game.Game;
|
|||
import mage.game.permanent.Permanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Loki
|
||||
*/
|
||||
public final class ArgentSphinx extends CardImpl {
|
||||
|
@ -39,6 +39,7 @@ public final class ArgentSphinx extends CardImpl {
|
|||
// <i>Metalcraft</i> — {U}: Exile Argent Sphinx. Return it to the battlefield under your control at the beginning of the next end step. Activate this ability only if you control three or more artifacts.
|
||||
Ability ability = new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, new ArgentSphinxEffect(), new ManaCostsImpl("{U}"), MetalcraftCondition.instance);
|
||||
ability.setAbilityWord(AbilityWord.METALCRAFT);
|
||||
ability.addHint(MetalcraftHint.instance);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.LoyaltyAbility;
|
||||
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
|
@ -17,11 +20,6 @@ import mage.target.common.TargetCardInExile;
|
|||
import mage.target.common.TargetCardInHand;
|
||||
import mage.target.common.TargetNonlandPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageObjectReference;
|
||||
import mage.cards.Card;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
|
@ -42,7 +40,7 @@ public final class AshiokNightmareMuse extends CardImpl {
|
|||
ability.addTarget(new TargetNonlandPermanent());
|
||||
this.addAbility(ability);
|
||||
|
||||
// −7: You may cast up to three face-up cards your opponents own from exile without paying their mana costs.
|
||||
// −7: You may cast up to three spells from among face-up cards your opponents own from exile without paying their mana costs.
|
||||
this.addAbility(new LoyaltyAbility(new AshiokNightmareMuseCastEffect(), -7));
|
||||
}
|
||||
|
||||
|
@ -102,7 +100,7 @@ class AshiokNightmareMuseCastEffect extends OneShotEffect {
|
|||
|
||||
AshiokNightmareMuseCastEffect() {
|
||||
super(Outcome.Discard);
|
||||
staticText = "You may cast up to three face-up cards your opponents own from exile without paying their mana costs.";
|
||||
staticText = "You may cast up to three spells from among face-up cards your opponents own from exile without paying their mana costs.";
|
||||
}
|
||||
|
||||
private AshiokNightmareMuseCastEffect(final AshiokNightmareMuseCastEffect effect) {
|
||||
|
|
|
@ -1,23 +1,20 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.keyword.DoubleStrikeAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author maurer.it_at_gmail.com
|
||||
*/
|
||||
public final class AuriokEdgewright extends CardImpl {
|
||||
|
@ -33,7 +30,12 @@ public final class AuriokEdgewright extends CardImpl {
|
|||
this.toughness = new MageInt(2);
|
||||
|
||||
ContinuousEffect effect = new GainAbilitySourceEffect(DoubleStrikeAbility.getInstance(), Duration.WhileOnBattlefield);
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(effect, MetalcraftCondition.instance, effectText)));
|
||||
this.addAbility(new SimpleStaticAbility(
|
||||
Zone.BATTLEFIELD,
|
||||
new ConditionalContinuousEffect(effect, MetalcraftCondition.instance, effectText))
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance)
|
||||
);
|
||||
}
|
||||
|
||||
public AuriokEdgewright(final AuriokEdgewright card) {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
|
@ -9,16 +7,15 @@ import mage.abilities.decorator.ConditionalContinuousEffect;
|
|||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author maurer.it_at_gmail.com
|
||||
*/
|
||||
public final class AuriokSunchaser extends CardImpl {
|
||||
|
@ -35,9 +32,18 @@ public final class AuriokSunchaser extends CardImpl {
|
|||
this.toughness = new MageInt(1);
|
||||
|
||||
ContinuousEffect effect1 = new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield);
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(effect1, MetalcraftCondition.instance, effect1Text)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
|
||||
new ConditionalContinuousEffect(effect1, MetalcraftCondition.instance, effect1Text))
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance)
|
||||
);
|
||||
|
||||
ContinuousEffect effect2 = new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield);
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(effect2, MetalcraftCondition.instance, effect2Text)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
|
||||
new ConditionalContinuousEffect(effect2, MetalcraftCondition.instance, effect2Text))
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance)
|
||||
);
|
||||
}
|
||||
|
||||
public AuriokSunchaser(final AuriokSunchaser card) {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.b;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
|
@ -9,15 +7,18 @@ import mage.abilities.condition.common.MetalcraftCondition;
|
|||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.keyword.HasteAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author North
|
||||
*/
|
||||
public final class BladeTribeBerserkers extends CardImpl {
|
||||
|
@ -34,7 +35,10 @@ public final class BladeTribeBerserkers extends CardImpl {
|
|||
//<i>Metalcraft</i> — When Blade-Tribe Berserkers enters the battlefield, if you control three or more artifacts, Blade-Tribe Berserkers gets +3/+3 and gains haste until end of turn.
|
||||
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new BoostSourceEffect(3, 3, Duration.EndOfTurn), false);
|
||||
ability.addEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.EndOfTurn));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, MetalcraftCondition.instance, effectText));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, MetalcraftCondition.instance, effectText)
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance)
|
||||
);
|
||||
}
|
||||
|
||||
public BladeTribeBerserkers(final BladeTribeBerserkers card) {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.b;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
|
@ -9,15 +7,18 @@ import mage.abilities.condition.common.MetalcraftCondition;
|
|||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.abilities.effects.common.LoseLifeTargetEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author North
|
||||
*/
|
||||
public final class BleakCovenVampires extends CardImpl {
|
||||
|
@ -37,7 +38,10 @@ public final class BleakCovenVampires extends CardImpl {
|
|||
Target target = new TargetPlayer();
|
||||
ability.addTarget(target);
|
||||
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, MetalcraftCondition.instance, effectText));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, MetalcraftCondition.instance, effectText)
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance)
|
||||
);
|
||||
}
|
||||
|
||||
public BleakCovenVampires(final BleakCovenVampires card) {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
package mage.cards.c;
|
||||
|
||||
import mage.MageInt;
|
||||
|
@ -7,12 +5,10 @@ import mage.abilities.common.SimpleStaticAbility;
|
|||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -35,8 +31,9 @@ public final class CarapaceForger extends CardImpl {
|
|||
new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield),
|
||||
MetalcraftCondition.instance, "<i>Metalcraft</i> — {this} gets " +
|
||||
"+2/+2 as long as you control three or more artifacts"
|
||||
)
|
||||
));
|
||||
))
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance));
|
||||
}
|
||||
|
||||
public CarapaceForger(final CarapaceForger card) {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
package mage.cards.c;
|
||||
|
||||
import mage.MageInt;
|
||||
|
@ -7,12 +5,10 @@ import mage.abilities.common.SimpleStaticAbility;
|
|||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -33,8 +29,9 @@ public final class ChromeSteed extends CardImpl {
|
|||
new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield),
|
||||
MetalcraftCondition.instance, "<i>Metalcraft</i> — {this} gets " +
|
||||
"+2/+2 as long as you control three or more artifacts"
|
||||
)
|
||||
));
|
||||
))
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance));
|
||||
}
|
||||
|
||||
public ChromeSteed(final ChromeSteed card) {
|
||||
|
|
|
@ -5,8 +5,10 @@ import mage.abilities.condition.common.MetalcraftCondition;
|
|||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.RestrictionEffect;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
|
@ -28,9 +30,12 @@ public final class ConcussiveBolt extends CardImpl {
|
|||
// Concussive Bolt deals 4 damage to target player.
|
||||
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
|
||||
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
|
||||
|
||||
// <i>Metalcraft</i> — If you control three or more artifacts, creatures that player controls can't block this turn.
|
||||
this.getSpellAbility().addEffect(new ConcussiveBoltEffect());
|
||||
this.getSpellAbility().addEffect(new ConcussiveBoltRestrictionEffect());
|
||||
this.getSpellAbility().setAbilityWord(AbilityWord.METALCRAFT);
|
||||
this.getSpellAbility().addHint(MetalcraftHint.instance);
|
||||
}
|
||||
|
||||
public ConcussiveBolt(final ConcussiveBolt card) {
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
|
||||
|
||||
package mage.cards.d;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.abilities.effects.common.TapTargetEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
import mage.constants.CardType;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Loki
|
||||
*/
|
||||
public final class Dispatch extends CardImpl {
|
||||
|
@ -21,9 +21,14 @@ public final class Dispatch extends CardImpl {
|
|||
public Dispatch(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}");
|
||||
|
||||
// Tap target creature.
|
||||
this.getSpellAbility().addEffect(new TapTargetEffect());
|
||||
|
||||
// Metalcraft — If you control three or more artifacts, exile that creature.
|
||||
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new ExileTargetEffect(), MetalcraftCondition.instance, "<i>Metalcraft</i> — If you control three or more artifacts, exile that creature"));
|
||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||
this.getSpellAbility().setAbilityWord(AbilityWord.METALCRAFT);
|
||||
this.getSpellAbility().addHint(MetalcraftHint.instance);
|
||||
}
|
||||
|
||||
public Dispatch(final Dispatch card) {
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
|
||||
|
||||
package mage.cards.d;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.SacrificeEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.common.FilterAttackingCreature;
|
||||
import mage.game.Game;
|
||||
import mage.target.TargetPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author maurer.it_at_gmail.com
|
||||
*/
|
||||
public final class DispenseJustice extends CardImpl {
|
||||
|
@ -24,9 +24,12 @@ public final class DispenseJustice extends CardImpl {
|
|||
public DispenseJustice(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}");
|
||||
|
||||
|
||||
// Target player sacrifices an attacking creature.
|
||||
// Metalcraft — That player sacrifices two attacking creatures instead if you control three or more artifacts.
|
||||
this.getSpellAbility().addEffect(new DispenseJusticeEffect());
|
||||
this.getSpellAbility().addTarget(new TargetPlayer());
|
||||
this.getSpellAbility().setAbilityWord(AbilityWord.METALCRAFT);
|
||||
this.getSpellAbility().addHint(MetalcraftHint.instance);
|
||||
}
|
||||
|
||||
public DispenseJustice(final DispenseJustice card) {
|
||||
|
@ -60,8 +63,7 @@ class DispenseJusticeEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
if (MetalcraftCondition.instance.apply(game, source)) {
|
||||
return new SacrificeEffect(filter, 2, effectText).apply(game, source);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return new SacrificeEffect(filter, 1, effectText).apply(game, source);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.d;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -9,10 +7,11 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreatureCard;
|
||||
import mage.filter.predicate.other.FaceDownPredicate;
|
||||
import mage.filter.predicate.other.FaceDownCastablePredicate;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author North
|
||||
*/
|
||||
public final class DreamChisel extends CardImpl {
|
||||
|
@ -20,7 +19,7 @@ public final class DreamChisel extends CardImpl {
|
|||
private static final FilterCreatureCard filter = new FilterCreatureCard("Face-down creature spells");
|
||||
|
||||
static {
|
||||
filter.add(FaceDownPredicate.instance);
|
||||
filter.add(FaceDownCastablePredicate.instance);
|
||||
}
|
||||
|
||||
public DreamChisel(UUID ownerId, CardSetInfo setInfo) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.d;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -11,12 +10,12 @@ import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
|
|||
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.AbilityType;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.CostModificationType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
|
@ -54,8 +53,9 @@ public final class Drought extends CardImpl {
|
|||
|
||||
class DroughtAdditionalCostEffect extends CostModificationEffectImpl {
|
||||
|
||||
private boolean appliesToSpells;
|
||||
private final boolean appliesToSpells;
|
||||
private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Swamp");
|
||||
|
||||
static {
|
||||
filter.add(SubType.SWAMP.getPredicate());
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package mage.cards.e;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.common.SagaAbility;
|
||||
|
@ -23,8 +24,6 @@ import mage.target.TargetPermanent;
|
|||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
|
@ -99,12 +98,17 @@ class ElspethConquersDeathCostEffect extends CostModificationEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(Ability abilityToModify, Ability source, Game game) {
|
||||
if (!(abilityToModify instanceof SpellAbility) ||
|
||||
!game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) {
|
||||
return false;
|
||||
if ((abilityToModify instanceof SpellAbility)
|
||||
&& game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) {
|
||||
Card spellCard = ((SpellAbility) abilityToModify).getCharacteristics(game);
|
||||
if (spellCard != null) {
|
||||
if (((SpellAbility) abilityToModify).getSpellAbilityCastMode() != SpellAbilityCastMode.NORMAL) {
|
||||
spellCard = ((SpellAbility) abilityToModify).getSpellAbilityCastMode().getTypeModifiedCardObjectCopy(spellCard, game);
|
||||
}
|
||||
Card card = game.getCard(abilityToModify.getSourceId());
|
||||
return card != null && !card.isCreature();
|
||||
return !spellCard.isCreature();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -117,8 +121,8 @@ class ElspethConquersDeathReturnEffect extends OneShotEffect {
|
|||
|
||||
ElspethConquersDeathReturnEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "Return target creature or planeswalker card from your graveyard to the battlefield. " +
|
||||
"Put a +1/+1 counter or a loyalty counter on it";
|
||||
staticText = "Return target creature or planeswalker card from your graveyard to the battlefield. "
|
||||
+ "Put a +1/+1 counter or a loyalty counter on it";
|
||||
}
|
||||
|
||||
private ElspethConquersDeathReturnEffect(final ElspethConquersDeathReturnEffect effect) {
|
||||
|
@ -149,4 +153,5 @@ class ElspethConquersDeathReturnEffect extends OneShotEffect {
|
|||
permanent.addCounters(counter, source, game);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.e;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
|
@ -9,19 +7,18 @@ import mage.abilities.condition.common.MetalcraftCondition;
|
|||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.keyword.ProtectionAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author North
|
||||
*/
|
||||
public final class EtchedChampion extends CardImpl {
|
||||
|
@ -45,8 +42,13 @@ public final class EtchedChampion extends CardImpl {
|
|||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
// Metalcraft — Etched Champion has protection from all colors as long as you control three or more artifacts.
|
||||
ContinuousEffect effect = new GainAbilitySourceEffect(new ProtectionAbility(filter), Duration.WhileOnBattlefield);
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(effect, MetalcraftCondition.instance, ruleText)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
|
||||
new ConditionalContinuousEffect(effect, MetalcraftCondition.instance, ruleText))
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance)
|
||||
);
|
||||
}
|
||||
|
||||
public EtchedChampion(final EtchedChampion card) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.e;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -20,7 +19,7 @@ public final class EyeOfRamos extends CardImpl {
|
|||
public EyeOfRamos(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
|
||||
|
||||
// {tap}: Add {U}.
|
||||
// {T}: Add {U}.
|
||||
this.addAbility(new BlueManaAbility());
|
||||
|
||||
// Sacrifice Eye of Ramos: Add {U}.
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
|
||||
|
||||
package mage.cards.e;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
|
@ -11,16 +8,15 @@ import mage.abilities.decorator.ConditionalContinuousEffect;
|
|||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Loki
|
||||
*/
|
||||
public final class EzurisBrigade extends CardImpl {
|
||||
|
@ -30,13 +26,16 @@ public final class EzurisBrigade extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}");
|
||||
this.subtype.add(SubType.ELF);
|
||||
this.subtype.add(SubType.WARRIOR);
|
||||
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(4);
|
||||
|
||||
// Metalcraft — As long as you control three or more artifacts, Ezuri’s Brigade gets +4/+4 and has trample.
|
||||
ContinuousEffect boostSource = new BoostSourceEffect(4, 4, Duration.WhileOnBattlefield);
|
||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(boostSource, MetalcraftCondition.instance, rule);
|
||||
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
|
||||
ability.addEffect(new ConditionalContinuousEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield), MetalcraftCondition.instance, ""));
|
||||
ability.setAbilityWord(AbilityWord.METALCRAFT);
|
||||
ability.addHint(MetalcraftHint.instance);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,10 @@ package mage.cards.g;
|
|||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
import mage.constants.CardType;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
|
||||
|
@ -29,6 +31,8 @@ public final class GalvanicBlast extends CardImpl {
|
|||
MetalcraftCondition.instance, effectText
|
||||
));
|
||||
this.getSpellAbility().addTarget(new TargetAnyTarget());
|
||||
this.getSpellAbility().setAbilityWord(AbilityWord.METALCRAFT);
|
||||
this.getSpellAbility().addHint(MetalcraftHint.instance);
|
||||
}
|
||||
|
||||
public GalvanicBlast(final GalvanicBlast card) {
|
||||
|
|
|
@ -1,23 +1,19 @@
|
|||
|
||||
|
||||
package mage.cards.g;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
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.constants.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Loki
|
||||
*/
|
||||
public final class GhalmasWarden extends CardImpl {
|
||||
|
@ -28,12 +24,16 @@ public final class GhalmasWarden extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
|
||||
this.subtype.add(SubType.ELEPHANT);
|
||||
this.subtype.add(SubType.SOLDIER);
|
||||
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(4);
|
||||
|
||||
// Metalcraft — Ghalma’s Warden 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, rule);
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance)
|
||||
);
|
||||
}
|
||||
|
||||
public GhalmasWarden(final GhalmasWarden card) {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package mage.cards.g;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import mage.*;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
|
@ -124,21 +122,6 @@ class GrandArchitectManaAbility extends ActivatedManaAbilityImpl {
|
|||
this.filter = ability.filter.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Mana> getNetMana(Game game) {
|
||||
if (game != null && game.inCheckPlayableState()) {
|
||||
int count = game.getBattlefield().count(filter, getSourceId(), getControllerId(), game);
|
||||
List<Mana> netMana = new ArrayList<>();
|
||||
if (count > 0) {
|
||||
ConditionalMana mana = new GrandArchitectConditionalMana();
|
||||
mana.setColorless(count * 2);
|
||||
netMana.add(mana);
|
||||
}
|
||||
return netMana;
|
||||
}
|
||||
return super.getNetMana(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrandArchitectManaAbility copy() {
|
||||
return new GrandArchitectManaAbility(this);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.h;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
|
@ -10,8 +8,8 @@ import mage.abilities.effects.OneShotEffect;
|
|||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.Game;
|
||||
|
@ -20,8 +18,9 @@ import mage.game.events.GameEvent.EventType;
|
|||
import mage.game.permanent.Permanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public final class HamletbackGoliath extends CardImpl {
|
||||
|
@ -72,7 +71,7 @@ class HamletbackGoliathTriggeredAbility extends TriggeredAbilityImpl {
|
|||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
UUID targetId = event.getTargetId();
|
||||
Permanent permanent = game.getPermanent(targetId);
|
||||
if (permanent.isCreature()
|
||||
if (permanent != null && permanent.isCreature()
|
||||
&& !(targetId.equals(this.getSourceId()))) {
|
||||
for (Effect effect : this.getEffects()) {
|
||||
effect.setTargetPointer(new FixedTarget(event.getTargetId()));
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.h;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -54,7 +53,7 @@ class HeraldOfWarCostReductionEffect extends CostModificationEffectImpl {
|
|||
|
||||
HeraldOfWarCostReductionEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST);
|
||||
staticText = "Angel spells and Human spells you cast cost {1} less to cast for each +1/+1 counter on Herald of War";
|
||||
staticText = "Angel spells and Human spells you cast cost {1} less to cast for each +1/+1 counter on {this}";
|
||||
}
|
||||
|
||||
HeraldOfWarCostReductionEffect(HeraldOfWarCostReductionEffect effect) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package mage.cards.h;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
|
@ -13,6 +12,7 @@ import mage.game.Game;
|
|||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.cards.Card;
|
||||
|
||||
/**
|
||||
* @author Pete Rossi
|
||||
|
@ -58,9 +58,12 @@ class HumOfTheRadixCostIncreaseEffect extends CostModificationEffectImpl {
|
|||
@Override
|
||||
public boolean applies(Ability abilityToModify, Ability source, Game game) {
|
||||
if (abilityToModify instanceof SpellAbility) {
|
||||
MageObject sourceObject = abilityToModify.getSourceObject(game);
|
||||
if (sourceObject != null && sourceObject.isArtifact()) {
|
||||
return true;
|
||||
Card spellCard = ((SpellAbility) abilityToModify).getCharacteristics(game);
|
||||
if (spellCard != null) {
|
||||
if (((SpellAbility) abilityToModify).getSpellAbilityCastMode() != SpellAbilityCastMode.NORMAL) {
|
||||
spellCard = ((SpellAbility) abilityToModify).getSpellAbilityCastMode().getTypeModifiedCardObjectCopy(spellCard, game);
|
||||
}
|
||||
return !spellCard.isArtifact();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
package mage.cards.h;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -18,6 +16,7 @@ public final class HuntersFeast extends CardImpl {
|
|||
public HuntersFeast(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}");
|
||||
|
||||
// Any number of target players each gain 6 life.
|
||||
this.getSpellAbility().addTarget(new TargetPlayer(0, Integer.MAX_VALUE, false));
|
||||
this.getSpellAbility().addEffect(new GainLifeTargetEffect(6));
|
||||
}
|
||||
|
|
|
@ -1,24 +1,21 @@
|
|||
|
||||
|
||||
package mage.cards.i;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.ShroudAbility;
|
||||
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.constants.*;
|
||||
import mage.filter.FilterPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
*/
|
||||
|
@ -35,13 +32,19 @@ public final class IndomitableArchangel extends CardImpl {
|
|||
public IndomitableArchangel(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}");
|
||||
this.subtype.add(SubType.ANGEL);
|
||||
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(4);
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Metalcraft — Artifacts you control have shroud as long as you control three or more artifacts. (An artifact with shroud can’t be the target of spells or abilities.)
|
||||
ContinuousEffect gainAbilityEffect = new GainAbilityControlledEffect(ShroudAbility.getInstance(), Duration.WhileOnBattlefield, filter);
|
||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(gainAbilityEffect, MetalcraftCondition.instance, rule);
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance)
|
||||
);
|
||||
}
|
||||
|
||||
public IndomitableArchangel(final IndomitableArchangel card) {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.i;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.ActivateIfConditionActivatedAbility;
|
||||
|
@ -11,9 +9,11 @@ import mage.abilities.costs.common.TapSourceCost;
|
|||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.mana.ColorlessManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
|
@ -24,8 +24,9 @@ import mage.game.events.GameEvent;
|
|||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fireshoes
|
||||
*/
|
||||
public final class InventorsFair extends CardImpl {
|
||||
|
@ -52,6 +53,8 @@ public final class InventorsFair extends CardImpl {
|
|||
new GenericManaCost(4), MetalcraftCondition.instance);
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addCost(new SacrificeSourceCost());
|
||||
ability.setAbilityWord(AbilityWord.METALCRAFT);
|
||||
ability.addHint(MetalcraftHint.instance);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,24 +1,20 @@
|
|||
|
||||
package mage.cards.j;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.keyword.FirstStrikeAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
import mage.filter.StaticFilters;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author North
|
||||
*/
|
||||
public final class JorKadeenThePrevailer extends CardImpl {
|
||||
|
@ -40,7 +36,9 @@ public final class JorKadeenThePrevailer extends CardImpl {
|
|||
// <i>Metalcraft</i> — Creatures you control get +3/+0 as long as you control three or more artifacts.
|
||||
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(new BoostControlledEffect(3, 0, Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE, false),
|
||||
MetalcraftCondition.instance, effectText);
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance));
|
||||
}
|
||||
|
||||
public JorKadeenThePrevailer(final JorKadeenThePrevailer card) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
|
|||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
|
@ -14,10 +15,9 @@ import mage.constants.WatcherScope;
|
|||
import mage.filter.FilterCard;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.predicate.ObjectPlayer;
|
||||
import mage.filter.predicate.ObjectPlayerPredicate;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.filter.predicate.other.FaceDownCastablePredicate;
|
||||
import mage.filter.predicate.other.FaceDownPredicate;
|
||||
import mage.game.Controllable;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.stack.Spell;
|
||||
|
@ -32,12 +32,12 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class KadenaSlinkingSorcerer extends CardImpl {
|
||||
|
||||
private static final FilterCard filter = new FilterCard();
|
||||
private static final FilterPermanent filter2 = new FilterControlledCreaturePermanent("a face-down creature");
|
||||
private static final FilterCard filterFirstFaceDownSpell = new FilterCard("first face-down creature spell");
|
||||
private static final FilterPermanent filterFaceDownPermanent = new FilterControlledCreaturePermanent("a face-down creature");
|
||||
|
||||
static {
|
||||
filter.add(KadenaSlinkingSorcererPredicate.instance);
|
||||
filter2.add(FaceDownPredicate.instance);
|
||||
filterFirstFaceDownSpell.add(KadenaSlinkingSorcererPredicate.instance);
|
||||
filterFaceDownPermanent.add(FaceDownPredicate.instance);
|
||||
}
|
||||
|
||||
public KadenaSlinkingSorcerer(UUID ownerId, CardSetInfo setInfo) {
|
||||
|
@ -51,13 +51,13 @@ public final class KadenaSlinkingSorcerer extends CardImpl {
|
|||
|
||||
// The first face-down creature spell you cast each turn costs {3} less to cast.
|
||||
this.addAbility(new SimpleStaticAbility(
|
||||
new SpellsCostReductionControllerEffect(filter, 3)
|
||||
new SpellsCostReductionControllerEffect(filterFirstFaceDownSpell, 3)
|
||||
.setText("The first face-down creature spell you cast each turn costs {3} less to cast.")
|
||||
), new KadenaSlinkingSorcererWatcher());
|
||||
|
||||
// Whenever a face-down creature enters the battlefield under your control, draw a card.
|
||||
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(
|
||||
new DrawCardSourceControllerEffect(1), filter2
|
||||
new DrawCardSourceControllerEffect(1), filterFaceDownPermanent
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -71,16 +71,15 @@ public final class KadenaSlinkingSorcerer extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
enum KadenaSlinkingSorcererPredicate implements ObjectPlayerPredicate<ObjectPlayer<Controllable>> {
|
||||
enum KadenaSlinkingSorcererPredicate implements Predicate<Card> {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(ObjectPlayer<Controllable> input, Game game) {
|
||||
if (input.getObject() instanceof Spell
|
||||
&& ((Spell) input.getObject()).isCreature()
|
||||
&& ((Spell) input.getObject()).isFaceDown(game)) {
|
||||
public boolean apply(Card input, Game game) {
|
||||
KadenaSlinkingSorcererWatcher watcher = game.getState().getWatcher(KadenaSlinkingSorcererWatcher.class);
|
||||
return watcher != null && !watcher.castFaceDownThisTurn(input.getPlayerId());
|
||||
if (watcher != null) {
|
||||
return FaceDownCastablePredicate.instance.apply(input, game)
|
||||
&& !watcher.castFaceDownThisTurn(input.getOwnerId());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.k;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.CompoundCondition;
|
||||
|
@ -10,18 +8,16 @@ import mage.abilities.condition.common.MetalcraftCondition;
|
|||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.decorator.ConditionalActivatedAbility;
|
||||
import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.HasteAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public final class KuldothaPhoenix extends CardImpl {
|
||||
|
@ -46,6 +42,7 @@ public final class KuldothaPhoenix extends CardImpl {
|
|||
new IsStepCondition(PhaseStep.UPKEEP), MetalcraftCondition.instance)
|
||||
);
|
||||
ability.setAbilityWord(AbilityWord.METALCRAFT);
|
||||
ability.addHint(MetalcraftHint.instance);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
|
||||
package mage.cards.l;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.ReturnToHandTargetEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author ayrat
|
||||
*/
|
||||
|
@ -37,6 +39,8 @@ public final class LumengridDrake extends CardImpl {
|
|||
TriggeredAbility conditional = new ConditionalInterveningIfTriggeredAbility(
|
||||
new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect()), MetalcraftCondition.instance, ruleText);
|
||||
conditional.addTarget(new TargetCreaturePermanent());
|
||||
conditional.setAbilityWord(AbilityWord.METALCRAFT);
|
||||
conditional.addHint(MetalcraftHint.instance);
|
||||
this.addAbility(conditional);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
|
||||
package mage.cards.m;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.condition.LockedInCondition;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author North
|
||||
*/
|
||||
public final class MirranMettle extends CardImpl {
|
||||
|
@ -23,12 +24,15 @@ public final class MirranMettle extends CardImpl {
|
|||
public MirranMettle(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}");
|
||||
|
||||
|
||||
// Target creature gets +2/+2 until end of turn.
|
||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||
this.getSpellAbility().addEffect(new BoostTargetEffect(2, 2, Duration.EndOfTurn));
|
||||
|
||||
// Metalcraft — That creature gets +4/+4 until end of turn instead if you control three or more artifacts.
|
||||
this.getSpellAbility().addEffect(new ConditionalContinuousEffect(new BoostTargetEffect(2, 2, Duration.EndOfTurn),
|
||||
new LockedInCondition(MetalcraftCondition.instance), effectText));
|
||||
this.getSpellAbility().setAbilityWord(AbilityWord.METALCRAFT);
|
||||
this.getSpellAbility().addHint(MetalcraftHint.instance);
|
||||
}
|
||||
|
||||
public MirranMettle(final MirranMettle card) {
|
||||
|
|
|
@ -3,12 +3,10 @@ package mage.cards.m;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
|
@ -31,6 +29,8 @@ public final class MoltenPsyche extends CardImpl {
|
|||
// <i>Metalcraft</i> — If you control three or more artifacts, Molten Psyche deals damage to each opponent equal to the number of cards that player has drawn this turn.
|
||||
this.getSpellAbility().addEffect(new MoltenPsycheEffect());
|
||||
this.getSpellAbility().addWatcher(new MoltenPsycheWatcher());
|
||||
this.getSpellAbility().setAbilityWord(AbilityWord.METALCRAFT);
|
||||
this.getSpellAbility().addHint(MetalcraftHint.instance);
|
||||
}
|
||||
|
||||
public MoltenPsyche(final MoltenPsyche card) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.m;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -7,8 +6,9 @@ import mage.Mana;
|
|||
import mage.abilities.common.EntersBattlefieldAbility;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.common.RemoveCountersSourceCost;
|
||||
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
|
||||
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
|
||||
import mage.abilities.mana.ActivatedManaAbilityImpl;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -48,12 +48,13 @@ public final class Morselhoarder extends CardImpl {
|
|||
}
|
||||
|
||||
class MorselhoarderAbility extends ActivatedManaAbilityImpl {
|
||||
|
||||
public MorselhoarderAbility() {
|
||||
this(new RemoveCountersSourceCost(CounterType.M1M1.createInstance()));
|
||||
}
|
||||
|
||||
public MorselhoarderAbility(Cost cost) {
|
||||
super(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(), cost);
|
||||
super(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(1, new CountersSourceCount(CounterType.M1M1), false), cost);
|
||||
this.netMana.add(new Mana(0, 0, 0, 0, 0, 0, 1, 0));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
|
||||
package mage.cards.m;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.mana.ActivateIfConditionManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -14,8 +13,9 @@ import mage.constants.CardType;
|
|||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com, Loki
|
||||
*/
|
||||
public final class MoxOpal extends CardImpl {
|
||||
|
@ -30,6 +30,7 @@ public final class MoxOpal extends CardImpl {
|
|||
new TapSourceCost(),
|
||||
MetalcraftCondition.instance);
|
||||
ability.setAbilityWord(AbilityWord.METALCRAFT);
|
||||
ability.addHint(MetalcraftHint.instance);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package mage.cards.m;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.ConditionalMana;
|
||||
import mage.MageObject;
|
||||
import mage.Mana;
|
||||
|
@ -20,8 +21,6 @@ import mage.filter.FilterCard;
|
|||
import mage.game.Game;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
*/
|
||||
|
@ -36,10 +35,10 @@ public final class MyrReservoir extends CardImpl {
|
|||
public MyrReservoir(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
|
||||
|
||||
// {tap}: Add {C}{C}. Spend this mana only to cast Myr spells or activate abilities of Myr.
|
||||
// {T}: Add {C}{C}. Spend this mana only to cast Myr spells or activate abilities of Myr.
|
||||
this.addAbility(new MyrReservoirManaAbility());
|
||||
|
||||
// {3}, {tap}: Return target Myr card from your graveyard to your hand.
|
||||
// {3}, {T}: Return target Myr card from your graveyard to your hand.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new GenericManaCost(3));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addTarget(new TargetCardInYourGraveyard(myrCardFilter));
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.n;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.dynamicvalue.common.EffectKeyValue;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
|
@ -15,8 +13,9 @@ import mage.game.events.GameEvent;
|
|||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.NestOfScarabsBlackInsectToken;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author stravant
|
||||
*/
|
||||
public final class NestOfScarabs extends CardImpl {
|
||||
|
@ -63,7 +62,7 @@ class NestOfScarabsTriggeredAbility extends TriggeredAbilityImpl {
|
|||
if (permanent == null) {
|
||||
permanent = game.getPermanentEntering(event.getTargetId());
|
||||
}
|
||||
if (permanent.isCreature()) {
|
||||
if (permanent != null && permanent.isCreature()) {
|
||||
getEffects().forEach(effect -> effect.setValue("countersAdded", event.getAmount()));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package mage.cards.n;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
|
@ -17,11 +21,6 @@ import mage.constants.Zone;
|
|||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
@ -69,14 +68,6 @@ class NykthosShrineToNyxManaAbility extends ActivatedManaAbilityImpl {
|
|||
return new NykthosShrineToNyxManaAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Mana> getNetMana(Game game) {
|
||||
List<Mana> netMana = new ArrayList<>();
|
||||
if (game != null) {
|
||||
netMana.addAll(((ManaEffect) this.getEffects().get(0)).getNetMana(game, this));
|
||||
}
|
||||
return netMana;
|
||||
}
|
||||
}
|
||||
|
||||
class NykthosDynamicManaEffect extends ManaEffect {
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package mage.cards.n;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTappedAbility;
|
||||
|
@ -16,11 +20,6 @@ import mage.constants.Zone;
|
|||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
|
@ -68,14 +67,6 @@ class NyxLotusManaAbility extends ActivatedManaAbilityImpl {
|
|||
return new NyxLotusManaAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Mana> getNetMana(Game game) {
|
||||
List<Mana> netMana = new ArrayList<>();
|
||||
if (game != null) {
|
||||
netMana.addAll(((ManaEffect) this.getEffects().get(0)).getNetMana(game, this));
|
||||
}
|
||||
return netMana;
|
||||
}
|
||||
}
|
||||
|
||||
class NyxLotusDynamicManaEffect extends ManaEffect {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.o;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
|
@ -14,10 +12,11 @@ import mage.constants.CardType;
|
|||
import mage.constants.Duration;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreatureCard;
|
||||
import mage.filter.predicate.other.FaceDownPredicate;
|
||||
import mage.filter.predicate.other.FaceDownCastablePredicate;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class ObscuringAether extends CardImpl {
|
||||
|
@ -25,7 +24,7 @@ public final class ObscuringAether extends CardImpl {
|
|||
private static final FilterCreatureCard filter = new FilterCreatureCard("Face-down creature spells");
|
||||
|
||||
static {
|
||||
filter.add(FaceDownPredicate.instance);
|
||||
filter.add(FaceDownCastablePredicate.instance);
|
||||
}
|
||||
|
||||
public ObscuringAether(UUID ownerId, CardSetInfo setInfo) {
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
|
||||
|
||||
package mage.cards.p;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
|
@ -11,6 +8,7 @@ import mage.abilities.costs.mana.GenericManaCost;
|
|||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.keyword.EquipAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -18,6 +16,8 @@ import mage.constants.*;
|
|||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author Loki
|
||||
*/
|
||||
|
@ -38,11 +38,15 @@ public final class PuresteelPaladin extends CardImpl {
|
|||
|
||||
// Whenever an Equipment enters the battlefield under your control, you may draw a card.
|
||||
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), filter, true));
|
||||
|
||||
// <i>Metalcraft</i> — Equipment you control have equip {0} as long as you control three or more artifacts
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(
|
||||
new GainAbilityControlledEffect(new EquipAbility(Outcome.AddAbility, new GenericManaCost(0)), Duration.WhileOnBattlefield, filter),
|
||||
MetalcraftCondition.instance,
|
||||
"<i>Metalcraft</i> — Equipment you control have equip {0} as long as you control three or more artifacts")));
|
||||
"<i>Metalcraft</i> — Equipment you control have equip {0} as long as you control three or more artifacts"))
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance)
|
||||
);
|
||||
}
|
||||
|
||||
public PuresteelPaladin(final PuresteelPaladin card) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.p;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -69,11 +68,10 @@ class PyromancersGauntletReplacementEffect extends ReplacementEffectImpl {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
Permanent permanent = game.getBattlefield().getPermanent(event.getSourceId());
|
||||
if(permanent != null && permanent.isPlaneswalker()){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
|
||||
return permanent != null
|
||||
&& permanent.isPlaneswalker()
|
||||
&& source.isControlledBy(permanent.getControllerId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -15,10 +15,10 @@ import mage.constants.*;
|
|||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.cards.Card;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
|
@ -115,9 +115,12 @@ class RakdosLordOfRiotsCostReductionEffect extends CostModificationEffectImpl {
|
|||
public boolean applies(Ability abilityToModify, Ability source, Game game) {
|
||||
if (abilityToModify instanceof SpellAbility) {
|
||||
if (abilityToModify.isControlledBy(source.getControllerId())) {
|
||||
Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId());
|
||||
if (spell != null) {
|
||||
return spell.isCreature();
|
||||
Card spellCard = ((SpellAbility) abilityToModify).getCharacteristics(game);
|
||||
if (spellCard != null) {
|
||||
if (((SpellAbility) abilityToModify).getSpellAbilityCastMode() != SpellAbilityCastMode.NORMAL) {
|
||||
spellCard = ((SpellAbility) abilityToModify).getSpellAbilityCastMode().getTypeModifiedCardObjectCopy(spellCard, game);
|
||||
}
|
||||
return spellCard.isCreature();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,19 @@
|
|||
|
||||
|
||||
package mage.cards.r;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
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.constants.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Loki
|
||||
*/
|
||||
public final class RazorfieldRhino extends CardImpl {
|
||||
|
@ -27,8 +23,12 @@ public final class RazorfieldRhino extends CardImpl {
|
|||
this.subtype.add(SubType.RHINO);
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(4);
|
||||
|
||||
// Metalcraft — Razorfield Rhino gets +2/+2 as long as you control three or more artifacts.
|
||||
ContinuousEffect effect1 = new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield);
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(effect1, MetalcraftCondition.instance, "<i>Metalcraft</i> — Razorfield Rhino gets +2/+2 as long as you control three or more artifacts")));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(effect1, MetalcraftCondition.instance, "<i>Metalcraft</i> — Razorfield Rhino gets +2/+2 as long as you control three or more artifacts"))
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance));
|
||||
}
|
||||
|
||||
public RazorfieldRhino(final RazorfieldRhino card) {
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
|
||||
|
||||
package mage.cards.r;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
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.constants.*;
|
||||
import mage.game.permanent.token.TokenImpl;
|
||||
import mage.game.permanent.token.Token;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Loki
|
||||
*/
|
||||
public final class RustedRelic extends CardImpl {
|
||||
|
||||
public RustedRelic(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
|
||||
|
||||
// Metalcraft — Rusted Relic is a 5/5 Golem artifact creature as long as you control three or more artifacts.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
|
||||
new ConditionalContinuousEffect(
|
||||
new BecomesCreatureSourceEffect(new RustedRelicToken(), "artifact", Duration.WhileOnBattlefield),
|
||||
MetalcraftCondition.instance,
|
||||
"<i>Metalcraft</i> — {this} is a 5/5 Golem artifact creature as long as you control three or more artifacts")));
|
||||
"<i>Metalcraft</i> — {this} is a 5/5 Golem artifact creature as long as you control three or more artifacts"))
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance)
|
||||
);
|
||||
}
|
||||
|
||||
public RustedRelic(final RustedRelic card) {
|
||||
|
@ -51,6 +51,7 @@ class RustedRelicToken extends TokenImpl {
|
|||
power = new MageInt(5);
|
||||
toughness = new MageInt(5);
|
||||
}
|
||||
|
||||
public RustedRelicToken(final RustedRelicToken token) {
|
||||
super(token);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -19,18 +19,11 @@ import mage.game.Game;
|
|||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.stack.StackObject;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.target.targetadjustment.TargetAdjuster;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
@ -80,16 +73,15 @@ class SatyrFiredancerTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
boolean controlledBy = isControlledBy(game.getControllerId(event.getSourceId()));
|
||||
if (!controlledBy) {
|
||||
if (!isControlledBy(game.getControllerId(event.getSourceId()))) {
|
||||
return false;
|
||||
}
|
||||
MageObject damageSource = game.getObject(event.getSourceId());
|
||||
if (damageSource == null) {
|
||||
return false;
|
||||
}
|
||||
UUID damageTarget = event.getTargetId();
|
||||
if (!game.getOpponents(getControllerId()).contains(damageTarget)) {
|
||||
UUID damageTargetId = event.getTargetId();
|
||||
if (!game.getOpponents(getControllerId()).contains(damageTargetId)) {
|
||||
return false;
|
||||
}
|
||||
MageObject sourceObject = game.getObject(event.getSourceId());
|
||||
|
@ -97,7 +89,7 @@ class SatyrFiredancerTriggeredAbility extends TriggeredAbilityImpl {
|
|||
return false;
|
||||
}
|
||||
for (Effect effect : this.getEffects()) {
|
||||
effect.setTargetPointer(new FixedTarget(damageTarget)); // used by adjust targets
|
||||
effect.setTargetPointer(new FixedTarget(damageTargetId)); // used by adjust targets
|
||||
effect.setValue("damage", event.getAmount());
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import mage.MageInt;
|
||||
|
@ -7,9 +6,11 @@ import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
|
|||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
|
||||
|
@ -23,10 +24,10 @@ public final class ScreechingSilcaw extends CardImpl {
|
|||
public ScreechingSilcaw(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
|
||||
this.subtype.add(SubType.BIRD);
|
||||
|
||||
this.power = new MageInt(1);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
//"<i>Metalcraft</i> — Whenever Screeching Silcaw deals combat damage to a player, if you control three or more artifacts, that player puts the top four cards of their library into their graveyard.
|
||||
|
@ -36,6 +37,8 @@ public final class ScreechingSilcaw extends CardImpl {
|
|||
), MetalcraftCondition.instance, "<i>Metalcraft</i> — Whenever {this} " +
|
||||
"deals combat damage to a player, if you control three or more artifacts, that player mills four cards."
|
||||
);
|
||||
conditional.setAbilityWord(AbilityWord.METALCRAFT);
|
||||
conditional.addHint(MetalcraftHint.instance);
|
||||
this.addAbility(conditional);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
|
@ -18,9 +20,6 @@ import mage.players.Player;
|
|||
import mage.target.TargetCard;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
*/
|
||||
|
@ -107,15 +106,19 @@ class SemblanceAnvilCostReductionEffect extends CostModificationEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(Ability abilityToModify, Ability source, Game game) {
|
||||
if (abilityToModify instanceof SpellAbility) {
|
||||
Card sourceCard = game.getCard(abilityToModify.getSourceId());
|
||||
if (sourceCard != null && sourceCard.isOwnedBy(source.getControllerId())) {
|
||||
if (abilityToModify instanceof SpellAbility
|
||||
&& abilityToModify.isControlledBy(source.getControllerId())) {
|
||||
Card spellCard = ((SpellAbility) abilityToModify).getCharacteristics(game);
|
||||
if (spellCard != null) {
|
||||
if (((SpellAbility) abilityToModify).getSpellAbilityCastMode() != SpellAbilityCastMode.NORMAL) {
|
||||
spellCard = ((SpellAbility) abilityToModify).getSpellAbilityCastMode().getTypeModifiedCardObjectCopy(spellCard, game);
|
||||
}
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null) {
|
||||
List<UUID> imprinted = permanent.getImprinted();
|
||||
if (imprinted != null && !imprinted.isEmpty()) {
|
||||
Card imprintedCard = game.getCard(imprinted.get(0));
|
||||
return imprintedCard != null && imprintedCard.shareTypes(sourceCard);
|
||||
return imprintedCard != null && imprintedCard.shareTypes(spellCard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,20 @@
|
|||
|
||||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Loki, nantuko
|
||||
*/
|
||||
public final class SnapsailGlider extends CardImpl {
|
||||
|
@ -30,8 +26,12 @@ public final class SnapsailGlider extends CardImpl {
|
|||
this.subtype.add(SubType.CONSTRUCT);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
// Metalcraft — Snapsail Glider has flying as long as you control three or more artifacts.
|
||||
ContinuousEffect effect = new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield);
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(effect, MetalcraftCondition.instance, rule)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(effect, MetalcraftCondition.instance, rule))
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance));
|
||||
}
|
||||
|
||||
public SnapsailGlider(final SnapsailGlider card) {
|
||||
|
|
|
@ -1,23 +1,20 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalContinuousEffect;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.keyword.DoubleStrikeAbility;
|
||||
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.constants.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author North
|
||||
*/
|
||||
public final class SpiralingDuelist extends CardImpl {
|
||||
|
@ -28,12 +25,14 @@ public final class SpiralingDuelist extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.BERSERKER);
|
||||
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
// Metalcraft — Spiraling Duelist has double strike as long as you control three or more artifacts.
|
||||
ContinuousEffect effect = new GainAbilitySourceEffect(DoubleStrikeAbility.getInstance(), Duration.WhileOnBattlefield);
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(effect, MetalcraftCondition.instance, effectText)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(effect, MetalcraftCondition.instance, effectText))
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance));
|
||||
}
|
||||
|
||||
public SpiralingDuelist(final SpiralingDuelist card) {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
|
@ -11,16 +9,15 @@ import mage.abilities.decorator.ConditionalContinuousEffect;
|
|||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.combat.CanAttackAsThoughItDidntHaveDefenderSourceEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.abilities.keyword.DefenderAbility;
|
||||
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.constants.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public final class SpireSerpent extends CardImpl {
|
||||
|
@ -34,13 +31,18 @@ public final class SpireSerpent extends CardImpl {
|
|||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(5);
|
||||
|
||||
// Defender
|
||||
this.addAbility(DefenderAbility.getInstance());
|
||||
|
||||
// Metalcraft — As long as you control three or more artifacts, Spire Serpent gets +2/+2 and can attack as though it didn’t have defender.
|
||||
ConditionalContinuousEffect effect1 = new ConditionalContinuousEffect(new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield), MetalcraftCondition.instance, abilityText1);
|
||||
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect1);
|
||||
Effect effect = new ConditionalAsThoughEffect(new CanAttackAsThoughItDidntHaveDefenderSourceEffect(Duration.WhileOnBattlefield),
|
||||
MetalcraftCondition.instance);
|
||||
effect.setText("and can attack as though it didn't have defender");
|
||||
ability.addEffect(effect);
|
||||
ability.setAbilityWord(AbilityWord.METALCRAFT);
|
||||
ability.addHint(MetalcraftHint.instance);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.effects.common.CounterTargetEffect;
|
||||
import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
|
@ -13,6 +13,8 @@ import mage.constants.CardType;
|
|||
import mage.constants.Zone;
|
||||
import mage.target.TargetSpell;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author ayrat
|
||||
*/
|
||||
|
@ -25,6 +27,7 @@ public final class StoicRebuttal extends CardImpl {
|
|||
Ability ability = new SimpleStaticAbility(Zone.ALL, new SpellCostReductionSourceEffect(1, MetalcraftCondition.instance));
|
||||
ability.setRuleAtTheTop(true);
|
||||
ability.setAbilityWord(AbilityWord.METALCRAFT);
|
||||
ability.addHint(MetalcraftHint.instance);
|
||||
this.addAbility(ability);
|
||||
|
||||
// Counter target spell.
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.LoyaltyAbility;
|
||||
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
|
@ -8,16 +7,19 @@ import mage.abilities.decorator.ConditionalOneShotEffect;
|
|||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.GetEmblemEffect;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.game.command.emblems.TezzeretArtificeMasterEmblem;
|
||||
import mage.game.permanent.token.ThopterColorlessToken;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class TezzeretArtificeMaster extends CardImpl {
|
||||
|
@ -39,7 +41,9 @@ public final class TezzeretArtificeMaster extends CardImpl {
|
|||
MetalcraftCondition.instance,
|
||||
"Draw a card. If you control three or "
|
||||
+ "more artifacts, draw two cards instead"
|
||||
), 0));
|
||||
), 0)
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance));
|
||||
|
||||
// −9: You get an emblem with "At the beginning of your end step, search your library for a permanent card, put it into the battlefield, then shuffle your library."
|
||||
this.addAbility(new LoyaltyAbility(
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -14,8 +15,6 @@ import mage.game.permanent.Permanent;
|
|||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
|
|
|
@ -21,7 +21,7 @@ import mage.target.common.TargetCardInLibrary;
|
|||
*/
|
||||
public final class TrinketMage extends CardImpl {
|
||||
|
||||
private static final FilterCard filter = new FilterCard("an artifact card with converted mana cost 1 or less");
|
||||
private static final FilterCard filter = new FilterCard("artifact card with converted mana cost 1 or less");
|
||||
|
||||
static {
|
||||
filter.add(CardType.ARTIFACT.getPredicate());
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
|
||||
|
||||
package mage.cards.v;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.ActivateIfConditionActivatedAbility;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.effects.common.TapTargetEffect;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
|
@ -19,9 +17,10 @@ import mage.filter.FilterPermanent;
|
|||
import mage.filter.predicate.Predicates;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Loki
|
||||
*/
|
||||
public final class VedalkenCertarch extends CardImpl {
|
||||
|
@ -38,14 +37,14 @@ public final class VedalkenCertarch extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}");
|
||||
this.subtype.add(SubType.VEDALKEN);
|
||||
this.subtype.add(SubType.WIZARD);
|
||||
|
||||
this.power = new MageInt(1);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
// <i>Metalcraft</i> — {T}: Tap target artifact, creature, or land. Activate this ability only if you control three or more artifacts.
|
||||
Ability ability = new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new TapSourceCost(), MetalcraftCondition.instance);
|
||||
ability.setAbilityWord(AbilityWord.METALCRAFT);
|
||||
ability.addTarget(new TargetPermanent(filter));
|
||||
ability.setAbilityWord(AbilityWord.METALCRAFT);
|
||||
ability.addHint(MetalcraftHint.instance);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package mage.cards.v;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.AttacksTriggeredAbility;
|
||||
|
@ -8,15 +7,18 @@ import mage.abilities.condition.common.MetalcraftCondition;
|
|||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.effects.common.continuous.LoseAllAbilitiesAllEffect;
|
||||
import mage.abilities.effects.common.continuous.SetPowerToughnessAllEffect;
|
||||
import mage.constants.SubType;
|
||||
import mage.abilities.hint.common.MetalcraftHint;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AbilityWord;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.StaticFilters;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class VedalkenHumiliator extends CardImpl {
|
||||
|
@ -46,8 +48,10 @@ public final class VedalkenHumiliator extends CardImpl {
|
|||
"<i>Metalcraft</i> — Whenever {this} attacks, "
|
||||
+ "if you control three or more artifacts, "
|
||||
+ "creatures your opponents control lose all abilities "
|
||||
+ "and have base power and toughness 1/1 until end of turn."
|
||||
));
|
||||
+ "and have base power and toughness 1/1 until end of turn.")
|
||||
.setAbilityWord(AbilityWord.METALCRAFT)
|
||||
.addHint(MetalcraftHint.instance)
|
||||
);
|
||||
}
|
||||
|
||||
public VedalkenHumiliator(final VedalkenHumiliator card) {
|
||||
|
|
117
Mage.Tests/src/test/java/PyromancersGauntletTest.java
Normal file
117
Mage.Tests/src/test/java/PyromancersGauntletTest.java
Normal file
|
@ -0,0 +1,117 @@
|
|||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.GameException;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class PyromancersGauntletTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void basicTest() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
|
||||
// If a red instant or sorcery spell you control or a red planeswalker you control
|
||||
// would deal damage to a permanent or player, it deals that much damage plus 2 to that permanent or player instead.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Pyromancer's Gauntlet"); // Artifact {5}
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Pillarfield Ox");
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 15); // Bolt 3 + 2
|
||||
|
||||
assertGraveyardCount(playerA, "Lightning Bolt", 2);
|
||||
assertGraveyardCount(playerB, "Pillarfield Ox", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void opponentsPyromancersGauntletAppliedToOwnPlaneswalkerTest() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
// +1: Elementals you control get +2/+0 until end of turn.
|
||||
// −1: Add {R}{R}.
|
||||
// −2: Chandra, Novice Pyromancer deals 2 damage to any target.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Chandra, Novice Pyromancer"); // Planeswalker (5) {3}{R}
|
||||
|
||||
// If a red instant or sorcery spell you control or a red planeswalker you control
|
||||
// would deal damage to a permanent or player, it deals that much damage plus 2 to that permanent or player instead.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Pyromancer's Gauntlet"); // Creature 2/4 {1}{R}{R}{R}
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Chandra, Novice Pyromancer"); // Planeswalker (5) {3}{R}
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Barbarian Horde"); // Creature 3/3 {3}{R}
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-2:", playerB);
|
||||
|
||||
attack(2, playerB, "Barbarian Horde");
|
||||
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "-2:", playerA);
|
||||
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "-2:", "Barbarian Horde");
|
||||
|
||||
setStopAt(3, PhaseStep.BEGIN_COMBAT);
|
||||
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertLife(playerA, 13); // Attack from Horde 3 + Dmage 2+2 from planeswalker
|
||||
assertLife(playerB, 18); // Damage from planeswalker 2
|
||||
|
||||
assertPermanentCount(playerB, "Barbarian Horde", 1);
|
||||
|
||||
assertCounterCount(playerA, "Chandra, Novice Pyromancer", CounterType.LOYALTY, 1);
|
||||
assertCounterCount(playerB, "Chandra, Novice Pyromancer", CounterType.LOYALTY, 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void with3PlayersTest() throws GameException {
|
||||
playerC = createPlayer(currentGame, playerC, "PlayerC");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
// +1: Elementals you control get +2/+0 until end of turn.
|
||||
// −1: Add {R}{R}.
|
||||
// −2: Chandra, Novice Pyromancer deals 2 damage to any target.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Chandra, Novice Pyromancer"); // Planeswalker (5) {3}{R}
|
||||
|
||||
// If a red instant or sorcery spell you control or a red planeswalker you control
|
||||
// would deal damage to a permanent or player, it deals that much damage plus 2 to that permanent or player instead.
|
||||
addCard(Zone.BATTLEFIELD, playerC, "Pyromancer's Gauntlet"); // Creature 2/4 {1}{R}{R}{R}
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Chandra, Novice Pyromancer"); // Planeswalker (5) {3}{R}
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Barbarian Horde"); // Creature 3/3 {3}{R}
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-2:", playerB);
|
||||
|
||||
attack(3, playerB, "Barbarian Horde");
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerB, "-2:", playerA);
|
||||
|
||||
activateAbility(4, PhaseStep.PRECOMBAT_MAIN, playerA, "-2:", "Barbarian Horde");
|
||||
|
||||
setStopAt(4, PhaseStep.BEGIN_COMBAT);
|
||||
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertLife(playerA, 15); // Attack from Horde 3 + Dmage 2 from planeswalker
|
||||
assertLife(playerB, 18); // Damage from planeswalker 2
|
||||
assertLife(playerC, 20);
|
||||
assertPermanentCount(playerB, "Barbarian Horde", 1);
|
||||
|
||||
assertCounterCount(playerA, "Chandra, Novice Pyromancer", CounterType.LOYALTY, 1);
|
||||
assertCounterCount(playerB, "Chandra, Novice Pyromancer", CounterType.LOYALTY, 3);
|
||||
}
|
||||
}
|
|
@ -191,7 +191,6 @@ public class BestowTest extends CardTestPlayerBase {
|
|||
addTarget(playerB, playerA); // Away
|
||||
addTarget(playerA, "Nyxborn Rollicker");
|
||||
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
@ -463,4 +462,26 @@ public class BestowTest extends CardTestPlayerBase {
|
|||
Assert.assertFalse("The unattached Nighthowler may not have the aura subtype.", nighthowler.getSubtype(currentGame).contains(SubType.AURA));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCastBestowWithCostReduction() {
|
||||
// Enchantment Creature — Horror
|
||||
// Bestow {5}{G} (If you cast this card for its bestow cost, it's an Aura spell with enchant creature. It becomes a creature again if it's not attached to a creature.)
|
||||
// Trample
|
||||
// Enchanted creature gets +3/+3 and has trample.
|
||||
addCard(Zone.HAND, playerA, "Nylea's Emissary"); // Enchantment Creature
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); // {1}{W} 2/2 creature
|
||||
// Aura spells you cast cost {1} less to cast.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Transcendent Envoy", 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Nylea's Emissary using bestow", "Silvercoat Lion");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Nylea's Emissary", 1);
|
||||
assertPowerToughness(playerA, "Silvercoat Lion", 5, 5);
|
||||
assertType("Nylea's Emissary", CardType.CREATURE, false);
|
||||
assertType("Nylea's Emissary", CardType.ENCHANTMENT, SubType.AURA);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1089,7 +1089,7 @@ public class MorphTest extends CardTestPlayerBase {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void test_MorphWithCostReductionMustBePlayable_MorphCondition() {
|
||||
public void test_MorphWithCostReductionMustBePlayable_MorphCondition1() {
|
||||
// {1}{U} creature
|
||||
// Morph {1}{U} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its morph cost.)
|
||||
// When Willbender is turned face up, change the target of target spell or ability with a single target.
|
||||
|
@ -1110,4 +1110,36 @@ public class MorphTest extends CardTestPlayerBase {
|
|||
|
||||
assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_MorphWithCostReductionMustBePlayable_MorphCondition2() {
|
||||
// {1}{U} creature
|
||||
// Morph {1}{U} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its morph cost.)
|
||||
// When Willbender is turned face up, change the target of target spell or ability with a single target.
|
||||
addCard(Zone.HAND, playerA, "Willbender", 2);
|
||||
//addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||
//
|
||||
// The first face-down creature spell you cast each turn costs {3} less to cast.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Kadena, Slinking Sorcerer");
|
||||
|
||||
// creature one - get cost reduce
|
||||
checkPlayableAbility("can", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Willbender", true);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Willbender");
|
||||
setChoice(playerA, "Yes"); // morph
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// creature two - do not get cost reduce
|
||||
checkPlayableAbility("can't by no reduce", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Willbender", false);
|
||||
|
||||
// on next turn it can cost reduce again
|
||||
checkPlayableAbility("can't by not your turn", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Willbender", false);
|
||||
checkPlayableAbility("can", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Willbender", true);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(3, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package org.mage.test.cards.abilities.oneshot.damage;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
|
@ -11,7 +10,6 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
|
|||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class SatyrFiredancerTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
|
@ -57,7 +55,6 @@ public class SatyrFiredancerTest extends CardTestPlayerBase {
|
|||
assertPermanentCount(playerB, "Silvercoat Lion", 1);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDamageFromOtherCreature() {
|
||||
// Whenever an instant or sorcery spell you control deals damage to an opponent, Satyr Firedancer deals that much damage to target creature that player controls.
|
||||
|
@ -82,6 +79,7 @@ public class SatyrFiredancerTest extends CardTestPlayerBase {
|
|||
playerC = createPlayer(currentGame, playerC, "PlayerC");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Satyr Firedancer", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
// Price of Progress deals damage to each player equal to twice the number of nonbasic lands that player controls.
|
||||
addCard(Zone.HAND, playerA, "Price of Progress", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Taiga", 1);
|
||||
|
|
|
@ -84,7 +84,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}, Sacrifice a permanent you control: Return target creature to its owner's hand.");
|
||||
addTarget(playerB, "Angel of Jubilation"); // return to hand
|
||||
setChoice(playerB, "Food Chain"); // cacrifice cost
|
||||
setChoice(playerB, "Food Chain"); // sacrifice cost
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
|
|
|
@ -240,4 +240,60 @@ public class TappedForManaRelatedTest extends CardTestPlayerBase {
|
|||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||
assertManaOptions("{Any}", manaOptions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestEyeOfRamos() {
|
||||
setStrictChooseMode(true);
|
||||
// {T}: Add {U}.
|
||||
// Sacrifice Eye of Ramos: Add {U}.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Eye of Ramos", 2);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertAllCommandsUsed();
|
||||
|
||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||
assertManaOptions("{U}{U}{U}{U}", manaOptions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestFarrelitePriest() {
|
||||
setStrictChooseMode(true);
|
||||
// {1}: Add {W}. If this ability has been activated four or more times this turn, sacrifice Farrelite Priest at the beginning of the next end step.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Farrelite Priest", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertAllCommandsUsed();
|
||||
|
||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||
Assert.assertEquals("mana variations don't fit", 5, manaOptions.size());
|
||||
assertManaOptions("{W}{W}{W}{W}", manaOptions);
|
||||
assertManaOptions("{W}{W}{W}{B}", manaOptions);
|
||||
assertManaOptions("{W}{W}{B}{B}", manaOptions);
|
||||
assertManaOptions("{W}{B}{B}{B}", manaOptions);
|
||||
assertManaOptions("{B}{B}{B}{B}", manaOptions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestMorselhoarder() {
|
||||
setStrictChooseMode(true);
|
||||
// Morselhoarder enters the battlefield with two -1/-1 counters on it.
|
||||
// Remove a -1/-1 counter from Morselhoarder: Add one mana of any color.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Morselhoarder", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertAllCommandsUsed();
|
||||
|
||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||
assertManaOptions("{B}{B}{Any}{Any}{Any}{Any}", manaOptions);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
package org.mage.test.cards.single.eld;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.GameException;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class TorbranThaneOfRedFellTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void basicTest() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
// If a red source you control would deal damage to an opponent or a permanent an opponent controls,
|
||||
// it deals that much damage plus 2 instead.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Torbran, Thane of Red Fell"); // Creature 2/4 {1}{R}{R}{R}
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox");
|
||||
|
||||
attack(1, playerA, "Torbran, Thane of Red Fell");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Pillarfield Ox");
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 11); // damage from: attack 2 + 2 Bolt 3 + 2
|
||||
|
||||
assertGraveyardCount(playerA, "Lightning Bolt", 2);
|
||||
assertGraveyardCount(playerB, "Pillarfield Ox", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void opponentsTornbanAppliedToOwnPlaneswalkerTest() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
// +1: Elementals you control get +2/+0 until end of turn.
|
||||
// −1: Add {R}{R}.
|
||||
// −2: Chandra, Novice Pyromancer deals 2 damage to any target.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Chandra, Novice Pyromancer"); // Planeswalker (5) {3}{R}
|
||||
|
||||
// If a red source you control would deal damage to an opponent or a permanent an opponent controls,
|
||||
// it deals that much damage plus 2 instead.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Torbran, Thane of Red Fell"); // Creature 2/4 {1}{R}{R}{R}
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Barbarian Horde"); // Creature 3/3 {3}{R}
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-2:", playerB);
|
||||
|
||||
attack(2, playerB, "Barbarian Horde");
|
||||
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "-2:", "Barbarian Horde");
|
||||
|
||||
setStopAt(3, PhaseStep.BEGIN_COMBAT);
|
||||
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertLife(playerA, 15); // Attack from Horde 3+2
|
||||
assertLife(playerB, 18); // Damage from planeswalker 2
|
||||
|
||||
assertPermanentCount(playerB, "Barbarian Horde", 1);
|
||||
|
||||
assertCounterCount("Chandra, Novice Pyromancer", CounterType.LOYALTY, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void with3PlayersTest() throws GameException {
|
||||
playerC = createPlayer(currentGame, playerC, "PlayerC");
|
||||
setStrictChooseMode(true);
|
||||
|
||||
// +1: Elementals you control get +2/+0 until end of turn.
|
||||
// −1: Add {R}{R}.
|
||||
// −2: Chandra, Novice Pyromancer deals 2 damage to any target.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Chandra, Novice Pyromancer"); // Planeswalker (5) {3}{R}
|
||||
|
||||
// If a red source you control would deal damage to an opponent or a permanent an opponent controls,
|
||||
// it deals that much damage plus 2 instead.
|
||||
addCard(Zone.BATTLEFIELD, playerC, "Torbran, Thane of Red Fell"); // Creature 2/4 {1}{R}{R}{R}
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Barbarian Horde"); // Creature 3/3 {3}{R}
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Chandra, Novice Pyromancer"); // Planeswalker (5) {3}{R}
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-2:", playerB);
|
||||
|
||||
attack(3, playerB, "Barbarian Horde", playerA);
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerB, "-2:", playerA);
|
||||
|
||||
activateAbility(4, PhaseStep.PRECOMBAT_MAIN, playerA, "-2:", "Barbarian Horde");
|
||||
|
||||
setStopAt(4, PhaseStep.BEGIN_COMBAT);
|
||||
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertLife(playerA, 15); // Attack from Horde 3+2
|
||||
assertLife(playerB, 18); // Damage from planeswalker 2
|
||||
|
||||
assertPermanentCount(playerB, "Barbarian Horde", 1);
|
||||
|
||||
assertCounterCount(playerA, "Chandra, Novice Pyromancer", CounterType.LOYALTY, 1);
|
||||
assertCounterCount(playerB, "Chandra, Novice Pyromancer", CounterType.LOYALTY, 3);
|
||||
}
|
||||
}
|
|
@ -453,7 +453,7 @@ public interface Ability extends Controllable, Serializable {
|
|||
*
|
||||
* @param abilityWord
|
||||
*/
|
||||
void setAbilityWord(AbilityWord abilityWord);
|
||||
Ability setAbilityWord(AbilityWord abilityWord);
|
||||
|
||||
/**
|
||||
* Creates the message about the ability casting/triggering/activating to
|
||||
|
|
|
@ -8,6 +8,7 @@ import mage.abilities.effects.ContinuousEffect;
|
|||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.Effects;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.abilities.hint.Hint;
|
||||
import mage.abilities.mana.ActivatedManaAbilityImpl;
|
||||
import mage.cards.Card;
|
||||
|
@ -34,7 +35,6 @@ import java.util.ArrayList;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
|
@ -54,7 +54,7 @@ public abstract class AbilityImpl implements Ability {
|
|||
protected ManaCosts<ManaCost> manaCostsToPay;
|
||||
protected Costs<Cost> costs;
|
||||
protected Costs<Cost> optionalCosts;
|
||||
protected Modes modes; // access to it by GetModes only (it's can be override by some abilities)
|
||||
protected Modes modes; // access to it by GetModes only (it can be overridden by some abilities)
|
||||
protected Zone zone;
|
||||
protected String name;
|
||||
protected AbilityWord abilityWord;
|
||||
|
@ -65,7 +65,7 @@ public abstract class AbilityImpl implements Ability {
|
|||
protected boolean activated = false;
|
||||
protected boolean worksFaceDown = false;
|
||||
protected int sourceObjectZoneChangeCounter;
|
||||
protected List<Watcher> watchers = new ArrayList<>(); // access to it by GetWatchers only (it's can be override by some abilities)
|
||||
protected List<Watcher> watchers = new ArrayList<>(); // access to it by GetWatchers only (it can be overridden by some abilities)
|
||||
protected List<Ability> subAbilities = null;
|
||||
protected boolean canFizzle = true;
|
||||
protected TargetAdjuster targetAdjuster = null;
|
||||
|
@ -1022,8 +1022,9 @@ public abstract class AbilityImpl implements Ability {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setAbilityWord(AbilityWord abilityWord) {
|
||||
public Ability setAbilityWord(AbilityWord abilityWord) {
|
||||
this.abilityWord = abilityWord;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1243,10 +1244,13 @@ public abstract class AbilityImpl implements Ability {
|
|||
}
|
||||
|
||||
/**
|
||||
* Dynamic cost modification for ability.
|
||||
* Example: if it need stack related info (like real targets) then must check two states (game.inCheckPlayableState):
|
||||
* 1. In playable state it must check all possible use cases (e.g. allow to reduce on any available target and modes)
|
||||
* 2. In real cast state it must check current use case (e.g. real selected targets and modes)
|
||||
* Dynamic cost modification for ability.<br>
|
||||
* Example: if it need stack related info (like real targets) then must
|
||||
* check two states (game.inCheckPlayableState): <br>
|
||||
* 1. In playable state it must check all possible use cases (e.g. allow to
|
||||
* reduce on any available target and modes) <br>
|
||||
* 2. In real cast state it must check current use case (e.g. real selected
|
||||
* targets and modes)
|
||||
*
|
||||
* @param costAdjuster
|
||||
*/
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
|
||||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.constants.Outcome;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
|
@ -59,12 +56,13 @@ public class GainLifeTargetEffect extends OneShotEffect {
|
|||
StringBuilder sb = new StringBuilder();
|
||||
String message = life.getMessage();
|
||||
|
||||
if (!mode.getTargets().isEmpty()) {
|
||||
sb.append("target ").append(mode.getTargets().get(0).getTargetName());
|
||||
if (!mode.getTargets().isEmpty() && mode.getTargets().get(0).getMaxNumberOfTargets() == Integer.MAX_VALUE) {
|
||||
sb.append("any number of target players each gain ");
|
||||
} else if (!mode.getTargets().isEmpty()) {
|
||||
sb.append("target ").append(mode.getTargets().get(0).getTargetName()).append(" gains ");
|
||||
} else {
|
||||
sb.append("that player");
|
||||
sb.append("that player gains ");
|
||||
}
|
||||
sb.append(" gains ");
|
||||
if (message.isEmpty() || !message.equals("1")) {
|
||||
sb.append(life.toString()).append(' ');
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import mage.util.CardUtil;
|
|||
*/
|
||||
public class AbilitiesCostReductionControllerEffect extends CostModificationEffectImpl {
|
||||
|
||||
private Class activatedAbility;
|
||||
private final Class activatedAbility;
|
||||
|
||||
public AbilitiesCostReductionControllerEffect(Class activatedAbility, String activatedAbilityName) {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST);
|
||||
|
|
|
@ -10,8 +10,6 @@ import mage.game.Game;
|
|||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class CostModificationSourceEffect extends CostModificationEffectImpl {
|
||||
|
||||
private final Class<? extends Ability> abilityType;
|
||||
|
|
|
@ -18,7 +18,7 @@ import mage.util.CardUtil;
|
|||
public class SpellCostReductionForEachSourceEffect extends CostModificationEffectImpl {
|
||||
|
||||
private final DynamicValue eachAmount;
|
||||
private ManaCosts<ManaCost> reduceManaCosts;
|
||||
private final ManaCosts<ManaCost> reduceManaCosts;
|
||||
private final int reduceGenericMana;
|
||||
|
||||
public SpellCostReductionForEachSourceEffect(int reduceGenericMana, DynamicValue eachAmount) {
|
||||
|
@ -50,7 +50,6 @@ public class SpellCostReductionForEachSourceEffect extends CostModificationEffec
|
|||
this.staticText = sb.toString();
|
||||
}
|
||||
|
||||
|
||||
protected SpellCostReductionForEachSourceEffect(final SpellCostReductionForEachSourceEffect effect) {
|
||||
super(effect);
|
||||
this.eachAmount = effect.eachAmount;
|
||||
|
|
|
@ -23,7 +23,7 @@ public class SpellsCostIncreasingAllEffect extends CostModificationEffectImpl {
|
|||
private final FilterCard filter;
|
||||
private final TargetController targetController;
|
||||
private final int increaseGenericCost;
|
||||
private ManaCosts<ManaCost> increaseManaCosts;
|
||||
private final ManaCosts<ManaCost> increaseManaCosts;
|
||||
|
||||
public SpellsCostIncreasingAllEffect(int increaseGenericCost, FilterCard filter, TargetController targetController) {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Detriment, CostModificationType.INCREASE_COST);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package mage.abilities.effects.common.cost;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.constants.CostModificationType;
|
||||
|
@ -12,9 +14,6 @@ import mage.game.stack.Spell;
|
|||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
|
@ -23,7 +22,7 @@ public class SpellsCostModificationThatTargetSourceEffect extends CostModificati
|
|||
private final FilterCard spellFilter;
|
||||
private final int modificationAmount;
|
||||
private String targetName = "{this}";
|
||||
private TargetController targetController;
|
||||
private final TargetController targetController;
|
||||
|
||||
public SpellsCostModificationThatTargetSourceEffect(int modificationAmount, FilterCard spellFilter, TargetController targetController) {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Neutral, modificationAmount < 0 ? CostModificationType.REDUCE_COST : CostModificationType.INCREASE_COST);
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package mage.abilities.effects.common.cost;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
|
@ -8,16 +11,12 @@ import mage.choices.ChoiceImpl;
|
|||
import mage.constants.CostModificationType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SpellAbilityCastMode;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.game.Game;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
@ -123,15 +122,12 @@ public class SpellsCostReductionAllEffect extends CostModificationEffectImpl {
|
|||
return false;
|
||||
}
|
||||
if (abilityToModify instanceof SpellAbility) {
|
||||
Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId());
|
||||
if (spell != null) {
|
||||
// real cast with put on stack
|
||||
return this.filter.match(spell, game) && selectedByRuntimeData(spell, source, game);
|
||||
} else {
|
||||
// get playable and other staff without put on stack
|
||||
// used at least for flashback ability because Flashback ability doesn't use stack
|
||||
Card sourceCard = game.getCard(abilityToModify.getSourceId());
|
||||
return sourceCard != null && this.filter.match(sourceCard, game) && selectedByRuntimeData(sourceCard, source, game);
|
||||
Card spellCard = ((SpellAbility) abilityToModify).getCharacteristics(game);
|
||||
if (spellCard != null) {
|
||||
if (((SpellAbility) abilityToModify).getSpellAbilityCastMode() != SpellAbilityCastMode.NORMAL) {
|
||||
spellCard = ((SpellAbility) abilityToModify).getSpellAbilityCastMode().getTypeModifiedCardObjectCopy(spellCard, game);
|
||||
}
|
||||
return this.filter.match(spellCard, game) && selectedByRuntimeData(spellCard, source, game);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package mage.abilities.effects.common.cost;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import mage.MageObject;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -11,15 +13,12 @@ import mage.choices.ChoiceImpl;
|
|||
import mage.constants.CostModificationType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SpellAbilityCastMode;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.game.Game;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author North
|
||||
*/
|
||||
|
@ -114,15 +113,12 @@ public class SpellsCostReductionControllerEffect extends CostModificationEffectI
|
|||
public boolean applies(Ability abilityToModify, Ability source, Game game) {
|
||||
if (abilityToModify instanceof SpellAbility) {
|
||||
if (abilityToModify.isControlledBy(source.getControllerId())) {
|
||||
Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId());
|
||||
if (spell != null) {
|
||||
// real cast with put on stack
|
||||
return this.filter.match(spell, source.getSourceId(), source.getControllerId(), game);
|
||||
} else {
|
||||
// get playable and other staff without put on stack
|
||||
// used at least for flashback ability because Flashback ability doesn't use stack
|
||||
Card sourceCard = game.getCard(abilityToModify.getSourceId());
|
||||
return sourceCard != null && this.filter.match(sourceCard, source.getSourceId(), source.getControllerId(), game);
|
||||
Card spellCard = ((SpellAbility) abilityToModify).getCharacteristics(game);;
|
||||
if (spellCard != null) {
|
||||
if (((SpellAbility) abilityToModify).getSpellAbilityCastMode() != SpellAbilityCastMode.NORMAL) {
|
||||
spellCard = ((SpellAbility) abilityToModify).getSpellAbilityCastMode().getTypeModifiedCardObjectCopy(spellCard, game);
|
||||
}
|
||||
return this.filter.match(spellCard, source.getSourceId(), source.getControllerId(), game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package mage.abilities.hint.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.hint.ConditionHint;
|
||||
import mage.abilities.hint.Hint;
|
||||
import mage.constants.CardType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public enum MetalcraftHint implements Hint {
|
||||
|
||||
instance;
|
||||
private static final ConditionHint hint = new ConditionHint(MetalcraftCondition.instance, "You control three or more artifacts");
|
||||
private static final FilterPermanent filter = new FilterPermanent("artifact");
|
||||
|
||||
static {
|
||||
filter.add(CardType.ARTIFACT.getPredicate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Game game, Ability ability) {
|
||||
int amount = game.getBattlefield().countAll(filter, ability.getControllerId(), game);
|
||||
return hint.getText(game, ability) + " (current: " + amount + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hint copy() {
|
||||
return instance;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import mage.MageObject;
|
||||
|
@ -138,6 +137,14 @@ public class BestowAbility extends SpellAbility {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
static public void becomeAura(Card card) {
|
||||
if (card != null) {
|
||||
card.getSubtype(null).add(SubType.AURA);
|
||||
card.getCardType().remove(CardType.CREATURE);
|
||||
card.getCardType().add(CardType.ENCHANTMENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BestowEntersBattlefieldEffect extends ReplacementEffectImpl {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package mage.abilities.mana;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.Mana;
|
||||
import mage.abilities.ActivatedAbilityImpl;
|
||||
import mage.abilities.costs.Cost;
|
||||
|
@ -13,10 +16,6 @@ import mage.game.Game;
|
|||
import mage.game.stack.Spell;
|
||||
import mage.game.stack.StackObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
@ -87,7 +86,7 @@ public abstract class ActivatedManaAbilityImpl extends ActivatedAbilityImpl impl
|
|||
*/
|
||||
@Override
|
||||
public List<Mana> getNetMana(Game game) {
|
||||
if (netMana.isEmpty()) {
|
||||
if (netMana.isEmpty() || (game != null && game.inCheckPlayableState())) {
|
||||
List<Mana> dynamicNetMana = new ArrayList<>();
|
||||
for (Effect effect : getEffects()) {
|
||||
if (effect instanceof ManaEffect) {
|
||||
|
|
|
@ -348,26 +348,34 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
private boolean subtractCostAddMana(Mana cost, Mana manaToAdd, boolean onlyManaCosts, Mana currentMana) {
|
||||
boolean oldManaWasReplaced = false; // true if the newly created mana includes all mana possibilities of the old
|
||||
boolean repeatable = false;
|
||||
if (manaToAdd.getAny() == 1 && manaToAdd.count() == 1 && onlyManaCosts) {
|
||||
if ((manaToAdd.countColored() > 0 || manaToAdd.getAny() > 0) && manaToAdd.count() > 0 && onlyManaCosts) {
|
||||
// deactivated because it does cause loops TODO: Find reason
|
||||
repeatable = true; // only replace to any with mana costs only will be repeated if able
|
||||
}
|
||||
Mana prevMana = currentMana.copy();
|
||||
if (currentMana.includesMana(cost)) { // it can be paid
|
||||
if (currentMana.includesMana(cost)) { // cost can be paid
|
||||
// generic mana costs can be paid with different colored mana, can lead to different color combinations
|
||||
if (cost.getGeneric() > 0 && cost.getGeneric() > (currentMana.getGeneric() + currentMana.getColorless())) {
|
||||
Mana coloredCost = cost.copy();
|
||||
coloredCost.setGeneric(0);
|
||||
currentMana.subtract(coloredCost);
|
||||
for (Mana payCombination : getPossiblePayCombinations(cost.getGeneric(), currentMana)) {
|
||||
Mana newMana = currentMana.copy();
|
||||
Mana currentManaCopy = currentMana.copy();
|
||||
while (currentManaCopy.includesMana(payCombination)) { // loop for multiple usage if possible
|
||||
boolean newCombinations = false;
|
||||
|
||||
Mana newMana = currentManaCopy.copy();
|
||||
newMana.subtract(payCombination);
|
||||
newMana.add(manaToAdd);
|
||||
Mana moreValuable = Mana.getMoreValuableMana(prevMana, newMana);
|
||||
if (!prevMana.equals(moreValuable)) {
|
||||
this.add(newMana);
|
||||
if (moreValuable != null) {
|
||||
oldManaWasReplaced = true; // the new mana includes all possibilities of the old one
|
||||
// Mana moreValuable = Mana.getMoreValuableMana(currentMana, newMana);
|
||||
if (!isExistingManaCombination(newMana)) {
|
||||
this.add(newMana); // add the new combination
|
||||
newCombinations = true; // repeat the while as long there are new combinations and usage is repeatable
|
||||
currentManaCopy = newMana.copy();
|
||||
Mana moreValuable = Mana.getMoreValuableMana(currentMana, newMana);
|
||||
if (!oldManaWasReplaced && newMana.equals(moreValuable)) {
|
||||
oldManaWasReplaced = true; // the new mana includes all possibilities of the old one, so no need to add it after return
|
||||
}
|
||||
}
|
||||
if (!newCombinations || !repeatable) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -447,6 +455,16 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
return payCombinations;
|
||||
}
|
||||
|
||||
private boolean isExistingManaCombination(Mana newMana) {
|
||||
for (Mana mana : this) {
|
||||
Mana moreValuable = Mana.getMoreValuableMana(mana, newMana);
|
||||
if (mana.equals(moreValuable)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addManaCombination(Mana mana, Mana existingMana, List<Mana> payCombinations, List<String> payCombinationsStrings) {
|
||||
Mana newMana = existingMana.copy();
|
||||
newMana.add(mana);
|
||||
|
@ -478,4 +496,20 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given mana (cost) is already included in one available mana
|
||||
* option
|
||||
*
|
||||
* @param mana
|
||||
* @return
|
||||
*/
|
||||
public boolean enough(Mana mana) {
|
||||
for (Mana avail : this) {
|
||||
if (mana.enough(avail)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
|
||||
package mage.constants;
|
||||
|
||||
import mage.abilities.keyword.BestowAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
@ -21,4 +24,12 @@ public enum SpellAbilityCastMode {
|
|||
public String toString() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public Card getTypeModifiedCardObjectCopy(Card card, Game game) {
|
||||
Card cardCopy = card.copy();
|
||||
if (this.equals(BESTOW)) {
|
||||
BestowAbility.becomeAura(cardCopy);
|
||||
}
|
||||
return cardCopy;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package mage.filter.predicate.other;
|
||||
|
||||
import mage.abilities.keyword.MorphAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public enum FaceDownCastablePredicate implements Predicate<Card> {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(Card input, Game game) {
|
||||
// is card able to cast as face down
|
||||
return input.getAbilities(game).containsClass(MorphAbility.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Face-down";
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package mage.game.command.planes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import mage.MageObject;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -29,9 +31,6 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
import mage.util.CardUtil;
|
||||
import mage.watchers.common.PlanarRollWatcher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author spjspj
|
||||
*/
|
||||
|
@ -52,9 +51,9 @@ public class FeedingGroundsPlane extends Plane {
|
|||
Effect chaosEffect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(), TargetConvertedManaCost.instance);
|
||||
Target chaosTarget = new TargetCreaturePermanent(1, 1, filter, false);
|
||||
|
||||
List<Effect> chaosEffects = new ArrayList<Effect>();
|
||||
List<Effect> chaosEffects = new ArrayList<>();
|
||||
chaosEffects.add(chaosEffect);
|
||||
List<Target> chaosTargets = new ArrayList<Target>();
|
||||
List<Target> chaosTargets = new ArrayList<>();
|
||||
chaosTargets.add(chaosTarget);
|
||||
|
||||
ActivateIfConditionActivatedAbility chaosAbility = new ActivateIfConditionActivatedAbility(Zone.COMMAND, new RollPlanarDieEffect(chaosEffects, chaosTargets), new GenericManaCost(0), MainPhaseStackEmptyCondition.instance);
|
||||
|
|
|
@ -17,7 +17,6 @@ import mage.filter.FilterCard;
|
|||
import mage.filter.common.FilterCreatureCard;
|
||||
import mage.game.Game;
|
||||
import mage.game.command.Plane;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.target.Target;
|
||||
import mage.util.CardUtil;
|
||||
import mage.watchers.common.PlanarRollWatcher;
|
||||
|
@ -42,9 +41,9 @@ public class TurriIslandPlane extends Plane {
|
|||
Effect chaosEffect = new RevealLibraryPutIntoHandEffect(3, new FilterCreatureCard("creature cards"), Zone.GRAVEYARD);
|
||||
Target chaosTarget = null;
|
||||
|
||||
List<Effect> chaosEffects = new ArrayList<Effect>();
|
||||
List<Effect> chaosEffects = new ArrayList<>();
|
||||
chaosEffects.add(chaosEffect);
|
||||
List<Target> chaosTargets = new ArrayList<Target>();
|
||||
List<Target> chaosTargets = new ArrayList<>();
|
||||
chaosTargets.add(chaosTarget);
|
||||
|
||||
ActivateIfConditionActivatedAbility chaosAbility = new ActivateIfConditionActivatedAbility(Zone.COMMAND, new RollPlanarDieEffect(chaosEffects, chaosTargets), new GenericManaCost(0), MainPhaseStackEmptyCondition.instance);
|
||||
|
@ -110,14 +109,12 @@ class TurriIslandEffect extends CostModificationEffectImpl {
|
|||
if (!cPlane.getPlaneType().equals(Planes.PLANE_TURRI_ISLAND)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId());
|
||||
if (spell != null) {
|
||||
return filter.match(spell, game) && selectedByRuntimeData(spell, source, game);
|
||||
} else {
|
||||
// used at least for flashback ability because Flashback ability doesn't use stack
|
||||
Card sourceCard = game.getCard(abilityToModify.getSourceId());
|
||||
return sourceCard != null && filter.match(sourceCard, game) && selectedByRuntimeData(sourceCard, source, game);
|
||||
Card spellCard = ((SpellAbility) abilityToModify).getCharacteristics(game);
|
||||
if (spellCard != null) {
|
||||
if (((SpellAbility) abilityToModify).getSpellAbilityCastMode() != SpellAbilityCastMode.NORMAL) {
|
||||
spellCard = ((SpellAbility) abilityToModify).getSpellAbilityCastMode().getTypeModifiedCardObjectCopy(spellCard, game);
|
||||
}
|
||||
return filter.match(spellCard, game) && selectedByRuntimeData(spellCard, source, game);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -472,7 +472,7 @@ public class StackAbility extends StackObjImpl implements Ability {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setAbilityWord(AbilityWord abilityWord) {
|
||||
public Ability setAbilityWord(AbilityWord abilityWord) {
|
||||
throw new UnsupportedOperationException("Not supported.");
|
||||
}
|
||||
|
||||
|
|
|
@ -3156,11 +3156,14 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
sourceObject.adjustCosts(copyAbility, game);
|
||||
game.getContinuousEffects().costModification(copyAbility, game);
|
||||
|
||||
for (Mana mana : copyAbility.getManaCostsToPay().getOptions()) {
|
||||
for (Mana avail : availableMana) {
|
||||
if (mana.enough(avail)) {
|
||||
// reduced all cost
|
||||
if (copyAbility.getManaCostsToPay().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (Mana mana : copyAbility.getManaCostsToPay().getOptions()) {
|
||||
if (availableMana.enough(mana)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3195,11 +3198,14 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
sourceObject.adjustCosts(copyAbility, game);
|
||||
game.getContinuousEffects().costModification(copyAbility, game);
|
||||
|
||||
for (Mana mana : copyAbility.getManaCostsToPay().getOptions()) {
|
||||
for (Mana avail : availableMana) {
|
||||
if (mana.enough(avail)) {
|
||||
// reduced all cost
|
||||
if (copyAbility.getManaCostsToPay().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (Mana mana : copyAbility.getManaCostsToPay().getOptions()) {
|
||||
if (availableMana.enough(mana)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3247,7 +3253,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
protected ActivatedAbility findActivatedAbilityFromAlternativeSourceCost(MageObject object, ManaOptions availableMana, Ability ability, Game game) {
|
||||
// return play ability that can activate AlternativeSourceCosts
|
||||
if (ability instanceof AlternativeSourceCosts && !(object instanceof Permanent)) {
|
||||
if (ability instanceof AlternativeSourceCosts && object != null && !(object instanceof Permanent)) {
|
||||
ActivatedAbility playAbility = null;
|
||||
if (object.isLand()) {
|
||||
playAbility = (PlayLandAbility) CardUtil.getAbilities(object, game).stream().filter(a -> a instanceof PlayLandAbility).findFirst().orElse(null);
|
||||
|
@ -3263,8 +3269,8 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
// Even mana cost can't be checked here without lookahead
|
||||
// So make it available all the time
|
||||
boolean canUse;
|
||||
if (ability instanceof MorphAbility) {
|
||||
canUse = game.canPlaySorcery(playerId) && ((MorphAbility) ability).isAvailable(playAbility, game);
|
||||
if (ability instanceof MorphAbility && object instanceof Card && game.canPlaySorcery(getId())) {
|
||||
canUse = canPlayCardByAlternateCost((Card) object, availableMana, playAbility, game);
|
||||
} else {
|
||||
canUse = canPlay(playAbility, availableMana, object, game); // canPlay already checks alternative source costs and all conditions
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue