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
woogerworks (North America/USA) :xmage.woogerworks.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
XMage.tahiti :xmage.tahiti.one:443
Seedds Server (Asia) :115.29.203.80:17171

View file

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

View file

@ -19,20 +19,14 @@ import java.util.UUID;
/**
* @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> combatBlockers = new HashMap<>();
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;

View file

@ -34,6 +34,7 @@ import java.awt.GridBagLayout;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
@ -142,6 +143,17 @@ public final class CollectionViewerPanel extends JPanel {
next.addActionListener(e -> mageBook.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 -> {
if (mageBook != null) {
String format = (String)formats.getSelectedItem();

View file

@ -57,9 +57,17 @@ import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
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.
@ -113,7 +121,7 @@ public class MageBook extends JComponent {
}
pageRight.setVisible(true);
AudioManager.playPrevPage();
showCards();
showCardsOrTokens();
});
image = ImageHelper.loadImage(RIGHT_PAGE_BUTTON_IMAGE_PATH);
@ -125,7 +133,7 @@ public class MageBook extends JComponent {
pageLeft.setVisible(true);
pageRight.setVisible(false);
AudioManager.playNextPage();
showCards();
showCardsOrTokens();
});
addSetTabs();
@ -170,7 +178,7 @@ public class MageBook extends JComponent {
final String _set = set;
final int _index = count;
tab.setObserver(() -> {
if (!currentSet.equals(_set) || currentPage != 0) {
if (!currentSet.equals(_set) || currentPage != 0 || stateChanged) {
AudioManager.playAnotherTab();
synchronized (MageBook.this) {
selectedTab = _index;
@ -180,7 +188,7 @@ public class MageBook extends JComponent {
pageLeft.setVisible(false);
pageRight.setVisible(false);
addSetTabs();
showCards();
showCardsOrTokens();
}
});
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() {
jLayeredPane.removeAll();
addLeftRightPageButtons();
@ -232,6 +249,37 @@ public class MageBook extends JComponent {
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) {
if (cardDimension == null) {
cardDimension = new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight);
@ -252,6 +300,19 @@ public class MageBook extends JComponent {
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) {
CardCriteria criteria = new CardCriteria();
criteria.setCodes(set);
@ -268,6 +329,50 @@ public class MageBook extends JComponent {
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) {
try {
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) {
switch (size) {
case LAYOUT_3x3:
@ -415,6 +529,8 @@ public class MageBook extends JComponent {
private java.util.List<String> setsToDisplay = new ArrayList<>();
private final java.util.List<HoverButton> tabs = new ArrayList<>();
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 RIGHT_PANEL_IMAGE_PATH = "/book_right.jpg";

View file

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

View file

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

View file

@ -22,7 +22,6 @@ import javax.swing.JPopupMenu;
import javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.SwingUtilities;
import mage.cards.MageCard;
import mage.cards.action.ActionCallback;
import mage.cards.action.TransferData;
@ -67,7 +66,6 @@ public class MageActionCallback implements ActionCallback {
private Popup tooltipPopup;
private JPopupMenu jPopupMenu;
private BigCard bigCard;
protected static final DefaultActionCallback defaultCallback = DefaultActionCallback.getInstance();
private CardView tooltipCard;
private TransferData popupData;
@ -236,14 +234,14 @@ public class MageActionCallback implements ActionCallback {
this.startedDragging = false;
if (maxXOffset < MIN_X_OFFSET_REQUIRED) { // we need this for protection from small card movements
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
hideTooltipPopup();
}
e.consume();
} else {
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
hideTooltipPopup();
e.consume();
@ -464,7 +462,7 @@ public class MageActionCallback implements ActionCallback {
int notches = e.getWheelRotation();
if (enlargedWindowState != EnlargedWindowState.CLOSED) {
// 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
hideEnlargedCard();
handleOverNewView(transferData);

View file

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

View file

@ -140,13 +140,8 @@ public final class ImageHelper {
* @return
*/
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);
BufferedImage image = ImageIO.read(stream);
return image;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -16,7 +16,7 @@ public class TokensMtgImageSourceTest {
@Test
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", ""));
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 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 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) {
ObjectColor color = new ObjectColor(originalColor);
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_MINOR = 4;
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 = "";
private final int major;

View file

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

View file

@ -197,7 +197,7 @@ public class GameView implements Serializable {
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) {
spellsCastCurrentTurn = watcher.getAmountOfSpellsAllPlayersCastOnCurrentTurn();
} else {

View file

@ -62,8 +62,8 @@ public class PermanentView extends CardView {
private final boolean attachedToPermanent;
public PermanentView(Permanent permanent, Card card, UUID createdForPlayerId, Game game) {
super(permanent, game, permanent.getControllerId().equals(createdForPlayerId));
this.controlled = permanent.getControllerId().equals(createdForPlayerId);
super(permanent, game, (permanent.getControllerId() == null) ? false : permanent.getControllerId().equals(createdForPlayerId));
this.controlled = (permanent.getControllerId() == null) ? false : permanent.getControllerId().equals(createdForPlayerId);
this.rules = permanent.getRules(game);
this.tapped = permanent.isTapped();
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());
if (owner != null) {
this.nameOwner = owner.getName();

View file

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

View file

@ -24,11 +24,11 @@
* 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.deck;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.GregorianCalendar;
@ -56,13 +56,18 @@ public class Standard extends Constructed {
}
});
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();
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());
if (set.getReleaseDate().before(current.getTime()) // This stops spoiled sets from counting as "new" blocks
&& set.getParentSet() == null
&& set.getSetType() == SetType.EXPANSION) {
if (blocksAdded == 0 && !isFallBlock(set)) { // if the most current block is no fall block, 4 blocks are added
blocksToAdd++;
}
blocksAdded++;
}
}
@ -72,4 +77,11 @@ public class Standard extends Constructed {
banned.add("Smuggler's Copter");
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())
|| (commander.isPlaneswalker() && commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) {
if (!bannedCommander.contains(commander.getName())) {
FilterMana color = CardUtil.getColorIdentity(commander);
FilterMana color = commander.getColorIdentity();
for (Card card : deck.getCards()) {
if (!isCardFormatValid(card, commander, color)) {
valid = false;
@ -249,7 +249,7 @@ public class TinyLeaders extends Constructed {
* @return True if card has a valid color identity
*/
public boolean cardHasValideColor(FilterMana commander, Card card) {
FilterMana cardColor = CardUtil.getColorIdentity(card);
FilterMana cardColor = card.getColorIdentity();
return !(cardColor.isBlack() && !commander.isBlack()
|| cardColor.isBlue() && !commander.isBlue()
|| cardColor.isGreen() && !commander.isGreen()

View file

@ -77,7 +77,7 @@ class AetherfluxReservoirDynamicValue implements DynamicValue {
@Override
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());
}

View file

@ -88,7 +88,7 @@ class AggravateRequirementEffect extends RequirementEffect {
@Override
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) {
return watcher.wasDamaged(permanent, game);
}

View file

@ -140,7 +140,7 @@ class AlhammarretsArchiveReplacementEffect extends ReplacementEffectImpl {
if (event.getPlayerId().equals(source.getControllerId())) {
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) {
return true;
}

View file

@ -47,13 +47,12 @@ import mage.util.CardUtil;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public class AlphaAuthority extends CardImpl {
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");
@ -66,7 +65,7 @@ public class AlphaAuthority extends CardImpl {
// 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));
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");
ability.addEffect(effect);
this.addAbility(ability);
@ -95,7 +94,7 @@ class CantBeBlockedByMoreThanOneAttachedEffect extends ContinuousEffectImpl {
super(duration, Outcome.Benefit);
this.amount = amount;
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) {

View file

@ -137,7 +137,7 @@ class AngelicArbiterCantAttackTargetEffect extends RestrictionEffect {
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
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) {
return true;
}
@ -185,7 +185,7 @@ class AngelicArbiterEffect2 extends ContinuousRuleModifyingEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
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())) {
return true;
}

View file

@ -97,7 +97,7 @@ class AngelsTrumpetTapEffect extends OneShotEffect {
continue;
}
// 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))) {
continue;
}

View file

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

View file

@ -58,7 +58,7 @@ public class ArchiveTrap extends CardImpl {
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.
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.
this.getSpellAbility().addTarget(new TargetOpponent());
@ -80,7 +80,7 @@ class ArchiveTrapWatcher extends Watcher {
Set<UUID> playerIds = new HashSet<>();
public ArchiveTrapWatcher() {
super("LibrarySearched", WatcherScope.GAME);
super(ArchiveTrapWatcher.class.getSimpleName(), WatcherScope.GAME);
}
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();
public static Condition getInstance() {
return instance;
}
instance;
@Override
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());
if (controller != null && watcher != null) {
for (UUID playerId : watcher.getPlayersSearchedLibrary()) {

View file

@ -102,7 +102,7 @@ class ArchmageAscensionTriggeredAbility extends TriggeredAbilityImpl {
public boolean checkTrigger(GameEvent event, Game game) {
Permanent archmage = game.getPermanent(super.getSourceId());
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;
}

View file

@ -47,11 +47,11 @@ import java.util.UUID;
public class ArrowVolleyTrap extends CardImpl {
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");
// 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.
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();
public static Condition getInstance() {
return instance;
}
instance;
@Override
public boolean apply(Game game, Ability source) {

View file

@ -83,7 +83,7 @@ class AsmiraHolyAvengerWatcher extends Watcher {
private int creaturesCount = 0;
public AsmiraHolyAvengerWatcher() {
super("YourCreaturesDied", WatcherScope.PLAYER);
super(AsmiraHolyAvengerWatcher.class.getSimpleName(), WatcherScope.PLAYER);
condition = true;
}
@ -122,7 +122,7 @@ class AsmiraHolyAvengerDynamicValue implements DynamicValue {
@Override
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) {
return watcher.getCreaturesCount();
}

View file

@ -52,28 +52,26 @@ import mage.target.common.TargetCreatureOrPlayerAmount;
import mage.target.targetpointer.FixedTarget;
import mage.watchers.Watcher;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.*;
/**
* GATECRASH FAQ 11.01.2013
*
* <p>
* 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.
*
* <p>
* 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
* 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
* casting noncreature spells this turn, you can't choose to redirect the
* damage to a planeswalker he or she controls.
*
* <p>
* 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
* deal damage to the remaining legal targets according to the original damage
* division.
*
* <p>
* 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
* player will be dealt damage.
@ -83,7 +81,7 @@ import java.util.UUID;
public class AureliasFury extends CardImpl {
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.
@ -124,15 +122,15 @@ class AureliasFuryEffect extends OneShotEffect {
@Override
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) {
for(UUID creatureId : watcher.damagedCreatures) {
for (UUID creatureId : watcher.damagedCreatures) {
Permanent permanent = game.getPermanent(creatureId);
if (permanent != null) {
permanent.tap(game);
}
}
for(UUID playerId : watcher.damagedPlayers) {
for (UUID playerId : watcher.damagedPlayers) {
ContinuousEffect effect = new AureliasFuryCantCastEffect();
effect.setTargetPointer(new FixedTarget(playerId));
game.addEffect(effect, source);
@ -194,11 +192,11 @@ class AureliasFuryCantCastEffect extends ContinuousRuleModifyingEffectImpl {
class AureliasFuryDamagedByWatcher extends Watcher {
public List<UUID> damagedCreatures = new ArrayList<>();
public List<UUID> damagedPlayers = new ArrayList<>();
public Set<UUID> damagedCreatures = new HashSet<>();
public Set<UUID> damagedPlayers = new HashSet<>();
public AureliasFuryDamagedByWatcher() {
super("AureliasFuryDamagedByWatcher", WatcherScope.CARD);
super(AureliasFuryDamagedByWatcher.class.getSimpleName(), WatcherScope.CARD);
}
public AureliasFuryDamagedByWatcher(final AureliasFuryDamagedByWatcher watcher) {
@ -217,7 +215,7 @@ class AureliasFuryDamagedByWatcher extends Watcher {
if (event.getType() == EventType.DAMAGED_CREATURE) {
MageObject obj = game.getObject(event.getSourceId());
if (obj instanceof Spell) {
if (sourceId.equals(((Spell) obj).getSourceId()) && !damagedCreatures.contains(event.getTargetId())) {
if (sourceId.equals(((Spell) obj).getSourceId())) {
damagedCreatures.add(event.getTargetId());
}
}
@ -225,7 +223,7 @@ class AureliasFuryDamagedByWatcher extends Watcher {
if (event.getType() == EventType.DAMAGED_PLAYER) {
MageObject obj = game.getObject(event.getSourceId());
if (obj instanceof Spell) {
if (sourceId.equals(((Spell) obj).getSourceId()) && !damagedPlayers.contains(event.getTargetId())) {
if (sourceId.equals(((Spell) obj).getSourceId())) {
damagedPlayers.add(event.getTargetId());
}
}

View file

@ -81,7 +81,7 @@ class AvengingArrowTarget extends TargetPermanent {
@Override
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.damageSources.contains(id)) {
return super.canTarget(id, source, game);
@ -94,7 +94,7 @@ class AvengingArrowTarget extends TargetPermanent {
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
Set<UUID> availablePossibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
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) {
for (UUID targetId : availablePossibleTargets) {
Permanent permanent = game.getPermanent(targetId);

View file

@ -44,17 +44,16 @@ import java.util.List;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public class BalothCageTrap extends CardImpl {
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");
// 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.
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();
public static Condition getInstance() {
return instance;
}
instance;
@Override
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) {
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
List<Permanent> permanents = watcher.getThisTurnEnteringPermanents(opponentId);

View file

@ -102,7 +102,7 @@ class BerserkReplacementEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
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 false;
@ -122,7 +122,7 @@ class BerserkReplacementEffect extends ContinuousRuleModifyingEffectImpl {
class CombatDamageStepStartedWatcher extends Watcher {
public CombatDamageStepStartedWatcher() {
super("CombatDamageStepStarted", WatcherScope.GAME);
super(CombatDamageStepStartedWatcher.class.getSimpleName(), WatcherScope.GAME);
}
public CombatDamageStepStartedWatcher(final CombatDamageStepStartedWatcher watcher) {
@ -196,7 +196,7 @@ class BerserkDelayedDestroyEffect extends OneShotEffect {
if (controller != null) {
Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
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 (((AttackedThisTurnWatcher) watcher).getAttackedThisTurnCreatures().contains(new MageObjectReference(permanent, game))) {
return permanent.destroy(source.getSourceId(), game, false);

View file

@ -50,7 +50,6 @@ import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public class BloodLust extends CardImpl {
@ -62,12 +61,12 @@ public class BloodLust extends CardImpl {
}
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.
this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
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),
"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());
@ -104,13 +103,9 @@ class TargetMatchesFilterCondition implements Condition {
}
}
class TargetPermanentToughnessMinus1Value implements DynamicValue {
enum TargetPermanentToughnessMinus1Value implements DynamicValue {
private static final TargetPermanentToughnessMinus1Value instance = new TargetPermanentToughnessMinus1Value();
public static TargetPermanentToughnessMinus1Value getInstance() {
return instance;
}
instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@ -123,7 +118,7 @@ class TargetPermanentToughnessMinus1Value implements DynamicValue {
@Override
public TargetPermanentToughnessMinus1Value copy() {
return new TargetPermanentToughnessMinus1Value();
return instance;
}
@Override

View file

@ -96,7 +96,7 @@ class BloodcrazedGoblinEffect extends RestrictionEffect {
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
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 false;

View file

@ -134,7 +134,7 @@ class BontuTheGlorifiedRestrictionEffect extends RestrictionEffect {
public boolean applies(Permanent permanent, Ability source, Game game) {
if (permanent.getId().equals(source.getSourceId())) {
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
&& watcher != null) {
return (watcher.getAmountOfCreaturesDiesThisTurn(controller.getId()) == 0);

View file

@ -89,7 +89,7 @@ class BoseijuWhoSheltersAllWatcher extends Watcher {
public List<UUID> spells = new ArrayList<>();
public BoseijuWhoSheltersAllWatcher() {
super("ManaPaidFromBoseijuWhoSheltersAllWatcher", WatcherScope.GAME);
super(BoseijuWhoSheltersAllWatcher.class.getSimpleName(), WatcherScope.GAME);
}
public BoseijuWhoSheltersAllWatcher(final BoseijuWhoSheltersAllWatcher watcher) {
@ -158,7 +158,7 @@ class BoseijuWhoSheltersAllCantCounterEffect extends ContinuousRuleModifyingEffe
@Override
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());
if (spell != null && watcher.spells.contains(spell.getId())) {
if (filter.match(spell.getCard(), game)) {

View file

@ -48,13 +48,12 @@ import java.util.List;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public class BriarbridgePatrol extends CardImpl {
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("Warrior");
this.power = new MageInt(3);
@ -64,7 +63,7 @@ public class BriarbridgePatrol extends CardImpl {
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.
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();
public static Condition getInstance() {
return instance;
}
instance;
@Override
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) {
List<Permanent> sacrificedPermanents = watcher.getThisTurnSacrificedPermanents(source.getControllerId());
if (sacrificedPermanents != null && !sacrificedPermanents.isEmpty()) {
@ -109,4 +104,4 @@ class BriarbridgePatrolCondition implements Condition {
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.target.common.TargetCreatureOrPlayer;
import mage.watchers.Watcher;
import mage.watchers.common.MorbidWatcher;
import java.util.UUID;
@ -80,7 +81,7 @@ class BrimstoneVolleyEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
int damage = 3;
Watcher watcher = game.getState().getWatchers().get("Morbid");
Watcher watcher = game.getState().getWatchers().get(MorbidWatcher.class.getSimpleName());
if (watcher.conditionMet()) {
damage = 5;
}

View file

@ -86,7 +86,7 @@ class CallerOfTheClawWatcher extends Watcher {
private int creaturesCount = 0;
public CallerOfTheClawWatcher() {
super(CallerOfTheClawWatcher.class.getName(), WatcherScope.PLAYER);
super(CallerOfTheClawWatcher.class.getSimpleName(), WatcherScope.PLAYER);
condition = true;
}
@ -140,7 +140,7 @@ class CallerOfTheClawDynamicValue implements DynamicValue {
@Override
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) {
return watcher.getCreaturesCount();
}

View file

@ -40,18 +40,15 @@ import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.watchers.Watcher;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.*;
/**
*
* @author BetaSteward
*/
public class CathedralMembrane extends CardImpl {
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.power = new MageInt(0);
@ -120,7 +117,7 @@ class CathedralMembraneEffect extends OneShotEffect {
@Override
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) {
for (UUID uuid : watcher.blockedCreatures) {
Permanent permanent = game.getPermanent(uuid);
@ -135,10 +132,10 @@ class CathedralMembraneEffect extends OneShotEffect {
class CathedralMembraneWatcher extends Watcher {
public List<UUID> blockedCreatures = new ArrayList<>();
public Set<UUID> blockedCreatures = new HashSet<>();
public CathedralMembraneWatcher() {
super("CathedralMembraneWatcher", WatcherScope.CARD);
super(CathedralMembraneWatcher.class.getSimpleName(), WatcherScope.CARD);
}
public CathedralMembraneWatcher(final CathedralMembraneWatcher watcher) {
@ -154,11 +151,9 @@ class CathedralMembraneWatcher extends Watcher {
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.BLOCKER_DECLARED && event.getSourceId().equals(sourceId)) {
if (!blockedCreatures.contains(event.getTargetId())) {
blockedCreatures.add(event.getTargetId());
}
}
}
@Override
public void reset() {

View file

@ -152,7 +152,7 @@ class CavernOfSoulsWatcher extends Watcher {
private final String originalId;
public CavernOfSoulsWatcher(UUID originalId) {
super("ManaPaidFromCavernOfSoulsWatcher", WatcherScope.CARD);
super(CavernOfSoulsWatcher.class.getSimpleName(), WatcherScope.CARD);
this.originalId = originalId.toString();
}
@ -224,7 +224,7 @@ class CavernOfSoulsCantCounterEffect extends ContinuousRuleModifyingEffectImpl {
@Override
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());
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) {
Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
if (targetPlayer != null) {
CerebralVortexWatcher watcher = (CerebralVortexWatcher) game.getState().getWatchers().get("CerebralVortexWatcher");
CerebralVortexWatcher watcher = (CerebralVortexWatcher) game.getState().getWatchers().get(CerebralVortexWatcher.class.getSimpleName());
if (watcher != null) {
targetPlayer.damage(watcher.getDraws(targetPlayer.getId()), source.getSourceId(), game, false, true);
return true;
@ -108,7 +108,7 @@ class CerebralVortexWatcher extends Watcher {
private final Map<UUID, Integer> draws = new HashMap<>();
CerebralVortexWatcher() {
super("CerebralVortexWatcher", WatcherScope.GAME);
super(CerebralVortexWatcher.class.getSimpleName(), WatcherScope.GAME);
}
CerebralVortexWatcher(final CerebralVortexWatcher watcher) {
@ -136,10 +136,7 @@ class CerebralVortexWatcher extends Watcher {
}
public int getDraws(UUID playerId) {
if (draws.containsKey(playerId)) {
return draws.get(playerId);
}
return 0;
return draws.getOrDefault(playerId, 0);
}
@Override

View file

@ -113,7 +113,7 @@ class ChainsOfMephistophelesReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
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) {
return true;
}

View file

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

View file

@ -78,7 +78,7 @@ class SourceControllerLostLifeCount implements DynamicValue {
@Override
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) {
return watcher.getLiveLost(sourceAbility.getControllerId());
}

View file

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

View file

@ -49,17 +49,16 @@ import java.util.Set;
import java.util.UUID;
/**
*
* @author Rafbill
*/
public class CobraTrap extends CardImpl {
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");
// 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.
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();
public static Condition getInstance() {
return instance;
}
instance;
@Override
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());
}
@ -101,7 +96,7 @@ class CobraTrapWatcher extends Watcher {
Set<UUID> players = new HashSet<>();
public CobraTrapWatcher() {
super(CobraTrapWatcher.class.getName(), WatcherScope.GAME);
super(CobraTrapWatcher.class.getSimpleName(), WatcherScope.GAME);
}
public CobraTrapWatcher(final CobraTrapWatcher watcher) {

View file

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

View file

@ -128,7 +128,7 @@ class ContainmentPriestReplacementEffect extends ReplacementEffectImpl {
card = card.getSecondCardFace();
}
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())) {
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();
cards.add(topcard);
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);
}
}

View file

@ -107,7 +107,7 @@ class CurseOfExhaustionEffect extends ContinuousRuleModifyingEffectImpl {
if (enchantment != null && enchantment.getAttachedTo() != null) {
Player player = game.getPlayer(enchantment.getAttachedTo());
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) {
return true;
}

View file

@ -179,7 +179,7 @@ class CyclopeanTombEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
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) {
Set<MageObjectReference> landRef = watcher.landMiredByCyclopeanTombInstance(mor, game);
@ -221,7 +221,7 @@ class CyclopeanTombCounterWatcher extends Watcher {
public HashMap<MageObjectReference, Set<MageObjectReference>> counterData = new HashMap<>();
public CyclopeanTombCounterWatcher() {
super(CyclopeanTombCounterWatcher.class.getName(), WatcherScope.GAME);
super(CyclopeanTombCounterWatcher.class.getSimpleName(), WatcherScope.GAME);
}
public CyclopeanTombCounterWatcher(final CyclopeanTombCounterWatcher watcher) {

View file

@ -68,7 +68,7 @@ public class DeathSpark extends CardImpl {
new DoIfCostPaid(new ReturnSourceFromGraveyardToHandEffect(), new GenericManaCost(1)),
TargetController.YOU,
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."));
}
@ -82,13 +82,9 @@ public class DeathSpark extends CardImpl {
}
}
class DeathSparkCondition implements Condition {
enum DeathSparkCondition implements Condition {
private static final DeathSparkCondition instance = new DeathSparkCondition();
public static Condition getInstance() {
return instance;
}
instance;
@Override
public boolean apply(Game game, Ability source) {

View file

@ -44,13 +44,12 @@ import java.util.HashMap;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public class DescentOfTheDragons extends CardImpl {
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.
this.getSpellAbility().addEffect(new DescentOfTheDragonsEffect());
@ -95,18 +94,15 @@ class DescentOfTheDragonsEffect extends OneShotEffect {
if (permanent != null) {
UUID controllerOfTargetId = permanent.getControllerId();
if (permanent.destroy(source.getSourceId(), game, false)) {
if(playersWithTargets.containsKey(controllerOfTargetId)) {
playersWithTargets.put(controllerOfTargetId, playersWithTargets.get(controllerOfTargetId) + 1);
}
else {
playersWithTargets.put(controllerOfTargetId, 1);
}
int count = playersWithTargets.getOrDefault(controllerOfTargetId, 0);
playersWithTargets.put(controllerOfTargetId, count + 1);
}
}
}
}
DragonToken dragonToken = new DragonToken();
for(UUID playerId : playersWithTargets.keySet()) {
for (UUID playerId : playersWithTargets.keySet()) {
dragonToken.putOntoBattlefield(playersWithTargets.get(playerId), game, source.getSourceId(), playerId);
}
return true;

View file

@ -116,7 +116,7 @@ class DraconicRoarEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
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())) {
Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source));
if (permanent != null) {

View file

@ -46,13 +46,12 @@ import java.util.Map.Entry;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public class DreamSalvage extends CardImpl {
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.
@ -77,7 +76,7 @@ class CardsDiscardedThisTurnWatcher extends Watcher {
private final Map<UUID, Integer> amountOfCardsDiscardedThisTurn = new HashMap<>();
public CardsDiscardedThisTurnWatcher() {
super("CardsDiscardedThisTurnWatcher", WatcherScope.GAME);
super(CardsDiscardedThisTurnWatcher.class.getSimpleName(), WatcherScope.GAME);
}
public CardsDiscardedThisTurnWatcher(final CardsDiscardedThisTurnWatcher watcher) {
@ -92,23 +91,13 @@ class CardsDiscardedThisTurnWatcher extends Watcher {
if (event.getType() == GameEvent.EventType.DISCARDED_CARD) {
UUID playerId = event.getPlayerId();
if (playerId != null) {
Integer amount = amountOfCardsDiscardedThisTurn.get(playerId);
if (amount == null) {
amount = 1;
} else {
amount++;
}
amountOfCardsDiscardedThisTurn.put(playerId, amount);
amountOfCardsDiscardedThisTurn.put(playerId, getAmountCardsDiscarded(playerId) + 1);
}
}
}
public int getAmountCardsDiscarded(UUID playerId) {
Integer amount = amountOfCardsDiscardedThisTurn.get(playerId);
if (amount != null) {
return amount;
}
return 0;
return amountOfCardsDiscardedThisTurn.getOrDefault(playerId, 0);
}
@Override
@ -140,7 +129,7 @@ class DreamSalvageEffect extends OneShotEffect {
@Override
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 controller = game.getPlayer(source.getControllerId());
if (targetOpponent != null

View file

@ -82,7 +82,7 @@ class CastBlueSpellThisTurnCondition implements Condition {
@Override
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) {
for (Spell spell : watcher.getSpellsCastThisTurn(source.getControllerId())) {
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()) {
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();
return attackedThisTurnCreatures.isEmpty()
|| (attackedThisTurnCreatures.size() == 1 && attackedThisTurnCreatures.contains(new MageObjectReference(attacker, game)));
@ -134,7 +134,7 @@ class NoMoreThanOneCreatureCanBlockEachTurnEffect extends RestrictionEffect {
if (!game.getCombat().getBlockers().isEmpty()) {
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();
MageObjectReference blockerReference = new MageObjectReference(blocker.getId(), blocker.getZoneChangeCounter(game), game);
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
public boolean apply(Game game, Ability source) {
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
&& watcher != null
&& watcher.AnotherCreatureEnteredBattlefieldUnderPlayersControlLastTurn(sourcePermanent, game);

View file

@ -104,7 +104,7 @@ class ErayoSoratamiAscendantTriggeredAbility extends TriggeredAbilityImpl {
@Override
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;
}
@ -153,7 +153,7 @@ class ErayosEssenceTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
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) {
for (Effect effect : getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getTargetId()));

View file

@ -45,13 +45,12 @@ import java.util.HashMap;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public class ErdwalIlluminator extends CardImpl {
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.power = new MageInt(1);
this.toughness = new MageInt(3);
@ -91,7 +90,7 @@ class ErdwalIlluminatorTriggeredAbility extends TriggeredAbilityImpl {
@Override
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;
}
@ -111,7 +110,7 @@ class InvestigatedWatcher extends Watcher {
private final HashMap<UUID, Integer> timesInvestigated = new HashMap<>();
public InvestigatedWatcher() {
super(InvestigatedWatcher.class.getName(), WatcherScope.GAME);
super(InvestigatedWatcher.class.getSimpleName(), WatcherScope.GAME);
}
public InvestigatedWatcher(final InvestigatedWatcher watcher) {
@ -126,11 +125,8 @@ class InvestigatedWatcher extends Watcher {
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == EventType.INVESTIGATED) {
if (!timesInvestigated.containsKey(event.getPlayerId())) {
timesInvestigated.put(event.getPlayerId(), 1);
} else {
timesInvestigated.put(event.getPlayerId(), timesInvestigated.get(event.getPlayerId()) + 1);
}
timesInvestigated.put(event.getPlayerId(), getTimesInvestigated(event.getPlayerId()) + 1);
}
}
@ -141,9 +137,6 @@ class InvestigatedWatcher extends Watcher {
}
public int getTimesInvestigated(UUID playerId) {
if (timesInvestigated.containsKey(playerId)) {
return timesInvestigated.get(playerId);
}
return 0;
return timesInvestigated.getOrDefault(playerId, 0);
}
}

View file

@ -80,7 +80,7 @@ class ErgRaidersCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
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
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<>();
public EtherswornCanonistWatcher() {
super(EtherswornCanonistWatcher.class.getName(), WatcherScope.GAME);
super(EtherswornCanonistWatcher.class.getSimpleName(), WatcherScope.GAME);
}
public EtherswornCanonistWatcher(final EtherswornCanonistWatcher watcher) {
@ -143,7 +143,7 @@ class EtherswornCanonistReplacementEffect extends ContinuousRuleModifyingEffectI
public boolean applies(GameEvent event, Ability source, Game game) {
Card card = game.getCard(event.getSourceId());
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 false;

View file

@ -84,7 +84,7 @@ class TargetCreaturePermanentThatDealtDamageThisTurn extends TargetPermanent {
@Override
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.damageSources.contains(id)) {
return super.canTarget(id, source, game);
@ -101,7 +101,7 @@ class TargetCreaturePermanentThatDealtDamageThisTurn extends TargetPermanent {
}
int count = 0;
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) {
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game)) {
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) {
Set<UUID> availablePossibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
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) {
for (UUID targetId : availablePossibleTargets) {
Permanent permanent = game.getPermanent(targetId);

View file

@ -49,7 +49,6 @@ import java.util.Set;
import java.util.UUID;
/**
*
* @author spjspj
*/
public class FairgroundsTrumpeter extends CardImpl {
@ -63,7 +62,7 @@ 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.
this.addAbility(new ConditionalTriggeredAbility(new BeginningOfEndStepTriggeredAbility(
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}."),
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();
public static Condition getInstance() {
return instance;
}
instance;
@Override
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());
}
@ -104,7 +99,7 @@ class FairgroundsTrumpeterWatcher extends Watcher {
private final Set<UUID> players = new HashSet<>();
public FairgroundsTrumpeterWatcher() {
super(FairgroundsTrumpeterWatcher.class.getName(), WatcherScope.GAME);
super(FairgroundsTrumpeterWatcher.class.getSimpleName(), WatcherScope.GAME);
}
public FairgroundsTrumpeterWatcher(final FairgroundsTrumpeterWatcher watcher) {

View file

@ -82,7 +82,7 @@ class FaithsRewardEffect extends OneShotEffect {
@Override
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) {
for (UUID id : watcher.cards) {
Card c = game.getCard(id);
@ -105,7 +105,7 @@ class FaithsRewardWatcher extends Watcher {
ArrayList<UUID> cards = new ArrayList<>();
public FaithsRewardWatcher() {
super("FaithsRewardWatcher", WatcherScope.GAME);
super(FaithsRewardWatcher.class.getSimpleName(), WatcherScope.GAME);
}
public FaithsRewardWatcher(final FaithsRewardWatcher watcher) {

View file

@ -59,7 +59,7 @@ public class FeastOnTheFallen extends CardImpl {
new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
new AddCountersTargetEffect(CounterType.P1P1.createInstance()),
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.");
ability.addTarget(new TargetControlledCreaturePermanent());
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();
public static FeastOnTheFallenCondition getInstance() {
return instance;
}
instance;
@Override
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) {
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
if (watcher.getLiveLostLastTurn(opponentId) > 0) {

View file

@ -98,7 +98,7 @@ class FellShepherdWatcher extends Watcher {
private Set<UUID> creatureIds = new HashSet<>();
public FellShepherdWatcher() {
super("YourCreaturesPutToGraveFromBattlefield", WatcherScope.PLAYER);
super(FellShepherdWatcher.class.getSimpleName(), WatcherScope.PLAYER);
condition = true;
}
@ -151,7 +151,7 @@ class FellShepherdEffect extends OneShotEffect {
@Override
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) {
StringBuilder sb = new StringBuilder();
for (UUID creatureId : watcher.getCreaturesIds()) {

View file

@ -72,7 +72,7 @@ class FinalPunishmentAmount implements DynamicValue {
@Override
public int calculate(Game game, Ability source, Effect effect) {
AmountOfDamageAPlayerReceivedThisTurnWatcher watcher
= (AmountOfDamageAPlayerReceivedThisTurnWatcher) game.getState().getWatchers().get("AmountOfDamageReceivedThisTurn");
= (AmountOfDamageAPlayerReceivedThisTurnWatcher) game.getState().getWatchers().get(AmountOfDamageAPlayerReceivedThisTurnWatcher.class.getSimpleName());
if(watcher != null) {
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.
Ability ability = new ConditionalTriggeredAbility(
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");
this.addAbility(ability);
// {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();
public static SourceOnBattelfieldOrGraveyardCondition getInstance() {
return instance;
}
instance;
@Override
public boolean apply(Game game, Ability source) {

View file

@ -84,7 +84,7 @@ class FirstResponseEffect extends OneShotEffect {
@Override
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.getLiveLostLastTurn(source.getControllerId()) > 0) {
return new CreateTokenEffect(new SoldierToken()).apply(game, source);

View file

@ -103,7 +103,7 @@ class FlamebreakCantRegenerateEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
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) {
return watcher.wasDamaged(event.getTargetId(), game);
}

View file

@ -101,7 +101,7 @@ class FlashEffect extends OneShotEffect {
if (card != null) {
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('?');
if (player.chooseUse(Outcome.Benefit, sb.toString(), source, game)) {
reducedCost.clearPaid();

View file

@ -83,7 +83,7 @@ class FleshAllergyWatcher extends Watcher {
public int creaturesDiedThisTurn = 0;
public FleshAllergyWatcher() {
super("CreaturesDied", WatcherScope.GAME);
super(FleshAllergyWatcher.class.getSimpleName(), WatcherScope.GAME);
}
public FleshAllergyWatcher(final FleshAllergyWatcher watcher) {
@ -131,7 +131,7 @@ class FleshAllergyEffect extends OneShotEffect {
@Override
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));
if (permanent != null && watcher != null) {
Player player = game.getPlayer(permanent.getControllerId());

View file

@ -116,7 +116,7 @@ class FoulTongueInvocationEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
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())) {
controller.gainLife(4, game);
}

View file

@ -68,7 +68,7 @@ class FreshMeatDynamicValue implements DynamicValue {
@Override
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) {
return watcher.getAmountOfCreaturesDiesThisTurn(sourceAbility.getControllerId());
}

View file

@ -27,9 +27,8 @@
*/
package mage.cards.g;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility;
import mage.abilities.condition.common.CardsInControllerGraveCondition;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
@ -59,8 +58,9 @@ import mage.target.common.TargetCardInHand;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public class GateToTheAfterlife extends CardImpl {
@ -76,7 +76,7 @@ public class GateToTheAfterlife extends CardImpl {
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.
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.setText("Then you may draw a card. If you do, discard a card");
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 GeneratorServantWatcher() {
super("GeneratorServantWatcher", WatcherScope.CARD);
super(GeneratorServantWatcher.class.getSimpleName(), WatcherScope.CARD);
}
public GeneratorServantWatcher(final GeneratorServantWatcher watcher) {
@ -141,7 +141,7 @@ class GeneratorServantHasteEffect extends ContinuousEffectImpl {
@Override
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) {
for (Permanent perm : game.getBattlefield().getAllActivePermanents()) {
if (watcher.creatures.contains(perm.getId())) {

View file

@ -49,13 +49,12 @@ import java.util.Set;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class GiltspireAvenger extends CardImpl {
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("Soldier");
@ -97,7 +96,7 @@ class GiltspireAvengerTarget extends TargetPermanent {
@Override
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)) {
return super.canTarget(id, source, game);
}
@ -108,10 +107,10 @@ class GiltspireAvengerTarget extends TargetPermanent {
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
Set<UUID> availablePossibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
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) {
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);
}
}
@ -126,8 +125,8 @@ class GiltspireAvengerTarget extends TargetPermanent {
}
int count = 0;
MageObject targetSource = game.getObject(sourceId);
PlayerDamagedBySourceWatcher watcher = (PlayerDamagedBySourceWatcher) game.getState().getWatchers().get("PlayerDamagedBySource", sourceControllerId);
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game)) {
PlayerDamagedBySourceWatcher watcher = (PlayerDamagedBySourceWatcher) game.getState().getWatchers().get(PlayerDamagedBySourceWatcher.class.getSimpleName(), sourceControllerId);
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game)) {
if (!targets.containsKey(permanent.getId()) && permanent.canBeTargetedBy(targetSource, sourceControllerId, game)
&& watcher != null && watcher.hasSourceDoneDamage(permanent.getId(), game)) {
count++;

View file

@ -143,7 +143,7 @@ class GisaAndGeralfCastFromGraveyardEffect extends AsThoughEffectImpl {
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (objectId.equals(getTargetPointer().getFirst(game, source))) {
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();
}
}

View file

@ -99,7 +99,7 @@ class GleancrawlerEffect extends OneShotEffect {
@Override
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());
if (controller != null && watcher != null) {
Set<MageObjectReference> cardsToGraveyardThisTurn = watcher.getCardsPutToGraveyardFromBattlefield();

View file

@ -104,7 +104,7 @@ class GlyphKeeperAbility extends TriggeredAbilityImpl {
if (event.getTargetId().equals(this.getSourceId())) {
Permanent permanent = game.getPermanent(event.getTargetId());
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
&& watcher.notMoreThanOnceTargetedThisTurn(permanent, game)) {
for (Effect effect : getEffects()) {

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