Merge pull request #3256 from ingmargoudt/move_magepermanent_method

Move magepermanent method
This commit is contained in:
LevelX2 2017-04-28 22:34:08 +02:00 committed by GitHub
commit 2d427861f1
33 changed files with 186 additions and 321 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -67,7 +67,6 @@ public class MageActionCallback implements ActionCallback {
private Popup tooltipPopup; private Popup tooltipPopup;
private JPopupMenu jPopupMenu; private JPopupMenu jPopupMenu;
private BigCard bigCard; private BigCard bigCard;
protected static final DefaultActionCallback defaultCallback = DefaultActionCallback.getInstance();
private CardView tooltipCard; private CardView tooltipCard;
private TransferData popupData; private TransferData popupData;
@ -236,14 +235,14 @@ public class MageActionCallback implements ActionCallback {
this.startedDragging = false; this.startedDragging = false;
if (maxXOffset < MIN_X_OFFSET_REQUIRED) { // we need this for protection from small card movements if (maxXOffset < MIN_X_OFFSET_REQUIRED) { // we need this for protection from small card movements
transferData.component.requestFocusInWindow(); transferData.component.requestFocusInWindow();
defaultCallback.mouseClicked(e, transferData.gameId, transferData.card); DefaultActionCallback.instance.mouseClicked(transferData.gameId, transferData.card);
// Closes popup & enlarged view if a card/Permanent is selected // Closes popup & enlarged view if a card/Permanent is selected
hideTooltipPopup(); hideTooltipPopup();
} }
e.consume(); e.consume();
} else { } else {
transferData.component.requestFocusInWindow(); transferData.component.requestFocusInWindow();
defaultCallback.mouseClicked(e, transferData.gameId, transferData.card); DefaultActionCallback.instance.mouseClicked(transferData.gameId, transferData.card);
// Closes popup & enlarged view if a card/Permanent is selected // Closes popup & enlarged view if a card/Permanent is selected
hideTooltipPopup(); hideTooltipPopup();
e.consume(); e.consume();

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -117,7 +117,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
}); });
jComboBox1 = new JComboBox(); jComboBox1 = new JComboBox();
cardImageSource = MagicCardsImageSource.getInstance(); cardImageSource = MagicCardsImageSource.instance;
jComboBox1.setModel(jComboBox1Model); jComboBox1.setModel(jComboBox1Model);
jComboBox1.setAlignmentX(Component.LEFT_ALIGNMENT); jComboBox1.setAlignmentX(Component.LEFT_ALIGNMENT);
@ -125,28 +125,28 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
JComboBox cb = (JComboBox) e.getSource(); JComboBox cb = (JComboBox) e.getSource();
switch (cb.getSelectedIndex()) { switch (cb.getSelectedIndex()) {
case 0: case 0:
cardImageSource = MagicCardsImageSource.getInstance(); cardImageSource = MagicCardsImageSource.instance;
break; break;
case 1: case 1:
cardImageSource = WizardCardsImageSource.getInstance(); cardImageSource = WizardCardsImageSource.instance;
break; break;
case 2: case 2:
cardImageSource = MythicspoilerComSource.getInstance(); cardImageSource = MythicspoilerComSource.instance;
break; break;
case 3: case 3:
cardImageSource = TokensMtgImageSource.getInstance(); cardImageSource = TokensMtgImageSource.instance;
break; break;
case 4: case 4:
cardImageSource = MtgOnlTokensImageSource.getInstance(); cardImageSource = MtgOnlTokensImageSource.instance;
break; break;
case 5: case 5:
cardImageSource = AltMtgOnlTokensImageSource.getInstance(); cardImageSource = AltMtgOnlTokensImageSource.instance;
break; break;
case 6: case 6:
cardImageSource = GrabbagImageSource.getInstance(); cardImageSource = GrabbagImageSource.instance;
break; break;
case 7: case 7:
cardImageSource = MagidexImageSource.getInstance(); cardImageSource = MagidexImageSource.instance;
break; break;
} }
updateCardsToDownload(); updateCardsToDownload();

