Merge origin/master

This commit is contained in:
LevelX2 2017-05-03 09:30:05 +02:00
commit 69ac72e242
334 changed files with 1441 additions and 1316 deletions

View file

@ -1,6 +1,7 @@
XMage.de 1 (Europe/Germany) fast :xmage.de:17171 XMage.de 1 (Europe/Germany) fast :xmage.de:17171
woogerworks (North America/USA) :xmage.woogerworks.com:17171 woogerworks (North America/USA) :xmage.woogerworks.com:17171
xmage.lukeskywalk.com (North America) :xmage.lukeskywalk.com:17171 xmage.lukeskywalk.com (North America) :xmage.lukeskywalk.com:17171
play.xmage.net (North America/Canada) :play.xmage.net:17171
XMageBr. (South America/Brazil) :magic.ncs3sistemas.com.br:17171 XMageBr. (South America/Brazil) :magic.ncs3sistemas.com.br:17171
XMage.tahiti :xmage.tahiti.one:443 XMage.tahiti :xmage.tahiti.one:443
Seedds Server (Asia) :115.29.203.80:17171 Seedds Server (Asia) :115.29.203.80:17171

View file

@ -68,7 +68,6 @@ import static mage.client.constants.Constants.*;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class Card extends MagePermanent implements MouseMotionListener, MouseListener, FocusListener, ComponentListener { public class Card extends MagePermanent implements MouseMotionListener, MouseListener, FocusListener, ComponentListener {
protected static final DefaultActionCallback callback = DefaultActionCallback.getInstance();
protected Point p; protected Point p;
protected final CardDimensions dimension; protected final CardDimensions dimension;
@ -367,7 +366,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis
@Override @Override
public void mousePressed(MouseEvent e) { public void mousePressed(MouseEvent e) {
requestFocusInWindow(); requestFocusInWindow();
callback.mouseClicked(e, gameId, card); DefaultActionCallback.instance.mouseClicked(gameId, card);
} }
@Override @Override

View file

@ -19,20 +19,14 @@ import java.util.UUID;
/** /**
* @author noxx * @author noxx
*/ */
public class CombatManager { public enum CombatManager {
private static CombatManager combatManager;
instance;
private final Map<UUID, Integer> combatAttackers = new HashMap<>(); private final Map<UUID, Integer> combatAttackers = new HashMap<>();
private final Map<UUID, Integer> combatBlockers = new HashMap<>(); private final Map<UUID, Integer> combatBlockers = new HashMap<>();
private int globalBlockersCount; // we need global counter as there are several combat groups private int globalBlockersCount; // we need global counter as there are several combat groups
public static CombatManager getInstance() {
if (combatManager == null) {
combatManager = new CombatManager();
}
return combatManager;
}
private Point parentPoint; private Point parentPoint;

View file

@ -34,6 +34,7 @@ import java.awt.GridBagLayout;
import javax.swing.Box; import javax.swing.Box;
import javax.swing.BoxLayout; import javax.swing.BoxLayout;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
@ -142,6 +143,17 @@ public final class CollectionViewerPanel extends JPanel {
next.addActionListener(e -> mageBook.next()); next.addActionListener(e -> mageBook.next());
buttonPanel.add(next); buttonPanel.add(next);
JLabel label4 = new JLabel("Show cards or tokens:");
label3.setAlignmentX(Component.LEFT_ALIGNMENT);
label3.setForeground(Color.white);
// spjspj - put back in after reorg of tokens -- jPanel1.add(label4);
JCheckBox cardsOrTokens = new JCheckBox("Display Cards");
cardsOrTokens.setSelected(true);
cardsOrTokens.setToolTipText("Select to show Cards or Tokens(and emblems) for the chosen set");
cardsOrTokens.addActionListener(e -> mageBook.cardsOrTokens(cardsOrTokens.isSelected()));
// spjspj - put back in after reorg of tokens -- jPanel1.add(cardsOrTokens);
formats.addActionListener(e -> { formats.addActionListener(e -> {
if (mageBook != null) { if (mageBook != null) {
String format = (String)formats.getSelectedItem(); String format = (String)formats.getSelectedItem();

View file

@ -57,9 +57,17 @@ import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level;
import mage.game.permanent.PermanentToken;
import mage.game.permanent.token.Token;
import mage.view.PermanentView;
import org.mage.plugins.card.images.CardDownloadData;
import static org.mage.plugins.card.images.DownloadPictures.getTokenCardUrls;
/** /**
* Mage book with cards and page flipping. * Mage book with cards and page flipping.
@ -113,7 +121,7 @@ public class MageBook extends JComponent {
} }
pageRight.setVisible(true); pageRight.setVisible(true);
AudioManager.playPrevPage(); AudioManager.playPrevPage();
showCards(); showCardsOrTokens();
}); });
image = ImageHelper.loadImage(RIGHT_PAGE_BUTTON_IMAGE_PATH); image = ImageHelper.loadImage(RIGHT_PAGE_BUTTON_IMAGE_PATH);
@ -125,7 +133,7 @@ public class MageBook extends JComponent {
pageLeft.setVisible(true); pageLeft.setVisible(true);
pageRight.setVisible(false); pageRight.setVisible(false);
AudioManager.playNextPage(); AudioManager.playNextPage();
showCards(); showCardsOrTokens();
}); });
addSetTabs(); addSetTabs();
@ -170,7 +178,7 @@ public class MageBook extends JComponent {
final String _set = set; final String _set = set;
final int _index = count; final int _index = count;
tab.setObserver(() -> { tab.setObserver(() -> {
if (!currentSet.equals(_set) || currentPage != 0) { if (!currentSet.equals(_set) || currentPage != 0 || stateChanged) {
AudioManager.playAnotherTab(); AudioManager.playAnotherTab();
synchronized (MageBook.this) { synchronized (MageBook.this) {
selectedTab = _index; selectedTab = _index;
@ -180,7 +188,7 @@ public class MageBook extends JComponent {
pageLeft.setVisible(false); pageLeft.setVisible(false);
pageRight.setVisible(false); pageRight.setVisible(false);
addSetTabs(); addSetTabs();
showCards(); showCardsOrTokens();
} }
}); });
tabs.add(tab); tabs.add(tab);
@ -203,6 +211,15 @@ public class MageBook extends JComponent {
} }
} }
private void showCardsOrTokens() {
stateChanged = false;
if (showCardsOrTokens) {
showCards();
} else {
showTokens();
}
}
public void showCards() { public void showCards() {
jLayeredPane.removeAll(); jLayeredPane.removeAll();
addLeftRightPageButtons(); addLeftRightPageButtons();
@ -232,6 +249,37 @@ public class MageBook extends JComponent {
jLayeredPane.repaint(); jLayeredPane.repaint();
} }
public void showTokens() {
jLayeredPane.removeAll();
addLeftRightPageButtons();
List<Token> tokens = getTokens(currentPage, currentSet);
int size = tokens.size();
if (tokens != null && tokens.size() > 0) {
Rectangle rectangle = new Rectangle();
rectangle.translate(OFFSET_X, OFFSET_Y);
for (int i = 0; i < Math.min(conf.CARDS_PER_PAGE / 2, size); i++) {
Token token = tokens.get(i);
addToken(token, bigCard, null, rectangle);
rectangle = CardPosition.translatePosition(i, rectangle, conf);
}
// calculate the x offset of the second (right) page
int second_page_x = (conf.WIDTH - 2 * LEFT_RIGHT_PAGES_WIDTH)
- (cardDimensions.frameWidth + CardPosition.GAP_X) * conf.CARD_COLUMNS + CardPosition.GAP_X - OFFSET_X;
rectangle.setLocation(second_page_x, OFFSET_Y);
for (int i = conf.CARDS_PER_PAGE / 2; i < Math.min(conf.CARDS_PER_PAGE, size); i++) {
Token token = tokens.get(i);
addToken(token, bigCard, null, rectangle);
rectangle = CardPosition.translatePosition(i - conf.CARDS_PER_PAGE / 2, rectangle, conf);
}
jLayeredPane.repaint();
}
}
private void addCard(CardView card, BigCard bigCard, UUID gameId, Rectangle rectangle) { private void addCard(CardView card, BigCard bigCard, UUID gameId, Rectangle rectangle) {
if (cardDimension == null) { if (cardDimension == null) {
cardDimension = new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight); cardDimension = new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight);
@ -252,6 +300,19 @@ public class MageBook extends JComponent {
jLayeredPane.add(label); jLayeredPane.add(label);
} }
private void addToken(Token token, BigCard bigCard, UUID gameId, Rectangle rectangle) {
if (cardDimension == null) {
cardDimension = new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight);
}
PermanentToken newToken = new PermanentToken(token, null, token.getOriginalExpansionSetCode(), null);
PermanentView theToken = new PermanentView(newToken, null, null, null);
final MageCard cardImg = Plugins.instance.getMagePermanent(theToken, bigCard, cardDimension, gameId, true);
cardImg.setBounds(rectangle);
jLayeredPane.add(cardImg, JLayeredPane.DEFAULT_LAYER, 10);
cardImg.update(theToken);
cardImg.setCardBounds(rectangle.x, rectangle.y, cardDimensions.frameWidth, cardDimensions.frameHeight);
}
private List<CardInfo> getCards(int page, String set) { private List<CardInfo> getCards(int page, String set) {
CardCriteria criteria = new CardCriteria(); CardCriteria criteria = new CardCriteria();
criteria.setCodes(set); criteria.setCodes(set);
@ -268,6 +329,50 @@ public class MageBook extends JComponent {
return cards.subList(start, end); return cards.subList(start, end);
} }
private List<Token> getTokens(int page, String set) {
ArrayList<CardDownloadData> allTokens = getTokenCardUrls();
ArrayList<Token> tokens = new ArrayList<>();
for (CardDownloadData token : allTokens) {
if (token.getSet().equals(set)) {
try {
String className = token.getName();
className = className.replaceAll("[^a-zA-Z0-9]", "");
className = className + "Token";
Class<?> c = Class.forName("mage.game.permanent.token." + className);
Constructor<?> cons = c.getConstructor();
Object newToken = cons.newInstance();
if (newToken != null && newToken instanceof mage.game.permanent.token.Token) {
tokens.add((Token) newToken);
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(MageBook.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchMethodException ex) {
java.util.logging.Logger.getLogger(MageBook.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
java.util.logging.Logger.getLogger(MageBook.class.getName()).log(Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(MageBook.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(MageBook.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
java.util.logging.Logger.getLogger(MageBook.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
java.util.logging.Logger.getLogger(MageBook.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
int start = page * conf.CARDS_PER_PAGE;
int end = page * conf.CARDS_PER_PAGE + conf.CARDS_PER_PAGE;
if (end > tokens.size()) {
end = tokens.size();
}
if (tokens.size() > end) {
pageRight.setVisible(true);
}
return tokens.subList(start, end);
}
private ImagePanel getImagePanel(String filename, ImagePanelStyle type) { private ImagePanel getImagePanel(String filename, ImagePanelStyle type) {
try { try {
InputStream is = this.getClass().getResourceAsStream(filename); InputStream is = this.getClass().getResourceAsStream(filename);
@ -320,6 +425,15 @@ public class MageBook extends JComponent {
} }
} }
public void cardsOrTokens(boolean showCards) {
synchronized (this) {
selectedTab = 0;
showCardsOrTokens = !showCardsOrTokens;
stateChanged = true;
tabs.get(selectedTab).execute();
}
}
public void updateSize(String size) { public void updateSize(String size) {
switch (size) { switch (size) {
case LAYOUT_3x3: case LAYOUT_3x3:
@ -415,6 +529,8 @@ public class MageBook extends JComponent {
private java.util.List<String> setsToDisplay = new ArrayList<>(); private java.util.List<String> setsToDisplay = new ArrayList<>();
private final java.util.List<HoverButton> tabs = new ArrayList<>(); private final java.util.List<HoverButton> tabs = new ArrayList<>();
private int selectedTab; private int selectedTab;
private boolean showCardsOrTokens = true;
private boolean stateChanged = false;
private static final String CENTER_PANEL_IMAGE_PATH = "/book_bg.jpg"; private static final String CENTER_PANEL_IMAGE_PATH = "/book_bg.jpg";
private static final String RIGHT_PANEL_IMAGE_PATH = "/book_right.jpg"; private static final String RIGHT_PANEL_IMAGE_PATH = "/book_right.jpg";

View file

@ -181,12 +181,7 @@ public class TableModel extends AbstractTableModel implements ICardGrid {
} }
} }
} else { } else {
for (CardView cv : view) { view.removeIf(cardView -> cardView.getId().equals(entry.getKey()));
if (cv.getId().equals(entry.getKey())) {
view.remove(cv);
break;
}
}
} }
} }
} }
@ -296,12 +291,7 @@ public class TableModel extends AbstractTableModel implements ICardGrid {
public void removeCard(UUID cardId) { public void removeCard(UUID cardId) {
cards.remove(cardId); cards.remove(cardId);
for (CardView cv : view) { view.removeIf(cardView -> cardView.getId().equals(cardId));
if (cv.getId().equals(cardId)) {
view.remove(cv);
break;
}
}
} }
@Override @Override

View file

@ -860,9 +860,9 @@ public final class GamePanel extends javax.swing.JPanel {
showRevealed(game); showRevealed(game);
showLookedAt(game); showLookedAt(game);
if (!game.getCombat().isEmpty()) { if (!game.getCombat().isEmpty()) {
CombatManager.getInstance().showCombat(game.getCombat(), gameId); CombatManager.instance.showCombat(game.getCombat(), gameId);
} else { } else {
CombatManager.getInstance().hideCombat(gameId); CombatManager.instance.hideCombat(gameId);
} }
for (PlayerView player : game.getPlayers()) { for (PlayerView player : game.getPlayers()) {

View file

@ -22,7 +22,6 @@ import javax.swing.JPopupMenu;
import javax.swing.Popup; import javax.swing.Popup;
import javax.swing.PopupFactory; import javax.swing.PopupFactory;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import mage.cards.MageCard; import mage.cards.MageCard;
import mage.cards.action.ActionCallback; import mage.cards.action.ActionCallback;
import mage.cards.action.TransferData; import mage.cards.action.TransferData;
@ -67,7 +66,6 @@ public class MageActionCallback implements ActionCallback {
private Popup tooltipPopup; private Popup tooltipPopup;
private JPopupMenu jPopupMenu; private JPopupMenu jPopupMenu;
private BigCard bigCard; private BigCard bigCard;
protected static final DefaultActionCallback defaultCallback = DefaultActionCallback.getInstance();
private CardView tooltipCard; private CardView tooltipCard;
private TransferData popupData; private TransferData popupData;
@ -178,21 +176,21 @@ public class MageActionCallback implements ActionCallback {
public void showPopup(final Component popupContainer, final Component infoPane) throws InterruptedException { public void showPopup(final Component popupContainer, final Component infoPane) throws InterruptedException {
final Component c = MageFrame.getUI().getComponent(MageComponents.DESKTOP_PANE); final Component c = MageFrame.getUI().getComponent(MageComponents.DESKTOP_PANE);
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
if (!popupTextWindowOpen if (!popupTextWindowOpen
|| enlargedWindowState != EnlargedWindowState.CLOSED) { || enlargedWindowState != EnlargedWindowState.CLOSED) {
return; return;
} }
if (data.locationOnScreen == null) { if (data.locationOnScreen == null) {
data.locationOnScreen = data.component.getLocationOnScreen(); data.locationOnScreen = data.component.getLocationOnScreen();
} }
Point location = new Point((int) data.locationOnScreen.getX() + data.popupOffsetX - 40, (int) data.locationOnScreen.getY() + data.popupOffsetY - 40); Point location = new Point((int) data.locationOnScreen.getX() + data.popupOffsetX - 40, (int) data.locationOnScreen.getY() + data.popupOffsetY - 40);
location = GuiDisplayUtil.keepComponentInsideParent(location, parentPoint, infoPane, parentComponent); location = GuiDisplayUtil.keepComponentInsideParent(location, parentPoint, infoPane, parentComponent);
location.translate(-parentPoint.x, -parentPoint.y); location.translate(-parentPoint.x, -parentPoint.y);
popupContainer.setLocation(location); popupContainer.setLocation(location);
popupContainer.setVisible(true); popupContainer.setVisible(true);
c.repaint(); c.repaint();
} }
); );
} }
}); });
@ -236,14 +234,14 @@ public class MageActionCallback implements ActionCallback {
this.startedDragging = false; this.startedDragging = false;
if (maxXOffset < MIN_X_OFFSET_REQUIRED) { // we need this for protection from small card movements if (maxXOffset < MIN_X_OFFSET_REQUIRED) { // we need this for protection from small card movements
transferData.component.requestFocusInWindow(); transferData.component.requestFocusInWindow();
defaultCallback.mouseClicked(e, transferData.gameId, transferData.card); DefaultActionCallback.instance.mouseClicked(transferData.gameId, transferData.card);
// Closes popup & enlarged view if a card/Permanent is selected // Closes popup & enlarged view if a card/Permanent is selected
hideTooltipPopup(); hideTooltipPopup();
} }
e.consume(); e.consume();
} else { } else {
transferData.component.requestFocusInWindow(); transferData.component.requestFocusInWindow();
defaultCallback.mouseClicked(e, transferData.gameId, transferData.card); DefaultActionCallback.instance.mouseClicked(transferData.gameId, transferData.card);
// Closes popup & enlarged view if a card/Permanent is selected // Closes popup & enlarged view if a card/Permanent is selected
hideTooltipPopup(); hideTooltipPopup();
e.consume(); e.consume();
@ -464,7 +462,7 @@ public class MageActionCallback implements ActionCallback {
int notches = e.getWheelRotation(); int notches = e.getWheelRotation();
if (enlargedWindowState != EnlargedWindowState.CLOSED) { if (enlargedWindowState != EnlargedWindowState.CLOSED) {
// same move direction will be ignored, opposite direction closes the enlarged window // same move direction will be ignored, opposite direction closes the enlarged window
if (new Date().getTime() - enlargeredViewOpened.getTime() > 1000) { if (enlargeredViewOpened != null && new Date().getTime() - enlargeredViewOpened.getTime() > 1000) {
// if the opening is back more than 1 seconds close anyway // if the opening is back more than 1 seconds close anyway
hideEnlargedCard(); hideEnlargedCard();
handleOverNewView(transferData); handleOverNewView(transferData);
@ -492,7 +490,7 @@ public class MageActionCallback implements ActionCallback {
* Show the big card image on mouse position while hovering over a card * Show the big card image on mouse position while hovering over a card
* *
* @param showAlternative defines if the original image (if it's a copied * @param showAlternative defines if the original image (if it's a copied
* card) or the opposite side of a transformable card will be shown * card) or the opposite side of a transformable card will be shown
*/ */
public void enlargeCard(EnlargeMode showAlternative) { public void enlargeCard(EnlargeMode showAlternative) {
if (enlargedWindowState == EnlargedWindowState.CLOSED) { if (enlargedWindowState == EnlargedWindowState.CLOSED) {

View file

@ -7,17 +7,11 @@ import mage.client.SessionHandler;
import mage.view.CardView; import mage.view.CardView;
public class DefaultActionCallback { public enum DefaultActionCallback {
private static final DefaultActionCallback INSTANCE = new DefaultActionCallback(); instance;
private DefaultActionCallback() {} public void mouseClicked(UUID gameId, CardView card) {
public static DefaultActionCallback getInstance() {
return INSTANCE;
}
public void mouseClicked(MouseEvent e, UUID gameId, CardView card) {
if (gameId != null) { if (gameId != null) {
if (card.isAbility() && card.getAbility() != null) { if (card.isAbility() && card.getAbility() != null) {
SessionHandler.sendPlayerUUID(gameId, card.getAbility().getId()); SessionHandler.sendPlayerUUID(gameId, card.getAbility().getId());

View file

@ -140,13 +140,8 @@ public final class ImageHelper {
* @return * @return
*/ */
public static Image getImageFromResources(String path) { public static Image getImageFromResources(String path) {
InputStream stream;
stream = UI.class.getResourceAsStream(path);
if (stream == null) {
throw new IllegalArgumentException("Couldn't find image in resources: " + path);
}
try { try(InputStream stream = UI.class.getResourceAsStream(path)) {
ImageIO.setUseCache(false); ImageIO.setUseCache(false);
BufferedImage image = ImageIO.read(stream); BufferedImage image = ImageIO.read(stream);
return image; return image;

View file

@ -151,7 +151,7 @@ public class CardPluginImpl implements CardPlugin {
outerLoop: outerLoop:
// //
for (MagePermanent permanent : permanents) { for (MagePermanent permanent : permanents) {
if (!CardUtil.isLand(permanent) || CardUtil.isCreature(permanent)) { if (!permanent.isLand() || permanent.isCreature()) {
continue; continue;
} }
@ -418,11 +418,11 @@ public class CardPluginImpl implements CardPlugin {
public boolean isType(MagePermanent card) { public boolean isType(MagePermanent card) {
switch (this) { switch (this) {
case land: case land:
return CardUtil.isLand(card); return card.isLand();
case creature: case creature:
return CardUtil.isCreature(card); return card.isCreature();
case other: case other:
return !CardUtil.isLand(card) && !CardUtil.isCreature(card); return !card.isLand() && !card.isCreature();
case attached: case attached:
return card.getOriginalPermanent().isAttachedToPermanent(); return card.getOriginalPermanent().isAttachedToPermanent();
default: default:

View file

@ -37,19 +37,12 @@ import java.util.HashMap;
* *
* @author spjspj * @author spjspj
*/ */
public class AltMtgOnlTokensImageSource implements CardImageSource { public enum AltMtgOnlTokensImageSource implements CardImageSource {
instance;
private static final Logger logger = Logger.getLogger(AltMtgOnlTokensImageSource.class); private static final Logger logger = Logger.getLogger(AltMtgOnlTokensImageSource.class);
private static CardImageSource instance = new AltMtgOnlTokensImageSource();
private static int maxTimes = 0; private static int maxTimes = 0;
public static CardImageSource getInstance() {
if (instance == null) {
instance = new AltMtgOnlTokensImageSource();
}
return instance;
}
@Override @Override
public String getSourceName() { public String getSourceName() {
return "http://alternative.mtg.onl/tokens/"; return "http://alternative.mtg.onl/tokens/";

View file

@ -37,19 +37,12 @@ import org.mage.plugins.card.images.CardDownloadData;
* *
* @author spjspj * @author spjspj
*/ */
public class GrabbagImageSource implements CardImageSource { public enum GrabbagImageSource implements CardImageSource {
instance;
private static final Logger logger = Logger.getLogger(GrabbagImageSource.class); private static final Logger logger = Logger.getLogger(GrabbagImageSource.class);
private static CardImageSource instance = new GrabbagImageSource();
private static int maxTimes = 0; private static int maxTimes = 0;
public static CardImageSource getInstance() {
if (instance == null) {
instance = new GrabbagImageSource();
}
return instance;
}
@Override @Override
public String getSourceName() { public String getSourceName() {
return ""; return "";

View file

@ -10,10 +10,9 @@ import org.mage.plugins.card.utils.CardImageUtils;
* *
* @author North * @author North
*/ */
public class MagicCardsImageSource implements CardImageSource { public enum MagicCardsImageSource implements CardImageSource {
private static CardImageSource instance = new MagicCardsImageSource();
instance;
private static final Map<String, String> setNameTokenReplacement = new HashMap<String, String>() { private static final Map<String, String> setNameTokenReplacement = new HashMap<String, String>() {
{ {
put("10E", "tenth-edition"); put("10E", "tenth-edition");
@ -146,12 +145,6 @@ public class MagicCardsImageSource implements CardImageSource {
return "magiccards.info"; return "magiccards.info";
} }
public static CardImageSource getInstance() {
if (instance == null) {
instance = new MagicCardsImageSource();
}
return instance;
}
@Override @Override
public String getNextHttpImageUrl() { public String getNextHttpImageUrl() {

View file

@ -36,15 +36,9 @@ import java.net.URI;
* @author Pete Rossi * @author Pete Rossi
*/ */
public class MagidexImageSource implements CardImageSource { public enum MagidexImageSource implements CardImageSource {
private static CardImageSource instance = new MagidexImageSource(); instance;
public static CardImageSource getInstance() {
if (instance == null) {
instance = new MagidexImageSource();
}
return instance;
}
@Override @Override
public String getSourceName() { public String getSourceName() {
return "magidex.com"; return "magidex.com";

View file

@ -39,16 +39,9 @@ import org.mage.plugins.card.images.CardDownloadData;
* @author LevelX2 * @author LevelX2
*/ */
public class MtgImageSource implements CardImageSource { public enum MtgImageSource implements CardImageSource {
private static CardImageSource instance = new MtgImageSource(); instance;
public static CardImageSource getInstance() {
if (instance == null) {
instance = new MtgImageSource();
}
return instance;
}
@Override @Override
public String getSourceName() { public String getSourceName() {

View file

@ -37,19 +37,12 @@ import java.util.HashMap;
* *
* @author spjspj * @author spjspj
*/ */
public class MtgOnlTokensImageSource implements CardImageSource { public enum MtgOnlTokensImageSource implements CardImageSource {
instance;
private static final Logger logger = Logger.getLogger(MtgOnlTokensImageSource.class); private static final Logger logger = Logger.getLogger(MtgOnlTokensImageSource.class);
private static CardImageSource instance = new MtgOnlTokensImageSource();
private static int maxTimes = 0; private static int maxTimes = 0;
public static CardImageSource getInstance() {
if (instance == null) {
instance = new MtgOnlTokensImageSource();
}
return instance;
}
@Override @Override
public String getSourceName() { public String getSourceName() {
return "http://mtg.onl/token-list/tokens/"; return "http://mtg.onl/token-list/tokens/";

View file

@ -54,27 +54,21 @@ import org.mage.plugins.card.images.CardDownloadData;
* *
* @author LevelX2 * @author LevelX2
*/ */
public class MythicspoilerComSource implements CardImageSource { public enum MythicspoilerComSource implements CardImageSource {
private static CardImageSource instance; instance;
private static Map<String, String> setsAliases; private Map<String, String> setsAliases;
private static Map<String, String> cardNameAliases; private Map<String, String> cardNameAliases;
private static Map<String, Set<String>> cardNameAliasesStart; private Map<String, Set<String>> cardNameAliasesStart;
private final Map<String, Map<String, String>> sets; private final Map<String, Map<String, String>> sets;
public static CardImageSource getInstance() {
if (instance == null) {
instance = new MythicspoilerComSource();
}
return instance;
}
@Override @Override
public String getSourceName() { public String getSourceName() {
return "mythicspoiler.com"; return "mythicspoiler.com";
} }
public MythicspoilerComSource() { MythicspoilerComSource() {
sets = new LinkedHashMap<>(); sets = new LinkedHashMap<>();
setsAliases = new HashMap<>(); setsAliases = new HashMap<>();
setsAliases.put("exp", "bfz"); setsAliases.put("exp", "bfz");

View file

@ -44,23 +44,16 @@ import java.util.Map;
* *
* @author Quercitron * @author Quercitron
*/ */
public class TokensMtgImageSource implements CardImageSource { public enum TokensMtgImageSource implements CardImageSource {
instance;
private static final Logger logger = Logger.getLogger(TokensMtgImageSource.class); private static final Logger logger = Logger.getLogger(TokensMtgImageSource.class);
private static CardImageSource instance = new TokensMtgImageSource();
private List<TokenData> tokensData; private List<TokenData> tokensData;
private final Object tokensDataSync = new Object(); private final Object tokensDataSync = new Object();
public static CardImageSource getInstance() {
if (instance == null) {
instance = new TokensMtgImageSource();
}
return instance;
}
@Override @Override
public String getSourceName() { public String getSourceName() {
return "tokens.mtg.onl"; return "tokens.mtg.onl";

View file

@ -42,6 +42,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.dialog.PreferencesDialog; import mage.client.dialog.PreferencesDialog;
import mage.remote.Connection; import mage.remote.Connection;
@ -53,29 +54,22 @@ import org.jsoup.select.Elements;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
/** /**
*
* @author North * @author North
*/ */
public class WizardCardsImageSource implements CardImageSource { public enum WizardCardsImageSource implements CardImageSource {
private static CardImageSource instance; instance;
private static Map<String, String> setsAliases; private Map<String, String> setsAliases;
private static Map<String, String> languageAliases; private Map<String, String> languageAliases;
private final Map<String, Map<String, String>> sets; private final Map<String, Map<String, String>> sets;
public static CardImageSource getInstance() {
if (instance == null) {
instance = new WizardCardsImageSource();
}
return instance;
}
@Override @Override
public String getSourceName() { public String getSourceName() {
return "WOTC Gatherer"; return "WOTC Gatherer";
} }
public WizardCardsImageSource() { WizardCardsImageSource() {
sets = new HashMap<>(); sets = new HashMap<>();
setsAliases = new HashMap<>(); setsAliases = new HashMap<>();
setsAliases.put("2ED", "Unlimited Edition"); setsAliases.put("2ED", "Unlimited Edition");

View file

@ -117,7 +117,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
}); });
jComboBox1 = new JComboBox(); jComboBox1 = new JComboBox();
cardImageSource = MagicCardsImageSource.getInstance(); cardImageSource = MagicCardsImageSource.instance;
jComboBox1.setModel(jComboBox1Model); jComboBox1.setModel(jComboBox1Model);
jComboBox1.setAlignmentX(Component.LEFT_ALIGNMENT); jComboBox1.setAlignmentX(Component.LEFT_ALIGNMENT);
@ -125,28 +125,28 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
JComboBox cb = (JComboBox) e.getSource(); JComboBox cb = (JComboBox) e.getSource();
switch (cb.getSelectedIndex()) { switch (cb.getSelectedIndex()) {
case 0: case 0:
cardImageSource = MagicCardsImageSource.getInstance(); cardImageSource = MagicCardsImageSource.instance;
break; break;
case 1: case 1:
cardImageSource = WizardCardsImageSource.getInstance(); cardImageSource = WizardCardsImageSource.instance;
break; break;
case 2: case 2:
cardImageSource = MythicspoilerComSource.getInstance(); cardImageSource = MythicspoilerComSource.instance;
break; break;
case 3: case 3:
cardImageSource = TokensMtgImageSource.getInstance(); cardImageSource = TokensMtgImageSource.instance;
break; break;
case 4: case 4:
cardImageSource = MtgOnlTokensImageSource.getInstance(); cardImageSource = MtgOnlTokensImageSource.instance;
break; break;
case 5: case 5:
cardImageSource = AltMtgOnlTokensImageSource.getInstance(); cardImageSource = AltMtgOnlTokensImageSource.instance;
break; break;
case 6: case 6:
cardImageSource = GrabbagImageSource.getInstance(); cardImageSource = GrabbagImageSource.instance;
break; break;
case 7: case 7:
cardImageSource = MagidexImageSource.getInstance(); cardImageSource = MagidexImageSource.instance;
break; break;
} }
updateCardsToDownload(); updateCardsToDownload();
@ -336,7 +336,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
return new ArrayList<>(cardsToDownload); return new ArrayList<>(cardsToDownload);
} }
private static ArrayList<CardDownloadData> getTokenCardUrls() throws RuntimeException { public static ArrayList<CardDownloadData> getTokenCardUrls() throws RuntimeException {
ArrayList<CardDownloadData> list = new ArrayList<>(); ArrayList<CardDownloadData> list = new ArrayList<>();
InputStream in = DownloadPictures.class.getClassLoader().getResourceAsStream("card-pictures-tok.txt"); InputStream in = DownloadPictures.class.getClassLoader().getResourceAsStream("card-pictures-tok.txt");

View file

@ -525,16 +525,12 @@
|Generate|TOK:M13|Wurm|| |Generate|TOK:M13|Wurm||
|Generate|EMBLEM:AVR|Tamiyo, the Moon Sage||Emblem Tamiyo| |Generate|EMBLEM:AVR|Tamiyo, the Moon Sage||Emblem Tamiyo|
|Generate|TOK:AVR|Angel|1| |Generate|TOK:AVR|Angel||
|Generate|TOK:AVR|Angel|2| |Generate|TOK:AVR|Demon||
|Generate|TOK:AVR|Angel|3|
|Generate|TOK:AVR|Human|1| |Generate|TOK:AVR|Human|1|
|Generate|TOK:AVR|Human|2| |Generate|TOK:AVR|Human|2|
|Generate|TOK:AVR|Spirit|1| |Generate|TOK:AVR|Spirit|1|
|Generate|TOK:AVR|Spirit|2| |Generate|TOK:AVR|Spirit|2|
|Generate|TOK:AVR|Demon|1|
|Generate|TOK:AVR|Demon|2|
|Generate|TOK:AVR|Demon|3|
|Generate|TOK:AVR|Zombie|| |Generate|TOK:AVR|Zombie||
|Generate|EMBLEM:DDI|Venser, the Sojourner||Emblem Venser| |Generate|EMBLEM:DDI|Venser, the Sojourner||Emblem Venser|

View file

@ -16,7 +16,7 @@ public class TokensMtgImageSourceTest {
@Test @Test
public void generateTokenUrlTest() throws Exception { public void generateTokenUrlTest() throws Exception {
CardImageSource imageSource = TokensMtgImageSource.getInstance(); CardImageSource imageSource = TokensMtgImageSource.instance;
String url = imageSource.generateTokenUrl(new CardDownloadData("Thopter", "ORI", "0", false, 1, "ORI", "")); String url = imageSource.generateTokenUrl(new CardDownloadData("Thopter", "ORI", "0", false, 1, "ORI", ""));
Assert.assertEquals("http://tokens.mtg.onl/tokens/ORI_010-Thopter.jpg", url); Assert.assertEquals("http://tokens.mtg.onl/tokens/ORI_010-Thopter.jpg", url);

View file

@ -10,4 +10,12 @@ public abstract class MagePermanent extends MageCard {
public abstract void update(PermanentView card); public abstract void update(PermanentView card);
public abstract PermanentView getOriginalPermanent(); public abstract PermanentView getOriginalPermanent();
public boolean isCreature(){
return getOriginal().isCreature();
}
public boolean isLand(){
return getOriginal().isLand();
}
} }

View file

@ -21,25 +21,6 @@ public final class CardUtil {
private static final String regexGreen = ".*\\x7b.{0,2}G.{0,2}\\x7d.*"; private static final String regexGreen = ".*\\x7b.{0,2}G.{0,2}\\x7d.*";
private static final String regexWhite = ".*\\x7b.{0,2}W.{0,2}\\x7d.*"; private static final String regexWhite = ".*\\x7b.{0,2}W.{0,2}\\x7d.*";
public static boolean isCreature(MagePermanent card) {
return is(card.getOriginal(), CardType.CREATURE);
}
public static boolean isPlaneswalker(MagePermanent card) {
return is(card.getOriginal(), CardType.PLANESWALKER);
}
public static boolean isLand(MagePermanent card) {
return is(card.getOriginal(), CardType.LAND);
}
public static boolean is(CardView card, CardType type) {
return card.getCardTypes().contains(type);
}
public static int getColorIdentitySortValue(List<String> manaCost, ObjectColor originalColor, List<String> rules) { public static int getColorIdentitySortValue(List<String> manaCost, ObjectColor originalColor, List<String> rules) {
ObjectColor color = new ObjectColor(originalColor); ObjectColor color = new ObjectColor(originalColor);
for (String rule : rules) { for (String rule : rules) {

View file

@ -41,7 +41,7 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
public final static int MAGE_VERSION_MAJOR = 1; public final static int MAGE_VERSION_MAJOR = 1;
public final static int MAGE_VERSION_MINOR = 4; public final static int MAGE_VERSION_MINOR = 4;
public final static int MAGE_VERSION_PATCH = 23; public final static int MAGE_VERSION_PATCH = 23;
public final static String MAGE_VERSION_MINOR_PATCH = "V3"; public final static String MAGE_VERSION_MINOR_PATCH = "V4";
public final static String MAGE_VERSION_INFO = ""; public final static String MAGE_VERSION_INFO = "";
private final int major; private final int major;

View file

@ -28,6 +28,7 @@
package mage.view; package mage.view;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import mage.MageObject; import mage.MageObject;
import mage.ObjectColor; import mage.ObjectColor;
import mage.abilities.Abilities; import mage.abilities.Abilities;
@ -64,7 +65,7 @@ public class CardView extends SimpleCardView {
protected List<String> rules; protected List<String> rules;
protected String power; protected String power;
protected String toughness; protected String toughness;
protected String loyalty; protected String loyalty = "";
protected String startingLoyalty; protected String startingLoyalty;
protected EnumSet<CardType> cardTypes; protected EnumSet<CardType> cardTypes;
protected List<String> subTypes; protected List<String> subTypes;
@ -344,12 +345,12 @@ public class CardView extends SimpleCardView {
if (card instanceof Permanent) { if (card instanceof Permanent) {
this.mageObjectType = MageObjectType.PERMANENT; this.mageObjectType = MageObjectType.PERMANENT;
Permanent permanent = (Permanent) card; Permanent permanent = (Permanent) card;
this.loyalty = Integer.toString(permanent.getCounters(game).getCount(CounterType.LOYALTY));
this.pairedCard = permanent.getPairedCard() != null ? permanent.getPairedCard().getSourceId() : null;
if (!permanent.getControllerId().equals(permanent.getOwnerId())) {
controlledByOwner = false;
}
if (game != null && permanent.getCounters(game) != null && !permanent.getCounters(game).isEmpty()) { if (game != null && permanent.getCounters(game) != null && !permanent.getCounters(game).isEmpty()) {
this.loyalty = Integer.toString(permanent.getCounters(game).getCount(CounterType.LOYALTY));
this.pairedCard = permanent.getPairedCard() != null ? permanent.getPairedCard().getSourceId() : null;
if (!permanent.getControllerId().equals(permanent.getOwnerId())) {
controlledByOwner = false;
}
counters = new ArrayList<>(); counters = new ArrayList<>();
for (Counter counter : permanent.getCounters(game).values()) { for (Counter counter : permanent.getCounters(game).values()) {
counters.add(new CounterView(counter)); counters.add(new CounterView(counter));
@ -963,44 +964,24 @@ public class CardView extends SimpleCardView {
} }
public String getColorText() { public String getColorText() {
if (getColor().getColorCount() == 0) {
return "Colorless"; String color = getColor().getDescription();
} else if (getColor().getColorCount() > 1) { return color.substring(0, 1).toUpperCase() + color.substring(1);
return "Gold";
} else if (getColor().isBlack()) {
return "Black";
} else if (getColor().isBlue()) {
return "Blue";
} else if (getColor().isWhite()) {
return "White";
} else if (getColor().isGreen()) {
return "Green";
} else if (getColor().isRed()) {
return "Red";
}
return "";
} }
public String getTypeText() { public String getTypeText() {
StringBuilder type = new StringBuilder(); StringBuilder type = new StringBuilder();
for (SuperType superType : getSuperTypes()) { if (!getSuperTypes().isEmpty()) {
type.append(superType.toString()); type.append(String.join(" ", getSuperTypes().stream().map(SuperType::toString).collect(Collectors.toList())));
type.append(' '); type.append(" ");
} }
for (CardType cardType : getCardTypes()) { if (!getCardTypes().isEmpty()) {
type.append(cardType.toString()); type.append(String.join(" ", getCardTypes().stream().map(CardType::toString).collect(Collectors.toList())));
type.append(' '); type.append(" ");
} }
if (!getSubTypes().isEmpty()) { if (!getSubTypes().isEmpty()) {
type.append("- "); type.append(" - ");
for (String subType : getSubTypes()) { type.append(String.join(" ", getSubTypes()));
type.append(subType);
type.append(' ');
}
}
if (type.length() > 0) {
// remove trailing space
type.deleteCharAt(type.length() - 1);
} }
return type.toString(); return type.toString();
} }

View file

@ -197,7 +197,7 @@ public class GameView implements Serializable {
this.special = false; this.special = false;
} }
CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getName()); CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
spellsCastCurrentTurn = watcher.getAmountOfSpellsAllPlayersCastOnCurrentTurn(); spellsCastCurrentTurn = watcher.getAmountOfSpellsAllPlayersCastOnCurrentTurn();
} else { } else {

View file

@ -62,8 +62,8 @@ public class PermanentView extends CardView {
private final boolean attachedToPermanent; private final boolean attachedToPermanent;
public PermanentView(Permanent permanent, Card card, UUID createdForPlayerId, Game game) { public PermanentView(Permanent permanent, Card card, UUID createdForPlayerId, Game game) {
super(permanent, game, permanent.getControllerId().equals(createdForPlayerId)); super(permanent, game, (permanent.getControllerId() == null) ? false : permanent.getControllerId().equals(createdForPlayerId));
this.controlled = permanent.getControllerId().equals(createdForPlayerId); this.controlled = (permanent.getControllerId() == null) ? false : permanent.getControllerId().equals(createdForPlayerId);
this.rules = permanent.getRules(game); this.rules = permanent.getRules(game);
this.tapped = permanent.isTapped(); this.tapped = permanent.isTapped();
this.flipped = permanent.isFlipped(); this.flipped = permanent.isFlipped();
@ -106,7 +106,7 @@ public class PermanentView extends CardView {
} }
} }
} }
if (!permanent.getOwnerId().equals(permanent.getControllerId())) { if (permanent.getOwnerId() != null && !permanent.getOwnerId().equals(permanent.getControllerId())) {
Player owner = game.getPlayer(permanent.getOwnerId()); Player owner = game.getPlayer(permanent.getOwnerId());
if (owner != null) { if (owner != null) {
this.nameOwner = owner.getName(); this.nameOwner = owner.getName();

View file

@ -150,7 +150,7 @@ public class Commander extends Constructed {
invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')'); invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')');
valid = false; valid = false;
} }
FilterMana commanderColor = CardUtil.getColorIdentity(commander); FilterMana commanderColor = commander.getColorIdentity();
if (commanderColor.isWhite()) { if (commanderColor.isWhite()) {
colorIdentity.setWhite(true); colorIdentity.setWhite(true);
} }
@ -194,7 +194,7 @@ public class Commander extends Constructed {
} }
public boolean cardHasValidColor(FilterMana commander, Card card) { public boolean cardHasValidColor(FilterMana commander, Card card) {
FilterMana cardColor = CardUtil.getColorIdentity(card); FilterMana cardColor = card.getColorIdentity();
return !(cardColor.isBlack() && !commander.isBlack() return !(cardColor.isBlack() && !commander.isBlack()
|| cardColor.isBlue() && !commander.isBlue() || cardColor.isBlue() && !commander.isBlue()
|| cardColor.isGreen() && !commander.isGreen() || cardColor.isGreen() && !commander.isGreen()
@ -654,7 +654,7 @@ public class Commander extends Constructed {
color = color.union(commander.getColor(null)); color = color.union(commander.getColor(null));
} }
FilterMana commanderColor = CardUtil.getColorIdentity(commander); FilterMana commanderColor = commander.getColorIdentity();
if (commanderColor.isWhite()) { if (commanderColor.isWhite()) {
color.setWhite(true); color.setWhite(true);
} }

View file

@ -24,11 +24,11 @@
* The views and conclusions contained in the software and documentation are those of the * The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.deck; package mage.deck;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
@ -56,13 +56,18 @@ public class Standard extends Constructed {
} }
}); });
int blocksAdded = 0; int blocksAdded = 0;
for (Iterator<ExpansionSet> iter = sets.iterator(); iter.hasNext() && blocksAdded < 3; ) { int blocksToAdd = 3;
for (Iterator<ExpansionSet> iter = sets.iterator(); iter.hasNext() && blocksAdded < blocksToAdd;) {
ExpansionSet set = iter.next(); ExpansionSet set = iter.next();
if (set.getSetType() == SetType.CORE || set.getSetType() == SetType.EXPANSION || set.getSetType() == SetType.SUPPLEMENTAL_STANDARD_LEGAL) { // Still adding core sets because of Magic Origins if (set.getSetType() == SetType.CORE || set.getSetType() == SetType.EXPANSION || set.getSetType() == SetType.SUPPLEMENTAL_STANDARD_LEGAL) { // Still adding core sets because of Magic Origins
setCodes.add(set.getCode()); setCodes.add(set.getCode());
if (set.getReleaseDate().before(current.getTime()) // This stops spoiled sets from counting as "new" blocks if (set.getReleaseDate().before(current.getTime()) // This stops spoiled sets from counting as "new" blocks
&& set.getParentSet() == null && set.getParentSet() == null
&& set.getSetType() == SetType.EXPANSION) { && set.getSetType() == SetType.EXPANSION) {
if (blocksAdded == 0 && !isFallBlock(set)) { // if the most current block is no fall block, 4 blocks are added
blocksToAdd++;
}
blocksAdded++; blocksAdded++;
} }
} }
@ -72,4 +77,11 @@ public class Standard extends Constructed {
banned.add("Smuggler's Copter"); banned.add("Smuggler's Copter");
banned.add("Felidar Guardian"); banned.add("Felidar Guardian");
} }
private static boolean isFallBlock(ExpansionSet set) {
Calendar cal = Calendar.getInstance();
cal.setTime(set.getReleaseDate());
// Sets from fall block are normally released in September and January
return cal.get(Calendar.MONTH) > 8 || cal.get(Calendar.MONTH) < 2;
}
} }

View file

@ -177,7 +177,7 @@ public class TinyLeaders extends Constructed {
if ((commander.isCreature() && commander.isLegendary()) if ((commander.isCreature() && commander.isLegendary())
|| (commander.isPlaneswalker() && commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) { || (commander.isPlaneswalker() && commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) {
if (!bannedCommander.contains(commander.getName())) { if (!bannedCommander.contains(commander.getName())) {
FilterMana color = CardUtil.getColorIdentity(commander); FilterMana color = commander.getColorIdentity();
for (Card card : deck.getCards()) { for (Card card : deck.getCards()) {
if (!isCardFormatValid(card, commander, color)) { if (!isCardFormatValid(card, commander, color)) {
valid = false; valid = false;
@ -249,7 +249,7 @@ public class TinyLeaders extends Constructed {
* @return True if card has a valid color identity * @return True if card has a valid color identity
*/ */
public boolean cardHasValideColor(FilterMana commander, Card card) { public boolean cardHasValideColor(FilterMana commander, Card card) {
FilterMana cardColor = CardUtil.getColorIdentity(card); FilterMana cardColor = card.getColorIdentity();
return !(cardColor.isBlack() && !commander.isBlack() return !(cardColor.isBlack() && !commander.isBlack()
|| cardColor.isBlue() && !commander.isBlue() || cardColor.isBlue() && !commander.isBlue()
|| cardColor.isGreen() && !commander.isGreen() || cardColor.isGreen() && !commander.isGreen()

View file

@ -77,7 +77,7 @@ class AetherfluxReservoirDynamicValue implements DynamicValue {
@Override @Override
public int calculate(Game game, Ability sourceAbility, Effect effect) { public int calculate(Game game, Ability sourceAbility, Effect effect) {
CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getName()); CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getSimpleName());
return watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(sourceAbility.getControllerId()); return watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(sourceAbility.getControllerId());
} }

View file

@ -88,7 +88,7 @@ class AggravateRequirementEffect extends RequirementEffect {
@Override @Override
public boolean applies(Permanent permanent, Ability source, Game game) { public boolean applies(Permanent permanent, Ability source, Game game) {
DamagedByWatcher watcher = (DamagedByWatcher) game.getState().getWatchers().get("DamagedByWatcher", source.getSourceId()); DamagedByWatcher watcher = (DamagedByWatcher) game.getState().getWatchers().get(DamagedByWatcher.class.getSimpleName(), source.getSourceId());
if (watcher != null) { if (watcher != null) {
return watcher.wasDamaged(permanent, game); return watcher.wasDamaged(permanent, game);
} }

View file

@ -140,7 +140,7 @@ class AlhammarretsArchiveReplacementEffect extends ReplacementEffectImpl {
if (event.getPlayerId().equals(source.getControllerId())) { if (event.getPlayerId().equals(source.getControllerId())) {
if (game.getActivePlayerId().equals(event.getPlayerId()) if (game.getActivePlayerId().equals(event.getPlayerId())
&& game.getPhase().getStep().getType() == PhaseStep.DRAW) { && game.getPhase().getStep().getType() == PhaseStep.DRAW) {
CardsDrawnDuringDrawStepWatcher watcher = (CardsDrawnDuringDrawStepWatcher) game.getState().getWatchers().get("CardsDrawnDuringDrawStep"); CardsDrawnDuringDrawStepWatcher watcher = (CardsDrawnDuringDrawStepWatcher) game.getState().getWatchers().get(CardsDrawnDuringDrawStepWatcher.class.getSimpleName());
if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) > 0) { if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) > 0) {
return true; return true;
} }

View file

@ -47,13 +47,12 @@ import mage.util.CardUtil;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public class AlphaAuthority extends CardImpl { public class AlphaAuthority extends CardImpl {
public AlphaAuthority(UUID ownerId, CardSetInfo setInfo) { public AlphaAuthority(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{G}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
this.subtype.add("Aura"); this.subtype.add("Aura");
@ -66,7 +65,7 @@ public class AlphaAuthority extends CardImpl {
// Enchanted creature has hexproof and can't be blocked by more than one creature. // Enchanted creature has hexproof and can't be blocked by more than one creature.
ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(HexproofAbility.getInstance(), AttachmentType.AURA, Duration.WhileOnBattlefield)); ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(HexproofAbility.getInstance(), AttachmentType.AURA, Duration.WhileOnBattlefield));
Effect effect = new CantBeBlockedByMoreThanOneAttachedEffect(AttachmentType.AURA,1); Effect effect = new CantBeBlockedByMoreThanOneAttachedEffect(AttachmentType.AURA, 1);
effect.setText("and can't be blocked by more than one creature"); effect.setText("and can't be blocked by more than one creature");
ability.addEffect(effect); ability.addEffect(effect);
this.addAbility(ability); this.addAbility(ability);
@ -95,7 +94,7 @@ class CantBeBlockedByMoreThanOneAttachedEffect extends ContinuousEffectImpl {
super(duration, Outcome.Benefit); super(duration, Outcome.Benefit);
this.amount = amount; this.amount = amount;
this.attachmentType = attachmentType; this.attachmentType = attachmentType;
staticText = (attachmentType == AttachmentType.AURA ? "Enchanted" : "Equipped") + " creature can't be blocked by more than " + CardUtil.numberToText(amount) + " creature" + (amount==1 ?"":"s"); staticText = attachmentType.verb() + " creature can't be blocked by more than " + CardUtil.numberToText(amount) + " creature" + (amount == 1 ? "" : "s");
} }
public CantBeBlockedByMoreThanOneAttachedEffect(final CantBeBlockedByMoreThanOneAttachedEffect effect) { public CantBeBlockedByMoreThanOneAttachedEffect(final CantBeBlockedByMoreThanOneAttachedEffect effect) {

View file

@ -137,7 +137,7 @@ class AngelicArbiterCantAttackTargetEffect extends RestrictionEffect {
@Override @Override
public boolean applies(Permanent permanent, Ability source, Game game) { public boolean applies(Permanent permanent, Ability source, Game game) {
if (game.getActivePlayerId().equals(permanent.getControllerId()) && game.getOpponents(source.getControllerId()).contains(permanent.getControllerId())) { if (game.getActivePlayerId().equals(permanent.getControllerId()) && game.getOpponents(source.getControllerId()).contains(permanent.getControllerId())) {
CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getName()); CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getSimpleName());
if (watcher != null && watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(permanent.getControllerId()) > 0) { if (watcher != null && watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(permanent.getControllerId()) > 0) {
return true; return true;
} }
@ -185,7 +185,7 @@ class AngelicArbiterEffect2 extends ContinuousRuleModifyingEffectImpl {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (game.getActivePlayerId().equals(event.getPlayerId()) && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { if (game.getActivePlayerId().equals(event.getPlayerId()) && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
AngelicArbiterWatcher2 watcher = (AngelicArbiterWatcher2) game.getState().getWatchers().get("PlayerAttacked"); AngelicArbiterWatcher2 watcher = (AngelicArbiterWatcher2) game.getState().getWatchers().get(AngelicArbiterWatcher2.class.getSimpleName());
if (watcher != null && watcher.hasPlayerAttackedThisTurn(event.getPlayerId())) { if (watcher != null && watcher.hasPlayerAttackedThisTurn(event.getPlayerId())) {
return true; return true;
} }

View file

@ -97,7 +97,7 @@ class AngelsTrumpetTapEffect extends OneShotEffect {
continue; continue;
} }
// Creatures that attacked are safe. // Creatures that attacked are safe.
AttackedThisTurnWatcher watcher = (AttackedThisTurnWatcher) game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getName()); AttackedThisTurnWatcher watcher = (AttackedThisTurnWatcher) game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getSimpleName());
if (watcher != null && watcher.getAttackedThisTurnCreatures().contains(new MageObjectReference(creature, game))) { if (watcher != null && watcher.getAttackedThisTurnCreatures().contains(new MageObjectReference(creature, game))) {
continue; continue;
} }

View file

@ -62,7 +62,7 @@ class ApproachOfTheSecondSunEffect extends OneShotEffect {
Spell spell = game.getStack().getSpell(source.getSourceId()); Spell spell = game.getStack().getSpell(source.getSourceId());
if (controller != null && spell != null) { if (controller != null && spell != null) {
ApproachOfTheSecondSunWatcher watcher ApproachOfTheSecondSunWatcher watcher
= (ApproachOfTheSecondSunWatcher) game.getState().getWatchers().get(ApproachOfTheSecondSunWatcher.class.getName()); = (ApproachOfTheSecondSunWatcher) game.getState().getWatchers().get(ApproachOfTheSecondSunWatcher.class.getSimpleName());
if (watcher != null && watcher.getApproachesCast(controller.getId()) > 1 && spell.getFromZone() == Zone.HAND) { if (watcher != null && watcher.getApproachesCast(controller.getId()) > 1 && spell.getFromZone() == Zone.HAND) {
// Win the game // Win the game
controller.won(game); controller.won(game);
@ -109,7 +109,7 @@ class ApproachOfTheSecondSunWatcher extends Watcher {
private Map<UUID, Integer> approachesCast = new HashMap<>(); private Map<UUID, Integer> approachesCast = new HashMap<>();
public ApproachOfTheSecondSunWatcher() { public ApproachOfTheSecondSunWatcher() {
super(ApproachOfTheSecondSunWatcher.class.getName(), WatcherScope.GAME); super(ApproachOfTheSecondSunWatcher.class.getSimpleName(), WatcherScope.GAME);
} }
public ApproachOfTheSecondSunWatcher(final ApproachOfTheSecondSunWatcher watcher) { public ApproachOfTheSecondSunWatcher(final ApproachOfTheSecondSunWatcher watcher) {

View file

@ -58,7 +58,7 @@ public class ArchiveTrap extends CardImpl {
this.subtype.add("Trap"); this.subtype.add("Trap");
// If an opponent searched his or her library this turn, you may pay {0} rather than pay Archive Trap's mana cost. // If an opponent searched his or her library this turn, you may pay {0} rather than pay Archive Trap's mana cost.
this.addAbility(new AlternativeCostSourceAbility(new GenericManaCost(0), OpponentSearchesLibCondition.getInstance()), new ArchiveTrapWatcher()); this.addAbility(new AlternativeCostSourceAbility(new GenericManaCost(0), OpponentSearchesLibCondition.instance), new ArchiveTrapWatcher());
// Target opponent puts the top thirteen cards of his or her library into his or her graveyard. // Target opponent puts the top thirteen cards of his or her library into his or her graveyard.
this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addTarget(new TargetOpponent());
@ -80,7 +80,7 @@ class ArchiveTrapWatcher extends Watcher {
Set<UUID> playerIds = new HashSet<>(); Set<UUID> playerIds = new HashSet<>();
public ArchiveTrapWatcher() { public ArchiveTrapWatcher() {
super("LibrarySearched", WatcherScope.GAME); super(ArchiveTrapWatcher.class.getSimpleName(), WatcherScope.GAME);
} }
public ArchiveTrapWatcher(final ArchiveTrapWatcher watcher) { public ArchiveTrapWatcher(final ArchiveTrapWatcher watcher) {
@ -112,17 +112,13 @@ class ArchiveTrapWatcher extends Watcher {
} }
} }
class OpponentSearchesLibCondition implements Condition { enum OpponentSearchesLibCondition implements Condition {
private static final OpponentSearchesLibCondition instance = new OpponentSearchesLibCondition(); instance;
public static Condition getInstance() {
return instance;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
ArchiveTrapWatcher watcher = (ArchiveTrapWatcher) game.getState().getWatchers().get("LibrarySearched"); ArchiveTrapWatcher watcher = (ArchiveTrapWatcher) game.getState().getWatchers().get(ArchiveTrapWatcher.class.getSimpleName());
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null && watcher != null) { if (controller != null && watcher != null) {
for (UUID playerId : watcher.getPlayersSearchedLibrary()) { for (UUID playerId : watcher.getPlayersSearchedLibrary()) {

View file

@ -102,7 +102,7 @@ class ArchmageAscensionTriggeredAbility extends TriggeredAbilityImpl {
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
Permanent archmage = game.getPermanent(super.getSourceId()); Permanent archmage = game.getPermanent(super.getSourceId());
CardsAmountDrawnThisTurnWatcher watcher = CardsAmountDrawnThisTurnWatcher watcher =
(CardsAmountDrawnThisTurnWatcher) game.getState().getWatchers().get(CardsAmountDrawnThisTurnWatcher.BASIC_KEY); (CardsAmountDrawnThisTurnWatcher) game.getState().getWatchers().get(CardsAmountDrawnThisTurnWatcher.class.getSimpleName());
return archmage != null && watcher != null && watcher.getAmountCardsDrawn(this.getControllerId()) >= 2; return archmage != null && watcher != null && watcher.getAmountCardsDrawn(this.getControllerId()) >= 2;
} }

View file

@ -47,11 +47,11 @@ import java.util.UUID;
public class ArrowVolleyTrap extends CardImpl { public class ArrowVolleyTrap extends CardImpl {
public ArrowVolleyTrap(UUID ownerId, CardSetInfo setInfo) { public ArrowVolleyTrap(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{W}{W}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{W}{W}");
this.subtype.add("Trap"); this.subtype.add("Trap");
// If four or more creatures are attacking, you may pay {1}{W} rather than pay Arrow Volley Trap's mana cost. // If four or more creatures are attacking, you may pay {1}{W} rather than pay Arrow Volley Trap's mana cost.
this.addAbility(new AlternativeCostSourceAbility(new ManaCostsImpl("{1}{W}"), ArrowVolleyTrapCondition.getInstance())); this.addAbility(new AlternativeCostSourceAbility(new ManaCostsImpl("{1}{W}"), ArrowVolleyTrapCondition.instance));
// Arrow Volley Trap deals 5 damage divided as you choose among any number of target attacking creatures. // Arrow Volley Trap deals 5 damage divided as you choose among any number of target attacking creatures.
this.getSpellAbility().addEffect(new DamageMultiEffect(5)); this.getSpellAbility().addEffect(new DamageMultiEffect(5));
@ -69,13 +69,9 @@ public class ArrowVolleyTrap extends CardImpl {
} }
} }
class ArrowVolleyTrapCondition implements Condition { enum ArrowVolleyTrapCondition implements Condition {
private static final ArrowVolleyTrapCondition instance = new ArrowVolleyTrapCondition(); instance;
public static Condition getInstance() {
return instance;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {

View file

@ -83,7 +83,7 @@ class AsmiraHolyAvengerWatcher extends Watcher {
private int creaturesCount = 0; private int creaturesCount = 0;
public AsmiraHolyAvengerWatcher() { public AsmiraHolyAvengerWatcher() {
super("YourCreaturesDied", WatcherScope.PLAYER); super(AsmiraHolyAvengerWatcher.class.getSimpleName(), WatcherScope.PLAYER);
condition = true; condition = true;
} }
@ -122,7 +122,7 @@ class AsmiraHolyAvengerDynamicValue implements DynamicValue {
@Override @Override
public int calculate(Game game, Ability sourceAbility, Effect effect) { public int calculate(Game game, Ability sourceAbility, Effect effect) {
AsmiraHolyAvengerWatcher watcher = (AsmiraHolyAvengerWatcher) game.getState().getWatchers().get("YourCreaturesDied", sourceAbility.getControllerId()); AsmiraHolyAvengerWatcher watcher = (AsmiraHolyAvengerWatcher) game.getState().getWatchers().get(AsmiraHolyAvengerWatcher.class.getSimpleName(), sourceAbility.getControllerId());
if (watcher != null) { if (watcher != null) {
return watcher.getCreaturesCount(); return watcher.getCreaturesCount();
} }

View file

@ -52,28 +52,26 @@ import mage.target.common.TargetCreatureOrPlayerAmount;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.watchers.Watcher; import mage.watchers.Watcher;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.UUID;
/** /**
* GATECRASH FAQ 11.01.2013 * GATECRASH FAQ 11.01.2013
* * <p>
* You announce the value of X and how the damage will be divided as part of * You announce the value of X and how the damage will be divided as part of
* casting Aurelia's Fury. Each chosen target must receive at least 1 damage. * casting Aurelia's Fury. Each chosen target must receive at least 1 damage.
* * <p>
* Aurelia's Fury can't deal damage to both a planeswalker and that * Aurelia's Fury can't deal damage to both a planeswalker and that
* planeswalker's controller. If damage dealt by Aurelia's Fury is redirected * planeswalker's controller. If damage dealt by Aurelia's Fury is redirected
* from a player to a planeswalker he or she controls, that player will be able * from a player to a planeswalker he or she controls, that player will be able
* to cast noncreature spells that turn. If you want to stop a player from * to cast noncreature spells that turn. If you want to stop a player from
* casting noncreature spells this turn, you can't choose to redirect the * casting noncreature spells this turn, you can't choose to redirect the
* damage to a planeswalker he or she controls. * damage to a planeswalker he or she controls.
* * <p>
* If Aurelia's Fury has multiple targets, and some but not all of them are * If Aurelia's Fury has multiple targets, and some but not all of them are
* illegal targets when Aurelia's Fury resolves, Aurelia's Fury will still * illegal targets when Aurelia's Fury resolves, Aurelia's Fury will still
* deal damage to the remaining legal targets according to the original damage * deal damage to the remaining legal targets according to the original damage
* division. * division.
* * <p>
* If all of the targets are illegal when Aurelia's Fury tries to resolve, * If all of the targets are illegal when Aurelia's Fury tries to resolve,
* it will be countered and none of its effects will happen. No creature or * it will be countered and none of its effects will happen. No creature or
* player will be dealt damage. * player will be dealt damage.
@ -83,7 +81,7 @@ import java.util.UUID;
public class AureliasFury extends CardImpl { public class AureliasFury extends CardImpl {
public AureliasFury(UUID ownerId, CardSetInfo setInfo) { public AureliasFury(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{R}{W}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{R}{W}");
// Aurelia's Fury deals X damage divided as you choose among any number of target creatures and/or players. // Aurelia's Fury deals X damage divided as you choose among any number of target creatures and/or players.
@ -107,39 +105,39 @@ public class AureliasFury extends CardImpl {
} }
class AureliasFuryEffect extends OneShotEffect { class AureliasFuryEffect extends OneShotEffect {
public AureliasFuryEffect() { public AureliasFuryEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
this.staticText = "Tap each creature dealt damage this way. Players dealt damage this way can't cast noncreature spells this turn"; this.staticText = "Tap each creature dealt damage this way. Players dealt damage this way can't cast noncreature spells this turn";
} }
public AureliasFuryEffect(final AureliasFuryEffect effect) { public AureliasFuryEffect(final AureliasFuryEffect effect) {
super(effect); super(effect);
} }
@Override @Override
public AureliasFuryEffect copy() { public AureliasFuryEffect copy() {
return new AureliasFuryEffect(this); return new AureliasFuryEffect(this);
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
AureliasFuryDamagedByWatcher watcher = (AureliasFuryDamagedByWatcher) game.getState().getWatchers().get("AureliasFuryDamagedByWatcher", source.getSourceId()); AureliasFuryDamagedByWatcher watcher = (AureliasFuryDamagedByWatcher) game.getState().getWatchers().get(AureliasFuryDamagedByWatcher.class.getSimpleName(), source.getSourceId());
if (watcher != null) { if (watcher != null) {
for(UUID creatureId : watcher.damagedCreatures) { for (UUID creatureId : watcher.damagedCreatures) {
Permanent permanent = game.getPermanent(creatureId); Permanent permanent = game.getPermanent(creatureId);
if (permanent != null) { if (permanent != null) {
permanent.tap(game); permanent.tap(game);
} }
} }
for(UUID playerId : watcher.damagedPlayers) { for (UUID playerId : watcher.damagedPlayers) {
ContinuousEffect effect = new AureliasFuryCantCastEffect(); ContinuousEffect effect = new AureliasFuryCantCastEffect();
effect.setTargetPointer(new FixedTarget(playerId)); effect.setTargetPointer(new FixedTarget(playerId));
game.addEffect(effect, source); game.addEffect(effect, source);
} }
watcher.reset(); watcher.reset();
} }
return false; return false;
} }
} }
@ -178,7 +176,7 @@ class AureliasFuryCantCastEffect extends ContinuousRuleModifyingEffectImpl {
public boolean checksEventType(GameEvent event, Game game) { public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.CAST_SPELL; return event.getType() == GameEvent.EventType.CAST_SPELL;
} }
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
@ -194,11 +192,11 @@ class AureliasFuryCantCastEffect extends ContinuousRuleModifyingEffectImpl {
class AureliasFuryDamagedByWatcher extends Watcher { class AureliasFuryDamagedByWatcher extends Watcher {
public List<UUID> damagedCreatures = new ArrayList<>(); public Set<UUID> damagedCreatures = new HashSet<>();
public List<UUID> damagedPlayers = new ArrayList<>(); public Set<UUID> damagedPlayers = new HashSet<>();
public AureliasFuryDamagedByWatcher() { public AureliasFuryDamagedByWatcher() {
super("AureliasFuryDamagedByWatcher", WatcherScope.CARD); super(AureliasFuryDamagedByWatcher.class.getSimpleName(), WatcherScope.CARD);
} }
public AureliasFuryDamagedByWatcher(final AureliasFuryDamagedByWatcher watcher) { public AureliasFuryDamagedByWatcher(final AureliasFuryDamagedByWatcher watcher) {
@ -217,7 +215,7 @@ class AureliasFuryDamagedByWatcher extends Watcher {
if (event.getType() == EventType.DAMAGED_CREATURE) { if (event.getType() == EventType.DAMAGED_CREATURE) {
MageObject obj = game.getObject(event.getSourceId()); MageObject obj = game.getObject(event.getSourceId());
if (obj instanceof Spell) { if (obj instanceof Spell) {
if (sourceId.equals(((Spell) obj).getSourceId()) && !damagedCreatures.contains(event.getTargetId())) { if (sourceId.equals(((Spell) obj).getSourceId())) {
damagedCreatures.add(event.getTargetId()); damagedCreatures.add(event.getTargetId());
} }
} }
@ -225,7 +223,7 @@ class AureliasFuryDamagedByWatcher extends Watcher {
if (event.getType() == EventType.DAMAGED_PLAYER) { if (event.getType() == EventType.DAMAGED_PLAYER) {
MageObject obj = game.getObject(event.getSourceId()); MageObject obj = game.getObject(event.getSourceId());
if (obj instanceof Spell) { if (obj instanceof Spell) {
if (sourceId.equals(((Spell) obj).getSourceId()) && !damagedPlayers.contains(event.getTargetId())) { if (sourceId.equals(((Spell) obj).getSourceId())) {
damagedPlayers.add(event.getTargetId()); damagedPlayers.add(event.getTargetId());
} }
} }

View file

@ -81,7 +81,7 @@ class AvengingArrowTarget extends TargetPermanent {
@Override @Override
public boolean canTarget(UUID id, Ability source, Game game) { public boolean canTarget(UUID id, Ability source, Game game) {
SourceDidDamageWatcher watcher = (SourceDidDamageWatcher) game.getState().getWatchers().get("SourceDidDamageWatcher"); SourceDidDamageWatcher watcher = (SourceDidDamageWatcher) game.getState().getWatchers().get(SourceDidDamageWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
if (watcher.damageSources.contains(id)) { if (watcher.damageSources.contains(id)) {
return super.canTarget(id, source, game); return super.canTarget(id, source, game);
@ -94,7 +94,7 @@ class AvengingArrowTarget extends TargetPermanent {
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
Set<UUID> availablePossibleTargets = super.possibleTargets(sourceId, sourceControllerId, game); Set<UUID> availablePossibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
Set<UUID> possibleTargets = new HashSet<>(); Set<UUID> possibleTargets = new HashSet<>();
SourceDidDamageWatcher watcher = (SourceDidDamageWatcher) game.getState().getWatchers().get("SourceDidDamageWatcher"); SourceDidDamageWatcher watcher = (SourceDidDamageWatcher) game.getState().getWatchers().get(SourceDidDamageWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
for (UUID targetId : availablePossibleTargets) { for (UUID targetId : availablePossibleTargets) {
Permanent permanent = game.getPermanent(targetId); Permanent permanent = game.getPermanent(targetId);

View file

@ -44,17 +44,16 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public class BalothCageTrap extends CardImpl { public class BalothCageTrap extends CardImpl {
public BalothCageTrap(UUID ownerId, CardSetInfo setInfo) { public BalothCageTrap(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{G}{G}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{G}{G}");
this.subtype.add("Trap"); this.subtype.add("Trap");
// If an opponent had an artifact enter the battlefield under his or her control this turn, you may pay {1}{G} rather than pay Baloth Cage Trap's mana cost. // If an opponent had an artifact enter the battlefield under his or her control this turn, you may pay {1}{G} rather than pay Baloth Cage Trap's mana cost.
this.addAbility(new AlternativeCostSourceAbility(new ManaCostsImpl("{1}{G}"), BalothCageTrapCondition.getInstance()), new PermanentsEnteredBattlefieldWatcher()); this.addAbility(new AlternativeCostSourceAbility(new ManaCostsImpl("{1}{G}"), BalothCageTrapCondition.instance), new PermanentsEnteredBattlefieldWatcher());
// Create a 4/4 green Beast creature token. // Create a 4/4 green Beast creature token.
this.getSpellAbility().addEffect(new CreateTokenEffect(new BeastToken2())); this.getSpellAbility().addEffect(new CreateTokenEffect(new BeastToken2()));
@ -70,17 +69,13 @@ public class BalothCageTrap extends CardImpl {
} }
} }
class BalothCageTrapCondition implements Condition { enum BalothCageTrapCondition implements Condition {
private static final BalothCageTrapCondition instance = new BalothCageTrapCondition(); instance;
public static Condition getInstance() {
return instance;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
PermanentsEnteredBattlefieldWatcher watcher = (PermanentsEnteredBattlefieldWatcher) game.getState().getWatchers().get(PermanentsEnteredBattlefieldWatcher.class.getName()); PermanentsEnteredBattlefieldWatcher watcher = (PermanentsEnteredBattlefieldWatcher) game.getState().getWatchers().get(PermanentsEnteredBattlefieldWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
for (UUID opponentId : game.getOpponents(source.getControllerId())) { for (UUID opponentId : game.getOpponents(source.getControllerId())) {
List<Permanent> permanents = watcher.getThisTurnEnteringPermanents(opponentId); List<Permanent> permanents = watcher.getThisTurnEnteringPermanents(opponentId);

View file

@ -102,7 +102,7 @@ class BerserkReplacementEffect extends ContinuousRuleModifyingEffectImpl {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.CAST_SPELL && event.getSourceId().equals(source.getSourceId())) { if (event.getType() == GameEvent.EventType.CAST_SPELL && event.getSourceId().equals(source.getSourceId())) {
CombatDamageStepStartedWatcher watcher = (CombatDamageStepStartedWatcher) game.getState().getWatchers().get("CombatDamageStepStarted"); CombatDamageStepStartedWatcher watcher = (CombatDamageStepStartedWatcher) game.getState().getWatchers().get(CombatDamageStepStartedWatcher.class.getSimpleName());
return watcher == null || watcher.conditionMet(); return watcher == null || watcher.conditionMet();
} }
return false; return false;
@ -122,7 +122,7 @@ class BerserkReplacementEffect extends ContinuousRuleModifyingEffectImpl {
class CombatDamageStepStartedWatcher extends Watcher { class CombatDamageStepStartedWatcher extends Watcher {
public CombatDamageStepStartedWatcher() { public CombatDamageStepStartedWatcher() {
super("CombatDamageStepStarted", WatcherScope.GAME); super(CombatDamageStepStartedWatcher.class.getSimpleName(), WatcherScope.GAME);
} }
public CombatDamageStepStartedWatcher(final CombatDamageStepStartedWatcher watcher) { public CombatDamageStepStartedWatcher(final CombatDamageStepStartedWatcher watcher) {
@ -196,7 +196,7 @@ class BerserkDelayedDestroyEffect extends OneShotEffect {
if (controller != null) { if (controller != null) {
Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if (permanent != null) { if (permanent != null) {
Watcher watcher = game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getName()); Watcher watcher = game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getSimpleName());
if (watcher != null && watcher instanceof AttackedThisTurnWatcher) { if (watcher != null && watcher instanceof AttackedThisTurnWatcher) {
if (((AttackedThisTurnWatcher) watcher).getAttackedThisTurnCreatures().contains(new MageObjectReference(permanent, game))) { if (((AttackedThisTurnWatcher) watcher).getAttackedThisTurnCreatures().contains(new MageObjectReference(permanent, game))) {
return permanent.destroy(source.getSourceId(), game, false); return permanent.destroy(source.getSourceId(), game, false);

View file

@ -50,7 +50,6 @@ import mage.target.common.TargetCreaturePermanent;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public class BloodLust extends CardImpl { public class BloodLust extends CardImpl {
@ -62,12 +61,12 @@ public class BloodLust extends CardImpl {
} }
public BloodLust(UUID ownerId, CardSetInfo setInfo) { public BloodLust(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}");
// If target creature has toughness 5 or greater, it gets +4/-4 until end of turn. Otherwise, it gets +4/-X until end of turn, where X is its toughness minus 1. // If target creature has toughness 5 or greater, it gets +4/-4 until end of turn. Otherwise, it gets +4/-X until end of turn, where X is its toughness minus 1.
this.getSpellAbility().addEffect(new ConditionalContinuousEffect( this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
new BoostTargetEffect(4, -4, Duration.EndOfTurn), new BoostTargetEffect(4, -4, Duration.EndOfTurn),
new BoostTargetEffect(new StaticValue(4), new SignInversionDynamicValue(new TargetPermanentToughnessMinus1Value()), Duration.WhileOnBattlefield), new BoostTargetEffect(new StaticValue(4), new SignInversionDynamicValue(TargetPermanentToughnessMinus1Value.instance), Duration.WhileOnBattlefield),
new TargetMatchesFilterCondition(filter), new TargetMatchesFilterCondition(filter),
"If target creature has toughness 5 or greater, it gets +4/-4 until end of turn. Otherwise, it gets +4/-X until end of turn, where X is its toughness minus 1")); "If target creature has toughness 5 or greater, it gets +4/-4 until end of turn. Otherwise, it gets +4/-X until end of turn, where X is its toughness minus 1"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addTarget(new TargetCreaturePermanent());
@ -104,13 +103,9 @@ class TargetMatchesFilterCondition implements Condition {
} }
} }
class TargetPermanentToughnessMinus1Value implements DynamicValue { enum TargetPermanentToughnessMinus1Value implements DynamicValue {
private static final TargetPermanentToughnessMinus1Value instance = new TargetPermanentToughnessMinus1Value(); instance;
public static TargetPermanentToughnessMinus1Value getInstance() {
return instance;
}
@Override @Override
public int calculate(Game game, Ability sourceAbility, Effect effect) { public int calculate(Game game, Ability sourceAbility, Effect effect) {
@ -123,7 +118,7 @@ class TargetPermanentToughnessMinus1Value implements DynamicValue {
@Override @Override
public TargetPermanentToughnessMinus1Value copy() { public TargetPermanentToughnessMinus1Value copy() {
return new TargetPermanentToughnessMinus1Value(); return instance;
} }
@Override @Override

View file

@ -96,7 +96,7 @@ class BloodcrazedGoblinEffect extends RestrictionEffect {
@Override @Override
public boolean applies(Permanent permanent, Ability source, Game game) { public boolean applies(Permanent permanent, Ability source, Game game) {
if (permanent.getId().equals(source.getSourceId())) { if (permanent.getId().equals(source.getSourceId())) {
BloodthirstWatcher watcher = (BloodthirstWatcher) game.getState().getWatchers().get("DamagedOpponents", source.getControllerId()); // BloodthirstWatcher BloodthirstWatcher watcher = (BloodthirstWatcher) game.getState().getWatchers().get(BloodthirstWatcher.class.getSimpleName(), source.getControllerId()); // BloodthirstWatcher
return !watcher.conditionMet(); return !watcher.conditionMet();
} }
return false; return false;

View file

@ -134,7 +134,7 @@ class BontuTheGlorifiedRestrictionEffect extends RestrictionEffect {
public boolean applies(Permanent permanent, Ability source, Game game) { public boolean applies(Permanent permanent, Ability source, Game game) {
if (permanent.getId().equals(source.getSourceId())) { if (permanent.getId().equals(source.getSourceId())) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
CreaturesDiedWatcher watcher = (CreaturesDiedWatcher) game.getState().getWatchers().get("CreaturesDiedWatcher"); CreaturesDiedWatcher watcher = (CreaturesDiedWatcher) game.getState().getWatchers().get(CreaturesDiedWatcher.class.getSimpleName());
if (controller != null if (controller != null
&& watcher != null) { && watcher != null) {
return (watcher.getAmountOfCreaturesDiesThisTurn(controller.getId()) == 0); return (watcher.getAmountOfCreaturesDiesThisTurn(controller.getId()) == 0);

View file

@ -89,7 +89,7 @@ class BoseijuWhoSheltersAllWatcher extends Watcher {
public List<UUID> spells = new ArrayList<>(); public List<UUID> spells = new ArrayList<>();
public BoseijuWhoSheltersAllWatcher() { public BoseijuWhoSheltersAllWatcher() {
super("ManaPaidFromBoseijuWhoSheltersAllWatcher", WatcherScope.GAME); super(BoseijuWhoSheltersAllWatcher.class.getSimpleName(), WatcherScope.GAME);
} }
public BoseijuWhoSheltersAllWatcher(final BoseijuWhoSheltersAllWatcher watcher) { public BoseijuWhoSheltersAllWatcher(final BoseijuWhoSheltersAllWatcher watcher) {
@ -158,7 +158,7 @@ class BoseijuWhoSheltersAllCantCounterEffect extends ContinuousRuleModifyingEffe
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
BoseijuWhoSheltersAllWatcher watcher = (BoseijuWhoSheltersAllWatcher) game.getState().getWatchers().get("ManaPaidFromBoseijuWhoSheltersAllWatcher"); BoseijuWhoSheltersAllWatcher watcher = (BoseijuWhoSheltersAllWatcher) game.getState().getWatchers().get(BoseijuWhoSheltersAllWatcher.class.getSimpleName());
Spell spell = game.getStack().getSpell(event.getTargetId()); Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell != null && watcher.spells.contains(spell.getId())) { if (spell != null && watcher.spells.contains(spell.getId())) {
if (filter.match(spell.getCard(), game)) { if (filter.match(spell.getCard(), game)) {

View file

@ -48,13 +48,12 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public class BriarbridgePatrol extends CardImpl { public class BriarbridgePatrol extends CardImpl {
public BriarbridgePatrol(UUID ownerId, CardSetInfo setInfo) { public BriarbridgePatrol(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.subtype.add("Human"); this.subtype.add("Human");
this.subtype.add("Warrior"); this.subtype.add("Warrior");
this.power = new MageInt(3); this.power = new MageInt(3);
@ -64,7 +63,7 @@ public class BriarbridgePatrol extends CardImpl {
this.addAbility(new DealsDamageToOneOrMoreCreaturesTriggeredAbility(new InvestigateEffect(), false, false, false)); this.addAbility(new DealsDamageToOneOrMoreCreaturesTriggeredAbility(new InvestigateEffect(), false, false, false));
// At the beginning of each end step, if you sacrificed three or more Clues this turn, you may put a creature card from your hand onto the battlefield. // At the beginning of each end step, if you sacrificed three or more Clues this turn, you may put a creature card from your hand onto the battlefield.
this.addAbility(new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new PutPermanentOnBattlefieldEffect(new FilterCreatureCard("a creature card")), TargetController.ANY, this.addAbility(new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new PutPermanentOnBattlefieldEffect(new FilterCreatureCard("a creature card")), TargetController.ANY,
BriarbridgePatrolCondition.getInstance(), true), new PermanentsSacrificedWatcher()); BriarbridgePatrolCondition.instance, true), new PermanentsSacrificedWatcher());
} }
@ -78,17 +77,13 @@ public class BriarbridgePatrol extends CardImpl {
} }
} }
class BriarbridgePatrolCondition implements Condition { enum BriarbridgePatrolCondition implements Condition {
private static final BriarbridgePatrolCondition instance = new BriarbridgePatrolCondition(); instance;
public static Condition getInstance() {
return instance;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
PermanentsSacrificedWatcher watcher = (PermanentsSacrificedWatcher) game.getState().getWatchers().get(PermanentsSacrificedWatcher.class.getName()); PermanentsSacrificedWatcher watcher = (PermanentsSacrificedWatcher) game.getState().getWatchers().get(PermanentsSacrificedWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
List<Permanent> sacrificedPermanents = watcher.getThisTurnSacrificedPermanents(source.getControllerId()); List<Permanent> sacrificedPermanents = watcher.getThisTurnSacrificedPermanents(source.getControllerId());
if (sacrificedPermanents != null && !sacrificedPermanents.isEmpty()) { if (sacrificedPermanents != null && !sacrificedPermanents.isEmpty()) {
@ -109,4 +104,4 @@ class BriarbridgePatrolCondition implements Condition {
return "if you sacrificed three or more Clues this turn"; return "if you sacrificed three or more Clues this turn";
} }
} }

View file

@ -38,6 +38,7 @@ import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCreatureOrPlayer; import mage.target.common.TargetCreatureOrPlayer;
import mage.watchers.Watcher; import mage.watchers.Watcher;
import mage.watchers.common.MorbidWatcher;
import java.util.UUID; import java.util.UUID;
@ -80,7 +81,7 @@ class BrimstoneVolleyEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
int damage = 3; int damage = 3;
Watcher watcher = game.getState().getWatchers().get("Morbid"); Watcher watcher = game.getState().getWatchers().get(MorbidWatcher.class.getSimpleName());
if (watcher.conditionMet()) { if (watcher.conditionMet()) {
damage = 5; damage = 5;
} }

View file

@ -86,7 +86,7 @@ class CallerOfTheClawWatcher extends Watcher {
private int creaturesCount = 0; private int creaturesCount = 0;
public CallerOfTheClawWatcher() { public CallerOfTheClawWatcher() {
super(CallerOfTheClawWatcher.class.getName(), WatcherScope.PLAYER); super(CallerOfTheClawWatcher.class.getSimpleName(), WatcherScope.PLAYER);
condition = true; condition = true;
} }
@ -140,7 +140,7 @@ class CallerOfTheClawDynamicValue implements DynamicValue {
@Override @Override
public int calculate(Game game, Ability sourceAbility, Effect effect) { public int calculate(Game game, Ability sourceAbility, Effect effect) {
CallerOfTheClawWatcher watcher = (CallerOfTheClawWatcher) game.getState().getWatchers().get(CallerOfTheClawWatcher.class.getName(), sourceAbility.getControllerId()); CallerOfTheClawWatcher watcher = (CallerOfTheClawWatcher) game.getState().getWatchers().get(CallerOfTheClawWatcher.class.getSimpleName(), sourceAbility.getControllerId());
if (watcher != null) { if (watcher != null) {
return watcher.getCreaturesCount(); return watcher.getCreaturesCount();
} }

View file

@ -40,18 +40,15 @@ import mage.game.events.GameEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.watchers.Watcher; import mage.watchers.Watcher;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.UUID;
/** /**
*
* @author BetaSteward * @author BetaSteward
*/ */
public class CathedralMembrane extends CardImpl { public class CathedralMembrane extends CardImpl {
public CathedralMembrane(UUID ownerId, CardSetInfo setInfo) { public CathedralMembrane(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{1}{W/P}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{W/P}");
this.subtype.add("Wall"); this.subtype.add("Wall");
this.power = new MageInt(0); this.power = new MageInt(0);
@ -94,7 +91,7 @@ class CathedralMembraneAbility extends ZoneChangeTriggeredAbility {
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
if (super.checkTrigger(event, game)) { if (super.checkTrigger(event, game)) {
if (game.getPhase().getType() == TurnPhase.COMBAT) { if (game.getPhase().getType() == TurnPhase.COMBAT) {
return true; return true;
} }
} }
return false; return false;
@ -120,7 +117,7 @@ class CathedralMembraneEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
CathedralMembraneWatcher watcher = (CathedralMembraneWatcher) game.getState().getWatchers().get("CathedralMembraneWatcher", source.getSourceId()); CathedralMembraneWatcher watcher = (CathedralMembraneWatcher) game.getState().getWatchers().get(CathedralMembraneWatcher.class.getSimpleName(), source.getSourceId());
if (watcher != null) { if (watcher != null) {
for (UUID uuid : watcher.blockedCreatures) { for (UUID uuid : watcher.blockedCreatures) {
Permanent permanent = game.getPermanent(uuid); Permanent permanent = game.getPermanent(uuid);
@ -135,10 +132,10 @@ class CathedralMembraneEffect extends OneShotEffect {
class CathedralMembraneWatcher extends Watcher { class CathedralMembraneWatcher extends Watcher {
public List<UUID> blockedCreatures = new ArrayList<>(); public Set<UUID> blockedCreatures = new HashSet<>();
public CathedralMembraneWatcher() { public CathedralMembraneWatcher() {
super("CathedralMembraneWatcher", WatcherScope.CARD); super(CathedralMembraneWatcher.class.getSimpleName(), WatcherScope.CARD);
} }
public CathedralMembraneWatcher(final CathedralMembraneWatcher watcher) { public CathedralMembraneWatcher(final CathedralMembraneWatcher watcher) {
@ -154,9 +151,7 @@ class CathedralMembraneWatcher extends Watcher {
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.BLOCKER_DECLARED && event.getSourceId().equals(sourceId)) { if (event.getType() == GameEvent.EventType.BLOCKER_DECLARED && event.getSourceId().equals(sourceId)) {
if (!blockedCreatures.contains(event.getTargetId())) { blockedCreatures.add(event.getTargetId());
blockedCreatures.add(event.getTargetId());
}
} }
} }

View file

@ -152,7 +152,7 @@ class CavernOfSoulsWatcher extends Watcher {
private final String originalId; private final String originalId;
public CavernOfSoulsWatcher(UUID originalId) { public CavernOfSoulsWatcher(UUID originalId) {
super("ManaPaidFromCavernOfSoulsWatcher", WatcherScope.CARD); super(CavernOfSoulsWatcher.class.getSimpleName(), WatcherScope.CARD);
this.originalId = originalId.toString(); this.originalId = originalId.toString();
} }
@ -224,7 +224,7 @@ class CavernOfSoulsCantCounterEffect extends ContinuousRuleModifyingEffectImpl {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
CavernOfSoulsWatcher watcher = (CavernOfSoulsWatcher) game.getState().getWatchers().get("ManaPaidFromCavernOfSoulsWatcher", source.getSourceId()); CavernOfSoulsWatcher watcher = (CavernOfSoulsWatcher) game.getState().getWatchers().get(CavernOfSoulsWatcher.class.getSimpleName(), source.getSourceId());
Spell spell = game.getStack().getSpell(event.getTargetId()); Spell spell = game.getStack().getSpell(event.getTargetId());
return spell != null && watcher != null && watcher.spellCantBeCountered(spell.getId()); return spell != null && watcher != null && watcher.spellCantBeCountered(spell.getId());
} }

View file

@ -93,7 +93,7 @@ class CerebralVortexEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
if (targetPlayer != null) { if (targetPlayer != null) {
CerebralVortexWatcher watcher = (CerebralVortexWatcher) game.getState().getWatchers().get("CerebralVortexWatcher"); CerebralVortexWatcher watcher = (CerebralVortexWatcher) game.getState().getWatchers().get(CerebralVortexWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
targetPlayer.damage(watcher.getDraws(targetPlayer.getId()), source.getSourceId(), game, false, true); targetPlayer.damage(watcher.getDraws(targetPlayer.getId()), source.getSourceId(), game, false, true);
return true; return true;
@ -108,7 +108,7 @@ class CerebralVortexWatcher extends Watcher {
private final Map<UUID, Integer> draws = new HashMap<>(); private final Map<UUID, Integer> draws = new HashMap<>();
CerebralVortexWatcher() { CerebralVortexWatcher() {
super("CerebralVortexWatcher", WatcherScope.GAME); super(CerebralVortexWatcher.class.getSimpleName(), WatcherScope.GAME);
} }
CerebralVortexWatcher(final CerebralVortexWatcher watcher) { CerebralVortexWatcher(final CerebralVortexWatcher watcher) {
@ -136,10 +136,7 @@ class CerebralVortexWatcher extends Watcher {
} }
public int getDraws(UUID playerId) { public int getDraws(UUID playerId) {
if (draws.containsKey(playerId)) { return draws.getOrDefault(playerId, 0);
return draws.get(playerId);
}
return 0;
} }
@Override @Override

View file

@ -113,7 +113,7 @@ class ChainsOfMephistophelesReplacementEffect extends ReplacementEffectImpl {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (game.getActivePlayerId().equals(event.getPlayerId()) && game.getPhase().getStep().getType() == PhaseStep.DRAW) { if (game.getActivePlayerId().equals(event.getPlayerId()) && game.getPhase().getStep().getType() == PhaseStep.DRAW) {
CardsDrawnDuringDrawStepWatcher watcher = (CardsDrawnDuringDrawStepWatcher) game.getState().getWatchers().get("CardsDrawnDuringDrawStep"); CardsDrawnDuringDrawStepWatcher watcher = (CardsDrawnDuringDrawStepWatcher) game.getState().getWatchers().get(CardsDrawnDuringDrawStepWatcher.class.getSimpleName());
if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) > 0) { if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) > 0) {
return true; return true;
} }

View file

@ -88,8 +88,8 @@ class ChargingCinderhornCondition implements Condition {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
AttackedThisTurnWatcher watcher = (AttackedThisTurnWatcher) game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getName()); AttackedThisTurnWatcher watcher = (AttackedThisTurnWatcher) game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getSimpleName());
if (watcher != null && watcher instanceof AttackedThisTurnWatcher) { if (watcher != null) {
return watcher.getAttackedThisTurnCreatures().isEmpty(); return watcher.getAttackedThisTurnCreatures().isEmpty();
} }
return true; return true;

View file

@ -78,7 +78,7 @@ class SourceControllerLostLifeCount implements DynamicValue {
@Override @Override
public int calculate(Game game, Ability sourceAbility, Effect effect) { public int calculate(Game game, Ability sourceAbility, Effect effect) {
PlayerLostLifeWatcher watcher = (PlayerLostLifeWatcher) game.getState().getWatchers().get("PlayerLostLifeWatcher"); PlayerLostLifeWatcher watcher = (PlayerLostLifeWatcher) game.getState().getWatchers().get(PlayerLostLifeWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
return watcher.getLiveLost(sourceAbility.getControllerId()); return watcher.getLiveLost(sourceAbility.getControllerId());
} }

View file

@ -83,7 +83,7 @@ public class CivilizedScholar extends CardImpl {
class HomicidalBruteWatcher extends Watcher { class HomicidalBruteWatcher extends Watcher {
public HomicidalBruteWatcher() { public HomicidalBruteWatcher() {
super("HomicidalBruteAttacked", WatcherScope.CARD); super(HomicidalBruteWatcher.class.getSimpleName(), WatcherScope.CARD);
} }
public HomicidalBruteWatcher(final HomicidalBruteWatcher watcher) { public HomicidalBruteWatcher(final HomicidalBruteWatcher watcher) {

View file

@ -49,17 +49,16 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author Rafbill * @author Rafbill
*/ */
public class CobraTrap extends CardImpl { public class CobraTrap extends CardImpl {
public CobraTrap(UUID ownerId, CardSetInfo setInfo) { public CobraTrap(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{4}{G}{G}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{G}{G}");
this.subtype.add("Trap"); this.subtype.add("Trap");
// If a noncreature permanent under your control was destroyed this turn by a spell or ability an opponent controlled, you may pay {G} rather than pay Cobra Trap's mana cost. // If a noncreature permanent under your control was destroyed this turn by a spell or ability an opponent controlled, you may pay {G} rather than pay Cobra Trap's mana cost.
this.addAbility(new AlternativeCostSourceAbility(new ManaCostsImpl("{G}"), CobraTrapCondition.getInstance()), new CobraTrapWatcher()); this.addAbility(new AlternativeCostSourceAbility(new ManaCostsImpl("{G}"), CobraTrapCondition.instance), new CobraTrapWatcher());
// Create four 1/1 green Snake creature tokens. // Create four 1/1 green Snake creature tokens.
this.getSpellAbility().addEffect(new CreateTokenEffect(new SnakeToken(), 4)); this.getSpellAbility().addEffect(new CreateTokenEffect(new SnakeToken(), 4));
@ -75,17 +74,13 @@ public class CobraTrap extends CardImpl {
} }
} }
class CobraTrapCondition implements Condition { enum CobraTrapCondition implements Condition {
private static final CobraTrapCondition instance = new CobraTrapCondition(); instance;
public static Condition getInstance() {
return instance;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
CobraTrapWatcher watcher = (CobraTrapWatcher) game.getState().getWatchers().get(CobraTrapWatcher.class.getName()); CobraTrapWatcher watcher = (CobraTrapWatcher) game.getState().getWatchers().get(CobraTrapWatcher.class.getSimpleName());
return watcher != null && watcher.conditionMet(source.getControllerId()); return watcher != null && watcher.conditionMet(source.getControllerId());
} }
@ -101,7 +96,7 @@ class CobraTrapWatcher extends Watcher {
Set<UUID> players = new HashSet<>(); Set<UUID> players = new HashSet<>();
public CobraTrapWatcher() { public CobraTrapWatcher() {
super(CobraTrapWatcher.class.getName(), WatcherScope.GAME); super(CobraTrapWatcher.class.getSimpleName(), WatcherScope.GAME);
} }
public CobraTrapWatcher(final CobraTrapWatcher watcher) { public CobraTrapWatcher(final CobraTrapWatcher watcher) {

View file

@ -56,7 +56,6 @@ import java.util.Map;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public class ConduitOfRuin extends CardImpl { public class ConduitOfRuin extends CardImpl {
@ -71,7 +70,7 @@ public class ConduitOfRuin extends CardImpl {
} }
public ConduitOfRuin(UUID ownerId, CardSetInfo setInfo) { public ConduitOfRuin(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{6}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}");
this.subtype.add("Eldrazi"); this.subtype.add("Eldrazi");
this.power = new MageInt(5); this.power = new MageInt(5);
this.toughness = new MageInt(5); this.toughness = new MageInt(5);
@ -102,7 +101,7 @@ class ConduitOfRuinWatcher extends Watcher {
int spellCount = 0; int spellCount = 0;
public ConduitOfRuinWatcher() { public ConduitOfRuinWatcher() {
super("FirstCreatureSpellCastThisTurn", WatcherScope.GAME); super(ConduitOfRuinWatcher.class.getSimpleName(), WatcherScope.GAME);
playerCreatureSpells = new HashMap<>(); playerCreatureSpells = new HashMap<>();
} }
@ -117,20 +116,13 @@ class ConduitOfRuinWatcher extends Watcher {
if (event.getType() == GameEvent.EventType.SPELL_CAST) { if (event.getType() == GameEvent.EventType.SPELL_CAST) {
Spell spell = (Spell) game.getObject(event.getTargetId()); Spell spell = (Spell) game.getObject(event.getTargetId());
if (spell != null && spell.isCreature()) { if (spell != null && spell.isCreature()) {
if (playerCreatureSpells.containsKey(event.getPlayerId())) { playerCreatureSpells.put(event.getPlayerId(), creatureSpellsCastThisTurn(event.getPlayerId()) + 1);
playerCreatureSpells.put(event.getPlayerId(), playerCreatureSpells.get(event.getPlayerId()) + 1);
} else {
playerCreatureSpells.put(event.getPlayerId(), 1);
}
} }
} }
} }
public int creatureSpellsCastThisTurn(UUID playerId) { public int creatureSpellsCastThisTurn(UUID playerId) {
if (playerCreatureSpells.containsKey(playerId)) { return playerCreatureSpells.getOrDefault(playerId, 0);
return playerCreatureSpells.get(playerId);
}
return 0;
} }
@Override @Override
@ -151,7 +143,7 @@ class FirstCastCreatureSpellPredicate implements ObjectPlayerPredicate<ObjectPla
public boolean apply(ObjectPlayer<Controllable> input, Game game) { public boolean apply(ObjectPlayer<Controllable> input, Game game) {
if (input.getObject() instanceof Spell if (input.getObject() instanceof Spell
&& ((Spell) input.getObject()).isCreature()) { && ((Spell) input.getObject()).isCreature()) {
ConduitOfRuinWatcher watcher = (ConduitOfRuinWatcher) game.getState().getWatchers().get("FirstCreatureSpellCastThisTurn"); ConduitOfRuinWatcher watcher = (ConduitOfRuinWatcher) game.getState().getWatchers().get(ConduitOfRuinWatcher.class.getSimpleName());
return watcher != null && watcher.creatureSpellsCastThisTurn(input.getPlayerId()) == 0; return watcher != null && watcher.creatureSpellsCastThisTurn(input.getPlayerId()) == 0;
} }
return false; return false;

View file

@ -128,7 +128,7 @@ class ContainmentPriestReplacementEffect extends ReplacementEffectImpl {
card = card.getSecondCardFace(); card = card.getSecondCardFace();
} }
if (card.isCreature()) { // TODO: Bestow Card cast as Enchantment probably not handled correctly if (card.isCreature()) { // TODO: Bestow Card cast as Enchantment probably not handled correctly
CreatureWasCastWatcher watcher = (CreatureWasCastWatcher) game.getState().getWatchers().get("CreatureWasCast"); CreatureWasCastWatcher watcher = (CreatureWasCastWatcher) game.getState().getWatchers().get(CreatureWasCastWatcher.class.getSimpleName());
if (watcher != null && !watcher.wasCreatureCastThisTurn(event.getTargetId())) { if (watcher != null && !watcher.wasCreatureCastThisTurn(event.getTargetId())) {
return true; return true;
} }

View file

@ -0,0 +1,76 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeXTargetCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.dynamicvalue.common.GetXValue;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.common.FilterControlledLandPermanent;
/**
*
* @author Rene - bugisemail at gmail.com
*/
public class CopperLeafAngel extends CardImpl {
public CopperLeafAngel(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}");
this.subtype.add("Angel");
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Flying
this.addAbility(FlyingAbility.getInstance());
// {tap}, Sacrifice X lands: Put X +1/+1 counters on Copper-Leaf Angel.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(),new GetXValue(), false), new TapSourceCost());
ability.addCost(new SacrificeXTargetCost(new FilterControlledLandPermanent("lands"), false));
this.addAbility(ability);
}
public CopperLeafAngel(final CopperLeafAngel card) {
super(card);
}
@Override
public CopperLeafAngel copy() {
return new CopperLeafAngel(this);
}
}

View file

@ -99,7 +99,7 @@ class CounterbalanceEffect extends OneShotEffect {
CardsImpl cards = new CardsImpl(); CardsImpl cards = new CardsImpl();
cards.add(topcard); cards.add(topcard);
controller.revealCards(sourcePermanent.getName(), cards, game); controller.revealCards(sourcePermanent.getName(), cards, game);
if (CardUtil.convertedManaCostsIsEqual(topcard, spell)) { if (topcard.getConvertedManaCost() == spell.getConvertedManaCost()) {
return game.getStack().counter(spell.getId(), source.getSourceId(), game); return game.getStack().counter(spell.getId(), source.getSourceId(), game);
} }
} }

View file

@ -107,7 +107,7 @@ class CurseOfExhaustionEffect extends ContinuousRuleModifyingEffectImpl {
if (enchantment != null && enchantment.getAttachedTo() != null) { if (enchantment != null && enchantment.getAttachedTo() != null) {
Player player = game.getPlayer(enchantment.getAttachedTo()); Player player = game.getPlayer(enchantment.getAttachedTo());
if (player != null && event.getPlayerId().equals(player.getId())) { if (player != null && event.getPlayerId().equals(player.getId())) {
CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getName()); CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getSimpleName());
if (watcher != null && watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(event.getPlayerId()) > 0) { if (watcher != null && watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(event.getPlayerId()) > 0) {
return true; return true;
} }

View file

@ -179,7 +179,7 @@ class CyclopeanTombEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
MageObjectReference mor = new MageObjectReference(source.getSourceId(), source.getSourceObjectZoneChangeCounter(), game); MageObjectReference mor = new MageObjectReference(source.getSourceId(), source.getSourceObjectZoneChangeCounter(), game);
CyclopeanTombCounterWatcher watcher = (CyclopeanTombCounterWatcher) game.getState().getWatchers().get(CyclopeanTombCounterWatcher.class.getName()); CyclopeanTombCounterWatcher watcher = (CyclopeanTombCounterWatcher) game.getState().getWatchers().get(CyclopeanTombCounterWatcher.class.getSimpleName());
if (controller != null && watcher != null) { if (controller != null && watcher != null) {
Set<MageObjectReference> landRef = watcher.landMiredByCyclopeanTombInstance(mor, game); Set<MageObjectReference> landRef = watcher.landMiredByCyclopeanTombInstance(mor, game);
@ -221,7 +221,7 @@ class CyclopeanTombCounterWatcher extends Watcher {
public HashMap<MageObjectReference, Set<MageObjectReference>> counterData = new HashMap<>(); public HashMap<MageObjectReference, Set<MageObjectReference>> counterData = new HashMap<>();
public CyclopeanTombCounterWatcher() { public CyclopeanTombCounterWatcher() {
super(CyclopeanTombCounterWatcher.class.getName(), WatcherScope.GAME); super(CyclopeanTombCounterWatcher.class.getSimpleName(), WatcherScope.GAME);
} }
public CyclopeanTombCounterWatcher(final CyclopeanTombCounterWatcher watcher) { public CyclopeanTombCounterWatcher(final CyclopeanTombCounterWatcher watcher) {

View file

@ -68,7 +68,7 @@ public class DeathSpark extends CardImpl {
new DoIfCostPaid(new ReturnSourceFromGraveyardToHandEffect(), new GenericManaCost(1)), new DoIfCostPaid(new ReturnSourceFromGraveyardToHandEffect(), new GenericManaCost(1)),
TargetController.YOU, TargetController.YOU,
false), false),
new DeathSparkCondition(), DeathSparkCondition.instance,
"At the beginning of your upkeep, if {this} is in your graveyard with a creature card directly above it, you may pay {1}. If you do, return {this} to your hand.")); "At the beginning of your upkeep, if {this} is in your graveyard with a creature card directly above it, you may pay {1}. If you do, return {this} to your hand."));
} }
@ -82,13 +82,9 @@ public class DeathSpark extends CardImpl {
} }
} }
class DeathSparkCondition implements Condition { enum DeathSparkCondition implements Condition {
private static final DeathSparkCondition instance = new DeathSparkCondition(); instance;
public static Condition getInstance() {
return instance;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {

View file

@ -44,13 +44,12 @@ import java.util.HashMap;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public class DescentOfTheDragons extends CardImpl { public class DescentOfTheDragons extends CardImpl {
public DescentOfTheDragons(UUID ownerId, CardSetInfo setInfo) { public DescentOfTheDragons(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{R}{R}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}{R}");
// Destroy any number of target creatures. For each creature destroyed this way, its controller creates a 4/4 red Dragon creature token with flying. // Destroy any number of target creatures. For each creature destroyed this way, its controller creates a 4/4 red Dragon creature token with flying.
this.getSpellAbility().addEffect(new DescentOfTheDragonsEffect()); this.getSpellAbility().addEffect(new DescentOfTheDragonsEffect());
@ -95,18 +94,15 @@ class DescentOfTheDragonsEffect extends OneShotEffect {
if (permanent != null) { if (permanent != null) {
UUID controllerOfTargetId = permanent.getControllerId(); UUID controllerOfTargetId = permanent.getControllerId();
if (permanent.destroy(source.getSourceId(), game, false)) { if (permanent.destroy(source.getSourceId(), game, false)) {
if(playersWithTargets.containsKey(controllerOfTargetId)) { int count = playersWithTargets.getOrDefault(controllerOfTargetId, 0);
playersWithTargets.put(controllerOfTargetId, playersWithTargets.get(controllerOfTargetId) + 1); playersWithTargets.put(controllerOfTargetId, count + 1);
}
else {
playersWithTargets.put(controllerOfTargetId, 1);
}
} }
} }
} }
} }
DragonToken dragonToken = new DragonToken(); DragonToken dragonToken = new DragonToken();
for(UUID playerId : playersWithTargets.keySet()) { for (UUID playerId : playersWithTargets.keySet()) {
dragonToken.putOntoBattlefield(playersWithTargets.get(playerId), game, source.getSourceId(), playerId); dragonToken.putOntoBattlefield(playersWithTargets.get(playerId), game, source.getSourceId(), playerId);
} }
return true; return true;

View file

@ -116,7 +116,7 @@ class DraconicRoarEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null) {
DragonOnTheBattlefieldWhileSpellWasCastWatcher watcher = (DragonOnTheBattlefieldWhileSpellWasCastWatcher) game.getState().getWatchers().get("DragonOnTheBattlefieldWhileSpellWasCastWatcher"); DragonOnTheBattlefieldWhileSpellWasCastWatcher watcher = (DragonOnTheBattlefieldWhileSpellWasCastWatcher) game.getState().getWatchers().get(DragonOnTheBattlefieldWhileSpellWasCastWatcher.class.getSimpleName());
if (watcher != null && watcher.castWithConditionTrue(source.getId())) { if (watcher != null && watcher.castWithConditionTrue(source.getId())) {
Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source));
if (permanent != null) { if (permanent != null) {

View file

@ -46,13 +46,12 @@ import java.util.Map.Entry;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public class DreamSalvage extends CardImpl { public class DreamSalvage extends CardImpl {
public DreamSalvage(UUID ownerId, CardSetInfo setInfo) { public DreamSalvage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U/B}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U/B}");
// Draw cards equal to the number of cards target opponent discarded this turn. // Draw cards equal to the number of cards target opponent discarded this turn.
@ -77,7 +76,7 @@ class CardsDiscardedThisTurnWatcher extends Watcher {
private final Map<UUID, Integer> amountOfCardsDiscardedThisTurn = new HashMap<>(); private final Map<UUID, Integer> amountOfCardsDiscardedThisTurn = new HashMap<>();
public CardsDiscardedThisTurnWatcher() { public CardsDiscardedThisTurnWatcher() {
super("CardsDiscardedThisTurnWatcher", WatcherScope.GAME); super(CardsDiscardedThisTurnWatcher.class.getSimpleName(), WatcherScope.GAME);
} }
public CardsDiscardedThisTurnWatcher(final CardsDiscardedThisTurnWatcher watcher) { public CardsDiscardedThisTurnWatcher(final CardsDiscardedThisTurnWatcher watcher) {
@ -92,23 +91,13 @@ class CardsDiscardedThisTurnWatcher extends Watcher {
if (event.getType() == GameEvent.EventType.DISCARDED_CARD) { if (event.getType() == GameEvent.EventType.DISCARDED_CARD) {
UUID playerId = event.getPlayerId(); UUID playerId = event.getPlayerId();
if (playerId != null) { if (playerId != null) {
Integer amount = amountOfCardsDiscardedThisTurn.get(playerId); amountOfCardsDiscardedThisTurn.put(playerId, getAmountCardsDiscarded(playerId) + 1);
if (amount == null) {
amount = 1;
} else {
amount++;
}
amountOfCardsDiscardedThisTurn.put(playerId, amount);
} }
} }
} }
public int getAmountCardsDiscarded(UUID playerId) { public int getAmountCardsDiscarded(UUID playerId) {
Integer amount = amountOfCardsDiscardedThisTurn.get(playerId); return amountOfCardsDiscardedThisTurn.getOrDefault(playerId, 0);
if (amount != null) {
return amount;
}
return 0;
} }
@Override @Override
@ -140,7 +129,7 @@ class DreamSalvageEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
CardsDiscardedThisTurnWatcher watcher = (CardsDiscardedThisTurnWatcher) game.getState().getWatchers().get("CardsDiscardedThisTurnWatcher"); CardsDiscardedThisTurnWatcher watcher = (CardsDiscardedThisTurnWatcher) game.getState().getWatchers().get(CardsDiscardedThisTurnWatcher.class.getSimpleName());
Player targetOpponent = game.getPlayer(source.getFirstTarget()); Player targetOpponent = game.getPlayer(source.getFirstTarget());
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (targetOpponent != null if (targetOpponent != null

View file

@ -82,7 +82,7 @@ class CastBlueSpellThisTurnCondition implements Condition {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
SpellsCastWatcher watcher = (SpellsCastWatcher) game.getState().getWatchers().get(SpellsCastWatcher.class.getName()); SpellsCastWatcher watcher = (SpellsCastWatcher) game.getState().getWatchers().get(SpellsCastWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
for (Spell spell : watcher.getSpellsCastThisTurn(source.getControllerId())) { for (Spell spell : watcher.getSpellsCastThisTurn(source.getControllerId())) {
if (!spell.getSourceId().equals(source.getSourceId()) && spell.getColor(game).isBlue()) { if (!spell.getSourceId().equals(source.getSourceId()) && spell.getColor(game).isBlue()) {

View file

@ -100,7 +100,7 @@ class NoMoreThanOneCreatureCanAttackEachTurnEffect extends RestrictionEffect {
if (!game.getCombat().getAttackers().isEmpty()) { if (!game.getCombat().getAttackers().isEmpty()) {
return false; return false;
} }
AttackedThisTurnWatcher watcher = (AttackedThisTurnWatcher) game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getName()); AttackedThisTurnWatcher watcher = (AttackedThisTurnWatcher) game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getSimpleName());
Set<MageObjectReference> attackedThisTurnCreatures = watcher.getAttackedThisTurnCreatures(); Set<MageObjectReference> attackedThisTurnCreatures = watcher.getAttackedThisTurnCreatures();
return attackedThisTurnCreatures.isEmpty() return attackedThisTurnCreatures.isEmpty()
|| (attackedThisTurnCreatures.size() == 1 && attackedThisTurnCreatures.contains(new MageObjectReference(attacker, game))); || (attackedThisTurnCreatures.size() == 1 && attackedThisTurnCreatures.contains(new MageObjectReference(attacker, game)));
@ -134,7 +134,7 @@ class NoMoreThanOneCreatureCanBlockEachTurnEffect extends RestrictionEffect {
if (!game.getCombat().getBlockers().isEmpty()) { if (!game.getCombat().getBlockers().isEmpty()) {
return false; return false;
} }
BlockedThisTurnWatcher watcher = (BlockedThisTurnWatcher) game.getState().getWatchers().get("BlockedThisTurn"); BlockedThisTurnWatcher watcher = (BlockedThisTurnWatcher) game.getState().getWatchers().get(BlockedThisTurnWatcher.class.getSimpleName());
Set<MageObjectReference> blockedThisTurnCreatures = watcher.getBlockedThisTurnCreatures(); Set<MageObjectReference> blockedThisTurnCreatures = watcher.getBlockedThisTurnCreatures();
MageObjectReference blockerReference = new MageObjectReference(blocker.getId(), blocker.getZoneChangeCounter(game), game); MageObjectReference blockerReference = new MageObjectReference(blocker.getId(), blocker.getZoneChangeCounter(game), game);
return blockedThisTurnCreatures.isEmpty() return blockedThisTurnCreatures.isEmpty()

View file

@ -0,0 +1,81 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.e;
import java.util.UUID;
import mage.target.common.TargetCreaturePermanent;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.combat.CanBlockAdditionalCreatureEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.constants.Outcome;
import mage.target.TargetPermanent;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
/**
*
* @author Rene bugisemail at gmail dot com
*/
public class Entangler extends CardImpl {
public Entangler(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
this.subtype.add("Aura");
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Enchanted creature can block any number of creatures.
SimpleStaticAbility blockAbility = new SimpleStaticAbility(Zone.BATTLEFIELD,new CanBlockAdditionalCreatureEffect(0));
Effect effect = new GainAbilityAttachedEffect(blockAbility,AttachmentType.AURA, Duration.WhileOnBattlefield);
effect.setText("Enchanted creature can block any number of creatures.");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
}
public Entangler(final Entangler card) {
super(card);
}
@Override
public Entangler copy() {
return new Entangler(this);
}
}

View file

@ -95,7 +95,7 @@ enum HadAnotherCreatureEnterTheBattlefieldCondition implements Condition {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
PermanentsEnteredBattlefieldWatcher watcher = (PermanentsEnteredBattlefieldWatcher) game.getState().getWatchers().get(PermanentsEnteredBattlefieldWatcher.class.getName()); PermanentsEnteredBattlefieldWatcher watcher = (PermanentsEnteredBattlefieldWatcher) game.getState().getWatchers().get(PermanentsEnteredBattlefieldWatcher.class.getSimpleName());
return sourcePermanent != null return sourcePermanent != null
&& watcher != null && watcher != null
&& watcher.AnotherCreatureEnteredBattlefieldUnderPlayersControlLastTurn(sourcePermanent, game); && watcher.AnotherCreatureEnteredBattlefieldUnderPlayersControlLastTurn(sourcePermanent, game);

View file

@ -104,7 +104,7 @@ class ErayoSoratamiAscendantTriggeredAbility extends TriggeredAbilityImpl {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getName()); CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getSimpleName());
return watcher != null && watcher.getAmountOfSpellsAllPlayersCastOnCurrentTurn() == 4; return watcher != null && watcher.getAmountOfSpellsAllPlayersCastOnCurrentTurn() == 4;
} }
@ -153,7 +153,7 @@ class ErayosEssenceTriggeredAbility extends TriggeredAbilityImpl {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
if (game.getOpponents(getControllerId()).contains(event.getPlayerId())) { if (game.getOpponents(getControllerId()).contains(event.getPlayerId())) {
CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getName()); CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getSimpleName());
if (watcher != null && watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(event.getPlayerId()) == 1) { if (watcher != null && watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(event.getPlayerId()) == 1) {
for (Effect effect : getEffects()) { for (Effect effect : getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getTargetId())); effect.setTargetPointer(new FixedTarget(event.getTargetId()));

View file

@ -45,13 +45,12 @@ import java.util.HashMap;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public class ErdwalIlluminator extends CardImpl { public class ErdwalIlluminator extends CardImpl {
public ErdwalIlluminator(UUID ownerId, CardSetInfo setInfo) { public ErdwalIlluminator(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.subtype.add("Spirit"); this.subtype.add("Spirit");
this.power = new MageInt(1); this.power = new MageInt(1);
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
@ -91,7 +90,7 @@ class ErdwalIlluminatorTriggeredAbility extends TriggeredAbilityImpl {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
InvestigatedWatcher watcher = (InvestigatedWatcher) game.getState().getWatchers().get(InvestigatedWatcher.class.getName()); InvestigatedWatcher watcher = (InvestigatedWatcher) game.getState().getWatchers().get(InvestigatedWatcher.class.getSimpleName());
return watcher != null && watcher.getTimesInvestigated(getControllerId()) == 1; return watcher != null && watcher.getTimesInvestigated(getControllerId()) == 1;
} }
@ -111,7 +110,7 @@ class InvestigatedWatcher extends Watcher {
private final HashMap<UUID, Integer> timesInvestigated = new HashMap<>(); private final HashMap<UUID, Integer> timesInvestigated = new HashMap<>();
public InvestigatedWatcher() { public InvestigatedWatcher() {
super(InvestigatedWatcher.class.getName(), WatcherScope.GAME); super(InvestigatedWatcher.class.getSimpleName(), WatcherScope.GAME);
} }
public InvestigatedWatcher(final InvestigatedWatcher watcher) { public InvestigatedWatcher(final InvestigatedWatcher watcher) {
@ -126,11 +125,8 @@ class InvestigatedWatcher extends Watcher {
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() == EventType.INVESTIGATED) { if (event.getType() == EventType.INVESTIGATED) {
if (!timesInvestigated.containsKey(event.getPlayerId())) { timesInvestigated.put(event.getPlayerId(), getTimesInvestigated(event.getPlayerId()) + 1);
timesInvestigated.put(event.getPlayerId(), 1);
} else {
timesInvestigated.put(event.getPlayerId(), timesInvestigated.get(event.getPlayerId()) + 1);
}
} }
} }
@ -141,9 +137,6 @@ class InvestigatedWatcher extends Watcher {
} }
public int getTimesInvestigated(UUID playerId) { public int getTimesInvestigated(UUID playerId) {
if (timesInvestigated.containsKey(playerId)) { return timesInvestigated.getOrDefault(playerId, 0);
return timesInvestigated.get(playerId);
}
return 0;
} }
} }

View file

@ -80,7 +80,7 @@ class ErgRaidersCondition implements Condition {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent raiders = game.getPermanentOrLKIBattlefield(source.getSourceId()); Permanent raiders = game.getPermanentOrLKIBattlefield(source.getSourceId());
AttackedThisTurnWatcher watcher = (AttackedThisTurnWatcher) game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getName()); AttackedThisTurnWatcher watcher = (AttackedThisTurnWatcher) game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getSimpleName());
// wasControlledFromStartOfControllerTurn should be checked during resolution I guess, but shouldn't be relevant // wasControlledFromStartOfControllerTurn should be checked during resolution I guess, but shouldn't be relevant
return raiders.wasControlledFromStartOfControllerTurn() && !watcher.getAttackedThisTurnCreatures().contains(new MageObjectReference(raiders, game)); return raiders.wasControlledFromStartOfControllerTurn() && !watcher.getAttackedThisTurnCreatures().contains(new MageObjectReference(raiders, game));
} }

View file

@ -78,7 +78,7 @@ class EtherswornCanonistWatcher extends Watcher {
private Set<UUID> castNonartifactSpell = new HashSet<>(); private Set<UUID> castNonartifactSpell = new HashSet<>();
public EtherswornCanonistWatcher() { public EtherswornCanonistWatcher() {
super(EtherswornCanonistWatcher.class.getName(), WatcherScope.GAME); super(EtherswornCanonistWatcher.class.getSimpleName(), WatcherScope.GAME);
} }
public EtherswornCanonistWatcher(final EtherswornCanonistWatcher watcher) { public EtherswornCanonistWatcher(final EtherswornCanonistWatcher watcher) {
@ -143,7 +143,7 @@ class EtherswornCanonistReplacementEffect extends ContinuousRuleModifyingEffectI
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
Card card = game.getCard(event.getSourceId()); Card card = game.getCard(event.getSourceId());
if (card != null && !card.isArtifact()) { if (card != null && !card.isArtifact()) {
EtherswornCanonistWatcher watcher = (EtherswornCanonistWatcher) game.getState().getWatchers().get(EtherswornCanonistWatcher.class.getName()); EtherswornCanonistWatcher watcher = (EtherswornCanonistWatcher) game.getState().getWatchers().get(EtherswornCanonistWatcher.class.getSimpleName());
return watcher != null && watcher.castNonArtifactSpell(event.getPlayerId()); return watcher != null && watcher.castNonArtifactSpell(event.getPlayerId());
} }
return false; return false;

View file

@ -84,7 +84,7 @@ class TargetCreaturePermanentThatDealtDamageThisTurn extends TargetPermanent {
@Override @Override
public boolean canTarget(UUID id, Ability source, Game game) { public boolean canTarget(UUID id, Ability source, Game game) {
SourceDidDamageWatcher watcher = (SourceDidDamageWatcher) game.getState().getWatchers().get("SourceDidDamageWatcher"); SourceDidDamageWatcher watcher = (SourceDidDamageWatcher) game.getState().getWatchers().get(SourceDidDamageWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
if (watcher.damageSources.contains(id)) { if (watcher.damageSources.contains(id)) {
return super.canTarget(id, source, game); return super.canTarget(id, source, game);
@ -101,7 +101,7 @@ class TargetCreaturePermanentThatDealtDamageThisTurn extends TargetPermanent {
} }
int count = 0; int count = 0;
MageObject targetSource = game.getObject(sourceId); MageObject targetSource = game.getObject(sourceId);
SourceDidDamageWatcher watcher = (SourceDidDamageWatcher) game.getState().getWatchers().get("SourceDidDamageWatcher"); SourceDidDamageWatcher watcher = (SourceDidDamageWatcher) game.getState().getWatchers().get(SourceDidDamageWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game)) { for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game)) {
if (!targets.containsKey(permanent.getId()) && watcher.damageSources.contains(permanent.getId())) { if (!targets.containsKey(permanent.getId()) && watcher.damageSources.contains(permanent.getId())) {
@ -121,7 +121,7 @@ class TargetCreaturePermanentThatDealtDamageThisTurn extends TargetPermanent {
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
Set<UUID> availablePossibleTargets = super.possibleTargets(sourceId, sourceControllerId, game); Set<UUID> availablePossibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
Set<UUID> possibleTargets = new HashSet<>(); Set<UUID> possibleTargets = new HashSet<>();
SourceDidDamageWatcher watcher = (SourceDidDamageWatcher) game.getState().getWatchers().get("SourceDidDamageWatcher"); SourceDidDamageWatcher watcher = (SourceDidDamageWatcher) game.getState().getWatchers().get(SourceDidDamageWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
for (UUID targetId : availablePossibleTargets) { for (UUID targetId : availablePossibleTargets) {
Permanent permanent = game.getPermanent(targetId); Permanent permanent = game.getPermanent(targetId);

View file

@ -49,7 +49,6 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public class FairgroundsTrumpeter extends CardImpl { public class FairgroundsTrumpeter extends CardImpl {
@ -62,9 +61,9 @@ public class FairgroundsTrumpeter extends CardImpl {
// At the beginning of each end step, if a +1/+1 counter was placed on a permanent under your control this turn, put a +1/+1 counter on Fairgrounds Trumpeter. // At the beginning of each end step, if a +1/+1 counter was placed on a permanent under your control this turn, put a +1/+1 counter on Fairgrounds Trumpeter.
this.addAbility(new ConditionalTriggeredAbility(new BeginningOfEndStepTriggeredAbility( this.addAbility(new ConditionalTriggeredAbility(new BeginningOfEndStepTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
TargetController.ANY, false), FairgroundsTrumpeterCondition.getInstance(), TargetController.ANY, false), FairgroundsTrumpeterCondition.instance,
"At the beginning of each end step, if a +1/+1 counter was placed on a permanent under your control this turn, put a +1/+1 counter on {this}."), "At the beginning of each end step, if a +1/+1 counter was placed on a permanent under your control this turn, put a +1/+1 counter on {this}."),
new FairgroundsTrumpeterWatcher()); new FairgroundsTrumpeterWatcher());
} }
@ -78,17 +77,13 @@ public class FairgroundsTrumpeter extends CardImpl {
} }
} }
class FairgroundsTrumpeterCondition implements Condition { enum FairgroundsTrumpeterCondition implements Condition {
private static final FairgroundsTrumpeterCondition instance = new FairgroundsTrumpeterCondition(); instance;
public static Condition getInstance() {
return instance;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
FairgroundsTrumpeterWatcher watcher = (FairgroundsTrumpeterWatcher) game.getState().getWatchers().get(FairgroundsTrumpeterWatcher.class.getName()); FairgroundsTrumpeterWatcher watcher = (FairgroundsTrumpeterWatcher) game.getState().getWatchers().get(FairgroundsTrumpeterWatcher.class.getSimpleName());
return watcher != null && watcher.p1p1AddedToPermanent(source.getControllerId()); return watcher != null && watcher.p1p1AddedToPermanent(source.getControllerId());
} }
@ -104,7 +99,7 @@ class FairgroundsTrumpeterWatcher extends Watcher {
private final Set<UUID> players = new HashSet<>(); private final Set<UUID> players = new HashSet<>();
public FairgroundsTrumpeterWatcher() { public FairgroundsTrumpeterWatcher() {
super(FairgroundsTrumpeterWatcher.class.getName(), WatcherScope.GAME); super(FairgroundsTrumpeterWatcher.class.getSimpleName(), WatcherScope.GAME);
} }
public FairgroundsTrumpeterWatcher(final FairgroundsTrumpeterWatcher watcher) { public FairgroundsTrumpeterWatcher(final FairgroundsTrumpeterWatcher watcher) {

View file

@ -82,7 +82,7 @@ class FaithsRewardEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
FaithsRewardWatcher watcher = (FaithsRewardWatcher) game.getState().getWatchers().get("FaithsRewardWatcher"); FaithsRewardWatcher watcher = (FaithsRewardWatcher) game.getState().getWatchers().get(FaithsRewardWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
for (UUID id : watcher.cards) { for (UUID id : watcher.cards) {
Card c = game.getCard(id); Card c = game.getCard(id);
@ -105,7 +105,7 @@ class FaithsRewardWatcher extends Watcher {
ArrayList<UUID> cards = new ArrayList<>(); ArrayList<UUID> cards = new ArrayList<>();
public FaithsRewardWatcher() { public FaithsRewardWatcher() {
super("FaithsRewardWatcher", WatcherScope.GAME); super(FaithsRewardWatcher.class.getSimpleName(), WatcherScope.GAME);
} }
public FaithsRewardWatcher(final FaithsRewardWatcher watcher) { public FaithsRewardWatcher(final FaithsRewardWatcher watcher) {

View file

@ -59,7 +59,7 @@ public class FeastOnTheFallen extends CardImpl {
new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new AddCountersTargetEffect(CounterType.P1P1.createInstance()),
TargetController.ANY, false), TargetController.ANY, false),
FeastOnTheFallenCondition.getInstance(), FeastOnTheFallenCondition.instance,
"At the beginning of each upkeep, if an opponent lost life last turn, put a +1/+1 counter on target creature you control."); "At the beginning of each upkeep, if an opponent lost life last turn, put a +1/+1 counter on target creature you control.");
ability.addTarget(new TargetControlledCreaturePermanent()); ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability); this.addAbility(ability);
@ -75,17 +75,13 @@ public class FeastOnTheFallen extends CardImpl {
} }
} }
class FeastOnTheFallenCondition implements Condition { enum FeastOnTheFallenCondition implements Condition {
private static final FeastOnTheFallenCondition instance = new FeastOnTheFallenCondition(); instance;
public static FeastOnTheFallenCondition getInstance() {
return instance;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
PlayerLostLifeWatcher watcher = (PlayerLostLifeWatcher) game.getState().getWatchers().get("PlayerLostLifeWatcher"); PlayerLostLifeWatcher watcher = (PlayerLostLifeWatcher) game.getState().getWatchers().get(PlayerLostLifeWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
for (UUID opponentId : game.getOpponents(source.getControllerId())) { for (UUID opponentId : game.getOpponents(source.getControllerId())) {
if (watcher.getLiveLostLastTurn(opponentId) > 0) { if (watcher.getLiveLostLastTurn(opponentId) > 0) {

View file

@ -98,7 +98,7 @@ class FellShepherdWatcher extends Watcher {
private Set<UUID> creatureIds = new HashSet<>(); private Set<UUID> creatureIds = new HashSet<>();
public FellShepherdWatcher() { public FellShepherdWatcher() {
super("YourCreaturesPutToGraveFromBattlefield", WatcherScope.PLAYER); super(FellShepherdWatcher.class.getSimpleName(), WatcherScope.PLAYER);
condition = true; condition = true;
} }
@ -151,7 +151,7 @@ class FellShepherdEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
FellShepherdWatcher watcher = (FellShepherdWatcher) game.getState().getWatchers().get("YourCreaturesPutToGraveFromBattlefield", source.getControllerId()); FellShepherdWatcher watcher = (FellShepherdWatcher) game.getState().getWatchers().get(FellShepherdWatcher.class.getSimpleName(), source.getControllerId());
if (watcher != null) { if (watcher != null) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (UUID creatureId : watcher.getCreaturesIds()) { for (UUID creatureId : watcher.getCreaturesIds()) {

View file

@ -72,7 +72,7 @@ class FinalPunishmentAmount implements DynamicValue {
@Override @Override
public int calculate(Game game, Ability source, Effect effect) { public int calculate(Game game, Ability source, Effect effect) {
AmountOfDamageAPlayerReceivedThisTurnWatcher watcher AmountOfDamageAPlayerReceivedThisTurnWatcher watcher
= (AmountOfDamageAPlayerReceivedThisTurnWatcher) game.getState().getWatchers().get("AmountOfDamageReceivedThisTurn"); = (AmountOfDamageAPlayerReceivedThisTurnWatcher) game.getState().getWatchers().get(AmountOfDamageAPlayerReceivedThisTurnWatcher.class.getSimpleName());
if(watcher != null) { if(watcher != null) {
return watcher.getAmountOfDamageReceivedThisTurn(source.getFirstTarget()); return watcher.getAmountOfDamageReceivedThisTurn(source.getFirstTarget());
} }

View file

@ -69,7 +69,7 @@ public class FiremaneAngel extends CardImpl {
// At the beginning of your upkeep, if Firemane Angel is in your graveyard or on the battlefield, you may gain 1 life. // At the beginning of your upkeep, if Firemane Angel is in your graveyard or on the battlefield, you may gain 1 life.
Ability ability = new ConditionalTriggeredAbility( Ability ability = new ConditionalTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility(Zone.ALL, new GainLifeEffect(1), TargetController.YOU, true), new BeginningOfUpkeepTriggeredAbility(Zone.ALL, new GainLifeEffect(1), TargetController.YOU, true),
SourceOnBattelfieldOrGraveyardCondition.getInstance(), SourceOnBattlefieldOrGraveyardCondition.instance,
"At the beginning of your upkeep, if {this} is in your graveyard or on the battlefield, you may gain 1 life"); "At the beginning of your upkeep, if {this} is in your graveyard or on the battlefield, you may gain 1 life");
this.addAbility(ability); this.addAbility(ability);
// {6}{R}{R}{W}{W}: Return Firemane Angel from your graveyard to the battlefield. Activate this ability only during your upkeep. // {6}{R}{R}{W}{W}: Return Firemane Angel from your graveyard to the battlefield. Activate this ability only during your upkeep.
@ -87,13 +87,9 @@ public class FiremaneAngel extends CardImpl {
} }
} }
class SourceOnBattelfieldOrGraveyardCondition implements Condition { enum SourceOnBattlefieldOrGraveyardCondition implements Condition {
private static final SourceOnBattelfieldOrGraveyardCondition instance = new SourceOnBattelfieldOrGraveyardCondition(); instance;
public static SourceOnBattelfieldOrGraveyardCondition getInstance() {
return instance;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {

View file

@ -84,7 +84,7 @@ class FirstResponseEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
PlayerLostLifeWatcher watcher = (PlayerLostLifeWatcher) game.getState().getWatchers().get("PlayerLostLifeWatcher"); PlayerLostLifeWatcher watcher = (PlayerLostLifeWatcher) game.getState().getWatchers().get(PlayerLostLifeWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
if (watcher.getLiveLostLastTurn(source.getControllerId()) > 0) { if (watcher.getLiveLostLastTurn(source.getControllerId()) > 0) {
return new CreateTokenEffect(new SoldierToken()).apply(game, source); return new CreateTokenEffect(new SoldierToken()).apply(game, source);

View file

@ -103,7 +103,7 @@ class FlamebreakCantRegenerateEffect extends ContinuousRuleModifyingEffectImpl {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == EventType.REGENERATE) { if (event.getType() == EventType.REGENERATE) {
DamagedByWatcher watcher = (DamagedByWatcher) game.getState().getWatchers().get("DamagedByWatcher", source.getSourceId()); DamagedByWatcher watcher = (DamagedByWatcher) game.getState().getWatchers().get(DamagedByWatcher.class.getSimpleName(), source.getSourceId());
if (watcher != null) { if (watcher != null) {
return watcher.wasDamaged(event.getTargetId(), game); return watcher.wasDamaged(event.getTargetId(), game);
} }

View file

@ -101,7 +101,7 @@ class FlashEffect extends OneShotEffect {
if (card != null) { if (card != null) {
card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), source.getControllerId()); card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), source.getControllerId());
ManaCosts<ManaCost> reducedCost = CardUtil.removeVariableManaCost(CardUtil.reduceCost(card.getManaCost(), 2)); ManaCosts<ManaCost> reducedCost = ManaCosts.removeVariableManaCost(CardUtil.reduceCost(card.getManaCost(), 2));
StringBuilder sb = new StringBuilder("Pay ").append(reducedCost.getText()).append('?'); StringBuilder sb = new StringBuilder("Pay ").append(reducedCost.getText()).append('?');
if (player.chooseUse(Outcome.Benefit, sb.toString(), source, game)) { if (player.chooseUse(Outcome.Benefit, sb.toString(), source, game)) {
reducedCost.clearPaid(); reducedCost.clearPaid();

View file

@ -83,7 +83,7 @@ class FleshAllergyWatcher extends Watcher {
public int creaturesDiedThisTurn = 0; public int creaturesDiedThisTurn = 0;
public FleshAllergyWatcher() { public FleshAllergyWatcher() {
super("CreaturesDied", WatcherScope.GAME); super(FleshAllergyWatcher.class.getSimpleName(), WatcherScope.GAME);
} }
public FleshAllergyWatcher(final FleshAllergyWatcher watcher) { public FleshAllergyWatcher(final FleshAllergyWatcher watcher) {
@ -131,7 +131,7 @@ class FleshAllergyEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
FleshAllergyWatcher watcher = (FleshAllergyWatcher) game.getState().getWatchers().get("CreaturesDied"); FleshAllergyWatcher watcher = (FleshAllergyWatcher) game.getState().getWatchers().get(FleshAllergyWatcher.class.getSimpleName());
Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source));
if (permanent != null && watcher != null) { if (permanent != null && watcher != null) {
Player player = game.getPlayer(permanent.getControllerId()); Player player = game.getPlayer(permanent.getControllerId());

View file

@ -116,7 +116,7 @@ class FoulTongueInvocationEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null) {
DragonOnTheBattlefieldWhileSpellWasCastWatcher watcher = (DragonOnTheBattlefieldWhileSpellWasCastWatcher) game.getState().getWatchers().get("DragonOnTheBattlefieldWhileSpellWasCastWatcher"); DragonOnTheBattlefieldWhileSpellWasCastWatcher watcher = (DragonOnTheBattlefieldWhileSpellWasCastWatcher) game.getState().getWatchers().get(DragonOnTheBattlefieldWhileSpellWasCastWatcher.class.getSimpleName());
if (watcher != null && watcher.castWithConditionTrue(source.getId())) { if (watcher != null && watcher.castWithConditionTrue(source.getId())) {
controller.gainLife(4, game); controller.gainLife(4, game);
} }

View file

@ -68,7 +68,7 @@ class FreshMeatDynamicValue implements DynamicValue {
@Override @Override
public int calculate(Game game, Ability sourceAbility, Effect effect) { public int calculate(Game game, Ability sourceAbility, Effect effect) {
CreaturesDiedWatcher watcher = (CreaturesDiedWatcher) game.getState().getWatchers().get("CreaturesDiedWatcher"); CreaturesDiedWatcher watcher = (CreaturesDiedWatcher) game.getState().getWatchers().get(CreaturesDiedWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
return watcher.getAmountOfCreaturesDiesThisTurn(sourceAbility.getControllerId()); return watcher.getAmountOfCreaturesDiesThisTurn(sourceAbility.getControllerId());
} }

View file

@ -27,9 +27,8 @@
*/ */
package mage.cards.g; package mage.cards.g;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility;
import mage.abilities.condition.common.CardsInControllerGraveCondition; import mage.abilities.condition.common.CardsInControllerGraveCondition;
import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
@ -59,8 +58,9 @@ import mage.target.common.TargetCardInHand;
import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public class GateToTheAfterlife extends CardImpl { public class GateToTheAfterlife extends CardImpl {
@ -76,7 +76,7 @@ public class GateToTheAfterlife extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// Whenever a nontoken creature you control dies, you gain 1 life. Then you may draw a card. If you do, discard a card. // Whenever a nontoken creature you control dies, you gain 1 life. Then you may draw a card. If you do, discard a card.
Ability ability = new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, new GainLifeEffect(1), filter, false); Ability ability = new PutIntoGraveFromBattlefieldAllTriggeredAbility(new GainLifeEffect(1), false, filter, false, true);
Effect effect = new DrawDiscardControllerEffect(1, 1, true); Effect effect = new DrawDiscardControllerEffect(1, 1, true);
effect.setText("Then you may draw a card. If you do, discard a card"); effect.setText("Then you may draw a card. If you do, discard a card");
ability.addEffect(effect); ability.addEffect(effect);

View file

@ -0,0 +1,52 @@
package mage.cards.g;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.dynamicvalue.common.AuraAttachedCount;
import mage.abilities.effects.common.RegenerateSourceEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.common.TargetControlledPermanent;
import java.util.UUID;
public class GathererOfGraces extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("an aura");
static {
filter.add(new SubtypePredicate("Aura"));
}
public GathererOfGraces(UUID ownerId, CardSetInfo cardSetInfo) {
super(ownerId, cardSetInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add("Human");
this.subtype.add("Druid");
this.power = new MageInt(1);
this.toughness = new MageInt(2);
// Gatherer of Graces gets +1/+1 for each Aura attached to it.
AuraAttachedCount count = new AuraAttachedCount(1);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(count, count, Duration.WhileOnBattlefield)));
// Sacrifice an Aura: Regenerate Gatherer of Graces
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter))));
}
public GathererOfGraces(GathererOfGraces gathererOfGraces) {
super(gathererOfGraces);
}
@Override
public GathererOfGraces copy() {
return new GathererOfGraces(this);
}
}

View file

@ -90,7 +90,7 @@ class GeneratorServantWatcher extends Watcher {
public List<UUID> creatures = new ArrayList<>(); public List<UUID> creatures = new ArrayList<>();
public GeneratorServantWatcher() { public GeneratorServantWatcher() {
super("GeneratorServantWatcher", WatcherScope.CARD); super(GeneratorServantWatcher.class.getSimpleName(), WatcherScope.CARD);
} }
public GeneratorServantWatcher(final GeneratorServantWatcher watcher) { public GeneratorServantWatcher(final GeneratorServantWatcher watcher) {
@ -141,7 +141,7 @@ class GeneratorServantHasteEffect extends ContinuousEffectImpl {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
GeneratorServantWatcher watcher = (GeneratorServantWatcher) game.getState().getWatchers().get("GeneratorServantWatcher", source.getSourceId()); GeneratorServantWatcher watcher = (GeneratorServantWatcher) game.getState().getWatchers().get(GeneratorServantWatcher.class.getSimpleName(), source.getSourceId());
if (watcher != null) { if (watcher != null) {
for (Permanent perm : game.getBattlefield().getAllActivePermanents()) { for (Permanent perm : game.getBattlefield().getAllActivePermanents()) {
if (watcher.creatures.contains(perm.getId())) { if (watcher.creatures.contains(perm.getId())) {

View file

@ -49,13 +49,12 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class GiltspireAvenger extends CardImpl { public class GiltspireAvenger extends CardImpl {
public GiltspireAvenger(UUID ownerId, CardSetInfo setInfo) { public GiltspireAvenger(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}{W}{U}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{W}{U}");
this.subtype.add("Human"); this.subtype.add("Human");
this.subtype.add("Soldier"); this.subtype.add("Soldier");
@ -97,7 +96,7 @@ class GiltspireAvengerTarget extends TargetPermanent {
@Override @Override
public boolean canTarget(UUID id, Ability source, Game game) { public boolean canTarget(UUID id, Ability source, Game game) {
PlayerDamagedBySourceWatcher watcher = (PlayerDamagedBySourceWatcher) game.getState().getWatchers().get("PlayerDamagedBySource",source.getControllerId()); PlayerDamagedBySourceWatcher watcher = (PlayerDamagedBySourceWatcher) game.getState().getWatchers().get(PlayerDamagedBySourceWatcher.class.getSimpleName(), source.getControllerId());
if (watcher != null && watcher.hasSourceDoneDamage(id, game)) { if (watcher != null && watcher.hasSourceDoneDamage(id, game)) {
return super.canTarget(id, source, game); return super.canTarget(id, source, game);
} }
@ -108,10 +107,10 @@ class GiltspireAvengerTarget extends TargetPermanent {
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
Set<UUID> availablePossibleTargets = super.possibleTargets(sourceId, sourceControllerId, game); Set<UUID> availablePossibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
Set<UUID> possibleTargets = new HashSet<>(); Set<UUID> possibleTargets = new HashSet<>();
PlayerDamagedBySourceWatcher watcher = (PlayerDamagedBySourceWatcher) game.getState().getWatchers().get("PlayerDamagedBySource", sourceControllerId); PlayerDamagedBySourceWatcher watcher = (PlayerDamagedBySourceWatcher) game.getState().getWatchers().get(PlayerDamagedBySourceWatcher.class.getSimpleName(), sourceControllerId);
for (UUID targetId : availablePossibleTargets) { for (UUID targetId : availablePossibleTargets) {
Permanent permanent = game.getPermanent(targetId); Permanent permanent = game.getPermanent(targetId);
if(permanent != null && watcher != null && watcher.hasSourceDoneDamage(targetId, game)){ if (permanent != null && watcher != null && watcher.hasSourceDoneDamage(targetId, game)) {
possibleTargets.add(targetId); possibleTargets.add(targetId);
} }
} }
@ -126,15 +125,15 @@ class GiltspireAvengerTarget extends TargetPermanent {
} }
int count = 0; int count = 0;
MageObject targetSource = game.getObject(sourceId); MageObject targetSource = game.getObject(sourceId);
PlayerDamagedBySourceWatcher watcher = (PlayerDamagedBySourceWatcher) game.getState().getWatchers().get("PlayerDamagedBySource", sourceControllerId); PlayerDamagedBySourceWatcher watcher = (PlayerDamagedBySourceWatcher) game.getState().getWatchers().get(PlayerDamagedBySourceWatcher.class.getSimpleName(), sourceControllerId);
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game)) { for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game)) {
if (!targets.containsKey(permanent.getId()) && permanent.canBeTargetedBy(targetSource, sourceControllerId, game) if (!targets.containsKey(permanent.getId()) && permanent.canBeTargetedBy(targetSource, sourceControllerId, game)
&& watcher != null && watcher.hasSourceDoneDamage(permanent.getId(), game)) { && watcher != null && watcher.hasSourceDoneDamage(permanent.getId(), game)) {
count++; count++;
if (count >= remainingTargets) { if (count >= remainingTargets) {
return true; return true;
}
} }
}
} }
return false; return false;
} }

View file

@ -143,7 +143,7 @@ class GisaAndGeralfCastFromGraveyardEffect extends AsThoughEffectImpl {
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (objectId.equals(getTargetPointer().getFirst(game, source))) { if (objectId.equals(getTargetPointer().getFirst(game, source))) {
if (affectedControllerId.equals(source.getControllerId())) { if (affectedControllerId.equals(source.getControllerId())) {
GisaAndGeralfWatcher watcher = (GisaAndGeralfWatcher) game.getState().getWatchers().get("GisaAndGeralfWatcher", source.getSourceId()); GisaAndGeralfWatcher watcher = (GisaAndGeralfWatcher) game.getState().getWatchers().get(GisaAndGeralfWatcher.class.getSimpleName(), source.getSourceId());
return !watcher.isAbilityUsed(); return !watcher.isAbilityUsed();
} }
} }

View file

@ -99,7 +99,7 @@ class GleancrawlerEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
CardsPutIntoGraveyardWatcher watcher = (CardsPutIntoGraveyardWatcher) game.getState().getWatchers().get("CardsPutIntoGraveyardWatcher"); CardsPutIntoGraveyardWatcher watcher = (CardsPutIntoGraveyardWatcher) game.getState().getWatchers().get(CardsPutIntoGraveyardWatcher.class.getSimpleName());
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null && watcher != null) { if (controller != null && watcher != null) {
Set<MageObjectReference> cardsToGraveyardThisTurn = watcher.getCardsPutToGraveyardFromBattlefield(); Set<MageObjectReference> cardsToGraveyardThisTurn = watcher.getCardsPutToGraveyardFromBattlefield();

View file

@ -104,7 +104,7 @@ class GlyphKeeperAbility extends TriggeredAbilityImpl {
if (event.getTargetId().equals(this.getSourceId())) { if (event.getTargetId().equals(this.getSourceId())) {
Permanent permanent = game.getPermanent(event.getTargetId()); Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && permanent.isCreature()) { if (permanent != null && permanent.isCreature()) {
NumberOfTimesPermanentTargetedATurnWatcher watcher = (NumberOfTimesPermanentTargetedATurnWatcher) game.getState().getWatchers().get(NumberOfTimesPermanentTargetedATurnWatcher.class.getName()); NumberOfTimesPermanentTargetedATurnWatcher watcher = (NumberOfTimesPermanentTargetedATurnWatcher) game.getState().getWatchers().get(NumberOfTimesPermanentTargetedATurnWatcher.class.getSimpleName());
if (watcher != null if (watcher != null
&& watcher.notMoreThanOnceTargetedThisTurn(permanent, game)) { && watcher.notMoreThanOnceTargetedThisTurn(permanent, game)) {
for (Effect effect : getEffects()) { for (Effect effect : getEffects()) {

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