View file

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

View file

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

View file

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

View file

@ -28,6 +28,9 @@
package mage.view; package mage.view;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import com.sun.xml.internal.ws.util.StringUtils;
import mage.MageObject; import mage.MageObject;
import mage.ObjectColor; import mage.ObjectColor;
import mage.abilities.Abilities; import mage.abilities.Abilities;
@ -218,8 +221,8 @@ public class CardView extends SimpleCardView {
* @param card * @param card
* @param game * @param game
* @param controlled is the card view created for the card controller - used * @param controlled is the card view created for the card controller - used
* for morph / face down cards to know which player may see information for * for morph / face down cards to know which player may see information for
* the card * the card
*/ */
public CardView(Card card, Game game, boolean controlled) { public CardView(Card card, Game game, boolean controlled) {
this(card, game, controlled, false, false); this(card, game, controlled, false, false);
@ -245,12 +248,12 @@ public class CardView extends SimpleCardView {
/** /**
* @param card * @param card
* @param game * @param game
* @param controlled is the card view created for the card controller - used * @param controlled is the card view created for the card controller - used
* for morph / face down cards to know which player may see information for * for morph / face down cards to know which player may see information for
* the card * the card
* @param showFaceDownCard if true and the card is not on the battlefield, * @param showFaceDownCard if true and the card is not on the battlefield,
* also a face down card is shown in the view, face down cards will be shown * also a face down card is shown in the view, face down cards will be shown
* @param storeZone if true the card zone will be set in the zone attribute. * @param storeZone if true the card zone will be set in the zone attribute.
*/ */
public CardView(Card card, Game game, boolean controlled, boolean showFaceDownCard, boolean storeZone) { public CardView(Card card, Game game, boolean controlled, boolean showFaceDownCard, boolean storeZone) {
super(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), card.getTokenSetCode(), game != null, card.getTokenDescriptor()); super(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), card.getTokenSetCode(), game != null, card.getTokenDescriptor());
@ -963,44 +966,22 @@ public class CardView extends SimpleCardView {
} }
public String getColorText() { public String getColorText() {
if (getColor().getColorCount() == 0) { return StringUtils.capitalize(getColor().getDescription());
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 "";
} }
public String getTypeText() { public String getTypeText() {
StringBuilder type = new StringBuilder(); StringBuilder type = new StringBuilder();
for (SuperType superType : getSuperTypes()) { if (!getSuperTypes().isEmpty()) {
type.append(superType.toString()); type.append(String.join(" ", getSuperTypes().stream().map(SuperType::toString).collect(Collectors.toList())));
type.append(' '); type.append(" ");
} }
for (CardType cardType : getCardTypes()) { if (!getCardTypes().isEmpty()) {
type.append(cardType.toString()); type.append(String.join(" ", getCardTypes().stream().map(CardType::toString).collect(Collectors.toList())));
type.append(' '); type.append(" ");
} }
if (!getSubTypes().isEmpty()) { if (!getSubTypes().isEmpty()) {
type.append("- "); type.append(" - ");
for (String subType : getSubTypes()) { type.append(String.join(" ", getSubTypes()));
type.append(subType);
type.append(' ');
}
}
if (type.length() > 0) {
// remove trailing space
type.deleteCharAt(type.length() - 1);
} }
return type.toString(); return type.toString();
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -145,7 +145,7 @@ class HisokaMinamoSenseiCounterEffect extends OneShotEffect {
Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source));
if (spell != null) { if (spell != null) {
HisokaMinamoSenseiDiscardTargetCost cost = (HisokaMinamoSenseiDiscardTargetCost) source.getCosts().get(0); HisokaMinamoSenseiDiscardTargetCost cost = (HisokaMinamoSenseiDiscardTargetCost) source.getCosts().get(0);
if (cost != null && CardUtil.convertedManaCostsIsEqual(cost.getDiscardedCard(), spell)) { if (cost != null && cost.getDiscardedCard().getConvertedManaCost() == spell.getConvertedManaCost()) {
return game.getStack().counter(targetPointer.getFirst(game, source), source.getSourceId(), game); return game.getStack().counter(targetPointer.getFirst(game, source), source.getSourceId(), game);
} }
} }

View file

@ -33,6 +33,8 @@ import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCost;
import mage.abilities.costs.mana.ManaCostImpl;
import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
@ -113,7 +115,7 @@ class TariffEffect extends OneShotEffect {
Permanent creatureToPayFor = chooseOnePermanent(game, player, creatures); Permanent creatureToPayFor = chooseOnePermanent(game, player, creatures);
if (creatureToPayFor != null) { if (creatureToPayFor != null) {
ManaCost manaCost = CardUtil.removeVariableManaCost(creatureToPayFor.getManaCost()); ManaCosts manaCost = ManaCosts.removeVariableManaCost(creatureToPayFor.getManaCost());
String message = new StringBuilder("Pay ").append(manaCost.getText()).append(" (otherwise sacrifice ") String message = new StringBuilder("Pay ").append(manaCost.getText()).append(" (otherwise sacrifice ")
.append(creatureToPayFor.getName()).append(")?").toString(); .append(creatureToPayFor.getName()).append(")?").toString();
if (player.chooseUse(Outcome.Benefit, message, source, game)) { if (player.chooseUse(Outcome.Benefit, message, source, game)) {

View file

@ -96,7 +96,7 @@ public class CommanderColorIdentityTest extends CardTestCommander3PlayersFFA {
throw new IllegalArgumentException("Couldn't find the card " + cardName + " in the DB."); throw new IllegalArgumentException("Couldn't find the card " + cardName + " in the DB.");
} }
Card card = cardInfo.getCard(); Card card = cardInfo.getCard();
FilterMana filterMana = CardUtil.getColorIdentity(card); FilterMana filterMana = card.getColorIdentity();
return filterMana.toString(); return filterMana.toString();
} }
} }

View file

@ -61,4 +61,16 @@ public interface ManaCosts<T extends ManaCost> extends List<T>, ManaCost {
@Override @Override
ManaCosts<T> copy(); ManaCosts<T> copy();
static ManaCosts<ManaCost> removeVariableManaCost(ManaCosts<ManaCost> m) {
ManaCosts<ManaCost> manaCosts = new ManaCostsImpl<>();
for(ManaCost manaCost : m){
if(!(manaCost instanceof VariableManaCost)){
manaCosts.add(manaCost);
}
}
return manaCosts;
}
} }

View file

@ -75,7 +75,7 @@ public class CommanderColorIdentityManaAbility extends ActivatedManaAbilityImpl
for (UUID commanderId : controller.getCommandersIds()) { for (UUID commanderId : controller.getCommandersIds()) {
Card commander = game.getCard(commanderId); Card commander = game.getCard(commanderId);
if (commander != null) { if (commander != null) {
FilterMana commanderMana = CardUtil.getColorIdentity(commander); FilterMana commanderMana = commander.getColorIdentity();
if (commanderMana.isBlack()) { if (commanderMana.isBlack()) {
netMana.add(new Mana(ColoredManaSymbol.B)); netMana.add(new Mana(ColoredManaSymbol.B));
} }
@ -130,7 +130,7 @@ class CommanderIdentityManaEffect extends ManaEffect {
for (UUID commanderId : controller.getCommandersIds()) { for (UUID commanderId : controller.getCommandersIds()) {
Card commander = game.getCard(commanderId); Card commander = game.getCard(commanderId);
if (commander != null) { if (commander != null) {
FilterMana commanderMana = CardUtil.getColorIdentity(commander); FilterMana commanderMana = commander.getColorIdentity();
if (commanderMana.isWhite()) { if (commanderMana.isWhite()) {
choice.getChoices().add("White"); choice.getChoices().add("White");
} }

View file

@ -32,6 +32,7 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.Mana; import mage.Mana;
import mage.ObjectColor;
import mage.abilities.Abilities; import mage.abilities.Abilities;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility; import mage.abilities.SpellAbility;
@ -40,12 +41,21 @@ import mage.constants.Rarity;
import mage.constants.Zone; import mage.constants.Zone;
import mage.counters.Counter; import mage.counters.Counter;
import mage.counters.Counters; import mage.counters.Counters;
import mage.filter.FilterMana;
import mage.game.Game; import mage.game.Game;
import mage.game.GameState; import mage.game.GameState;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
public interface Card extends MageObject { public interface Card extends MageObject {
final String regexBlack = ".*\\x7b.{0,2}B.{0,2}\\x7d.*";
final String regexBlue = ".*\\x7b.{0,2}U.{0,2}\\x7d.*";
final String regexRed = ".*\\x7b.{0,2}R.{0,2}\\x7d.*";
final String regexGreen = ".*\\x7b.{0,2}G.{0,2}\\x7d.*";
final String regexWhite = ".*\\x7b.{0,2}W.{0,2}\\x7d.*";
UUID getOwnerId(); UUID getOwnerId();
String getCardNumber(); String getCardNumber();
@ -176,6 +186,67 @@ public interface Card extends MageObject {
*/ */
Card getMainCard(); Card getMainCard();
/**
* Gets the colors that are in the casting cost but also in the rules text
* as far as not included in reminder text.
*
* @return
*/
default FilterMana getColorIdentity() {
FilterMana mana = new FilterMana();
mana.setBlack(getManaCost().getText().matches(regexBlack));
mana.setBlue(getManaCost().getText().matches(regexBlue));
mana.setGreen(getManaCost().getText().matches(regexGreen));
mana.setRed(getManaCost().getText().matches(regexRed));
mana.setWhite(getManaCost().getText().matches(regexWhite));
for (String rule : getRules()) {
rule = rule.replaceAll("(?i)<i.*?</i>", ""); // Ignoring reminder text in italic
if (!mana.isBlack() && rule.matches(regexBlack)) {
mana.setBlack(true);
}
if (!mana.isBlue() && rule.matches(regexBlue)) {
mana.setBlue(true);
}
if (!mana.isGreen() && rule.matches(regexGreen)) {
mana.setGreen(true);
}
if (!mana.isRed() && rule.matches(regexRed)) {
mana.setRed(true);
}
if (!mana.isWhite() && rule.matches(regexWhite)) {
mana.setWhite(true);
}
}
if (isTransformable()) {
Card secondCard = getSecondCardFace();
ObjectColor color = secondCard.getColor(null);
mana.setBlack(mana.isBlack() || color.isBlack());
mana.setGreen(mana.isGreen() || color.isGreen());
mana.setRed(mana.isRed() || color.isRed());
mana.setBlue(mana.isBlue() || color.isBlue());
mana.setWhite(mana.isWhite() || color.isWhite());
for (String rule : secondCard.getRules()) {
rule = rule.replaceAll("(?i)<i.*?</i>", ""); // Ignoring reminder text in italic
if (!mana.isBlack() && rule.matches(regexBlack)) {
mana.setBlack(true);
}
if (!mana.isBlue() && rule.matches(regexBlue)) {
mana.setBlue(true);
}
if (!mana.isGreen() && rule.matches(regexGreen)) {
mana.setGreen(true);
}
if (!mana.isRed() && rule.matches(regexRed)) {
mana.setRed(true);
}
if (!mana.isWhite() && rule.matches(regexWhite)) {
mana.setWhite(true);
}
}
}
return mana;
}
} }

View file

@ -31,6 +31,7 @@ import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.Mana; import mage.Mana;
import mage.ObjectColor; import mage.ObjectColor;
@ -52,11 +53,6 @@ import mage.util.functions.CopyTokenFunction;
*/ */
public final class CardUtil { public final class CardUtil {
private static final String regexBlack = ".*\\x7b.{0,2}B.{0,2}\\x7d.*";
private static final String regexBlue = ".*\\x7b.{0,2}U.{0,2}\\x7d.*";
private static final String regexRed = ".*\\x7b.{0,2}R.{0,2}\\x7d.*";
private static final String regexGreen = ".*\\x7b.{0,2}G.{0,2}\\x7d.*";
private static final String regexWhite = ".*\\x7b.{0,2}W.{0,2}\\x7d.*";
private static final String SOURCE_EXILE_ZONE_TEXT = "SourceExileZone"; private static final String SOURCE_EXILE_ZONE_TEXT = "SourceExileZone";
@ -80,10 +76,6 @@ public final class CardUtil {
"Trap", "Arcane"}; "Trap", "Arcane"};
private static final Set<String> NON_CREATURE_SUBTYPES = new HashSet<>(Arrays.asList(NON_CHANGELING_SUBTYPES_VALUES)); private static final Set<String> NON_CREATURE_SUBTYPES = new HashSet<>(Arrays.asList(NON_CHANGELING_SUBTYPES_VALUES));
/** /**
* Increase spell or ability cost to be paid. * Increase spell or ability cost to be paid.
* *
@ -163,15 +155,6 @@ public final class CardUtil {
return adjustedCost; return adjustedCost;
} }
public static ManaCosts<ManaCost> removeVariableManaCost(ManaCosts<ManaCost> manaCosts) {
ManaCosts<ManaCost> adjustedCost = new ManaCostsImpl<>();
for (ManaCost manaCost : manaCosts) {
if (!(manaCost instanceof VariableManaCost)) {
adjustedCost.add(manaCost);
}
}
return adjustedCost;
}
public static void reduceCost(SpellAbility spellAbility, ManaCosts<ManaCost> manaCostsToReduce) { public static void reduceCost(SpellAbility spellAbility, ManaCosts<ManaCost> manaCostsToReduce) {
adjustCost(spellAbility, manaCostsToReduce, true); adjustCost(spellAbility, manaCostsToReduce, true);
@ -193,8 +176,8 @@ public final class CardUtil {
* *
* @param spellAbility * @param spellAbility
* @param manaCostsToReduce costs to reduce * @param manaCostsToReduce costs to reduce
* @param convertToGeneric colored mana does reduce generic mana if no * @param convertToGeneric colored mana does reduce generic mana if no
* appropriate colored mana is in the costs included * appropriate colored mana is in the costs included
*/ */
public static void adjustCost(SpellAbility spellAbility, ManaCosts<ManaCost> manaCostsToReduce, boolean convertToGeneric) { public static void adjustCost(SpellAbility spellAbility, ManaCosts<ManaCost> manaCostsToReduce, boolean convertToGeneric) {
ManaCosts<ManaCost> previousCost = spellAbility.getManaCostsToPay(); ManaCosts<ManaCost> previousCost = spellAbility.getManaCostsToPay();
@ -284,8 +267,8 @@ public final class CardUtil {
} }
} }
if(mana.getColorless() > 0 && reduceMana.getColorless() > 0) { if (mana.getColorless() > 0 && reduceMana.getColorless() > 0) {
if(reduceMana.getColorless() > mana.getColorless()) { if (reduceMana.getColorless() > mana.getColorless()) {
reduceMana.setColorless(reduceMana.getColorless() - mana.getColorless()); reduceMana.setColorless(reduceMana.getColorless() - mana.getColorless());
mana.setColorless(0); mana.setColorless(0);
} else { } else {
@ -379,7 +362,7 @@ public final class CardUtil {
* *
* @param number number to convert to text * @param number number to convert to text
* @param forOne if the number is 1, this string will be returnedinstead of * @param forOne if the number is 1, this string will be returnedinstead of
* "one". * "one".
* @return * @return
*/ */
public static String numberToText(int number, String forOne) { public static String numberToText(int number, String forOne) {
@ -424,7 +407,7 @@ public final class CardUtil {
/** /**
* Creates and saves a (card + zoneChangeCounter) specific exileId. * Creates and saves a (card + zoneChangeCounter) specific exileId.
* *
* @param game the current game * @param game the current game
* @param source source ability * @param source source ability
* @return the specific UUID * @return the specific UUID
*/ */
@ -459,9 +442,9 @@ public final class CardUtil {
* be specific to a permanent instance. So they won't match, if a permanent * be specific to a permanent instance. So they won't match, if a permanent
* was e.g. exiled and came back immediately. * was e.g. exiled and came back immediately.
* *
* @param text short value to describe the value * @param text short value to describe the value
* @param cardId id of the card * @param cardId id of the card
* @param game the game * @param game the game
* @return * @return
*/ */
public static String getCardZoneString(String text, UUID cardId, Game game) { public static String getCardZoneString(String text, UUID cardId, Game game) {
@ -521,91 +504,7 @@ public final class CardUtil {
return "<font color = 'blue'>" + text + "</font>"; return "<font color = 'blue'>" + text + "</font>";
} }
public static boolean convertedManaCostsIsEqual(MageObject object1, MageObject object2) {
Set<Integer> cmcObject1 = getCMC(object1);
Set<Integer> cmcObject2 = getCMC(object2);
for (Integer integer : cmcObject1) {
if (cmcObject2.contains(integer)) {
return true;
}
}
return false;
}
public static Set<Integer> getCMC(MageObject object) {
Set<Integer> cmcObject = new HashSet<>();
if (object instanceof Spell) {
cmcObject.add(object.getConvertedManaCost());
} else if (object instanceof Card) {
Card card = (Card) object;
cmcObject.add(card.getConvertedManaCost());
}
return cmcObject;
}
/**
* Gets the colors that are in the casting cost but also in the rules text
* as far as not included in reminder text.
*
* @param card
* @return
*/
public static FilterMana getColorIdentity(Card card) {
FilterMana mana = new FilterMana();
mana.setBlack(card.getManaCost().getText().matches(regexBlack));
mana.setBlue(card.getManaCost().getText().matches(regexBlue));
mana.setGreen(card.getManaCost().getText().matches(regexGreen));
mana.setRed(card.getManaCost().getText().matches(regexRed));
mana.setWhite(card.getManaCost().getText().matches(regexWhite));
for (String rule : card.getRules()) {
rule = rule.replaceAll("(?i)<i.*?</i>", ""); // Ignoring reminder text in italic
if (!mana.isBlack() && rule.matches(regexBlack)) {
mana.setBlack(true);
}
if (!mana.isBlue() && rule.matches(regexBlue)) {
mana.setBlue(true);
}
if (!mana.isGreen() && rule.matches(regexGreen)) {
mana.setGreen(true);
}
if (!mana.isRed() && rule.matches(regexRed)) {
mana.setRed(true);
}
if (!mana.isWhite() && rule.matches(regexWhite)) {
mana.setWhite(true);
}
}
if (card.isTransformable()) {
Card secondCard = card.getSecondCardFace();
ObjectColor color = secondCard.getColor(null);
mana.setBlack(mana.isBlack() || color.isBlack());
mana.setGreen(mana.isGreen() || color.isGreen());
mana.setRed(mana.isRed() || color.isRed());
mana.setBlue(mana.isBlue() || color.isBlue());
mana.setWhite(mana.isWhite() || color.isWhite());
for (String rule : secondCard.getRules()) {
rule = rule.replaceAll("(?i)<i.*?</i>", ""); // Ignoring reminder text in italic
if (!mana.isBlack() && rule.matches(regexBlack)) {
mana.setBlack(true);
}
if (!mana.isBlue() && rule.matches(regexBlue)) {
mana.setBlue(true);
}
if (!mana.isGreen() && rule.matches(regexGreen)) {
mana.setGreen(true);
}
if (!mana.isRed() && rule.matches(regexRed)) {
mana.setRed(true);
}
if (!mana.isWhite() && rule.matches(regexWhite)) {
mana.setWhite(true);
}
}
}
return mana;
}
public static boolean isNonCreatureSubtype(String subtype) { public static boolean isNonCreatureSubtype(String subtype) {
return NON_CREATURE_SUBTYPES.contains(subtype); return NON_CREATURE_SUBTYPES.contains(subtype);