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")
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

@ -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

@ -67,7 +67,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 +235,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();

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();

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

@ -28,6 +28,9 @@
package mage.view;
import java.util.*;
import java.util.stream.Collectors;
import com.sun.xml.internal.ws.util.StringUtils;
import mage.MageObject;
import mage.ObjectColor;
import mage.abilities.Abilities;
@ -218,8 +221,8 @@ public class CardView extends SimpleCardView {
* @param card
* @param game
* @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
* the card
* for morph / face down cards to know which player may see information for
* the card
*/
public CardView(Card card, Game game, boolean controlled) {
this(card, game, controlled, false, false);
@ -245,12 +248,12 @@ public class CardView extends SimpleCardView {
/**
* @param card
* @param game
* @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
* the card
* @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
* the card
* @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
* @param storeZone if true the card zone will be set in the zone attribute.
* 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.
*/
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());
@ -963,44 +966,22 @@ 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 "";
return StringUtils.capitalize(getColor().getDescription());
}
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

@ -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

@ -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

@ -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

@ -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

@ -145,7 +145,7 @@ class HisokaMinamoSenseiCounterEffect extends OneShotEffect {
Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source));
if (spell != null) {
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);
}
}

View file

@ -33,6 +33,8 @@ import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
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.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -113,7 +115,7 @@ class TariffEffect extends OneShotEffect {
Permanent creatureToPayFor = chooseOnePermanent(game, player, creatures);
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 ")
.append(creatureToPayFor.getName()).append(")?").toString();
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.");
}
Card card = cardInfo.getCard();
FilterMana filterMana = CardUtil.getColorIdentity(card);
FilterMana filterMana = card.getColorIdentity();
return filterMana.toString();
}
}

View file

@ -61,4 +61,16 @@ public interface ManaCosts<T extends ManaCost> extends List<T>, ManaCost {
@Override
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()) {
Card commander = game.getCard(commanderId);
if (commander != null) {
FilterMana commanderMana = CardUtil.getColorIdentity(commander);
FilterMana commanderMana = commander.getColorIdentity();
if (commanderMana.isBlack()) {
netMana.add(new Mana(ColoredManaSymbol.B));
}
@ -130,7 +130,7 @@ class CommanderIdentityManaEffect extends ManaEffect {
for (UUID commanderId : controller.getCommandersIds()) {
Card commander = game.getCard(commanderId);
if (commander != null) {
FilterMana commanderMana = CardUtil.getColorIdentity(commander);
FilterMana commanderMana = commander.getColorIdentity();
if (commanderMana.isWhite()) {
choice.getChoices().add("White");
}

View file

@ -32,6 +32,7 @@ import java.util.List;
import java.util.UUID;
import mage.MageObject;
import mage.Mana;
import mage.ObjectColor;
import mage.abilities.Abilities;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
@ -40,12 +41,21 @@ import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.Counter;
import mage.counters.Counters;
import mage.filter.FilterMana;
import mage.game.Game;
import mage.game.GameState;
import mage.game.permanent.Permanent;
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();
String getCardNumber();
@ -176,6 +186,67 @@ public interface Card extends MageObject {
*/
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.Set;
import java.util.UUID;
import mage.MageObject;
import mage.Mana;
import mage.ObjectColor;
@ -52,11 +53,6 @@ import mage.util.functions.CopyTokenFunction;
*/
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";
@ -80,10 +76,6 @@ public final class CardUtil {
"Trap", "Arcane"};
private static final Set<String> NON_CREATURE_SUBTYPES = new HashSet<>(Arrays.asList(NON_CHANGELING_SUBTYPES_VALUES));
/**
* Increase spell or ability cost to be paid.
*
@ -163,15 +155,6 @@ public final class CardUtil {
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) {
adjustCost(spellAbility, manaCostsToReduce, true);
@ -193,8 +176,8 @@ public final class CardUtil {
*
* @param spellAbility
* @param manaCostsToReduce costs to reduce
* @param convertToGeneric colored mana does reduce generic mana if no
* appropriate colored mana is in the costs included
* @param convertToGeneric colored mana does reduce generic mana if no
* appropriate colored mana is in the costs included
*/
public static void adjustCost(SpellAbility spellAbility, ManaCosts<ManaCost> manaCostsToReduce, boolean convertToGeneric) {
ManaCosts<ManaCost> previousCost = spellAbility.getManaCostsToPay();
@ -284,8 +267,8 @@ public final class CardUtil {
}
}
if(mana.getColorless() > 0 && reduceMana.getColorless() > 0) {
if(reduceMana.getColorless() > mana.getColorless()) {
if (mana.getColorless() > 0 && reduceMana.getColorless() > 0) {
if (reduceMana.getColorless() > mana.getColorless()) {
reduceMana.setColorless(reduceMana.getColorless() - mana.getColorless());
mana.setColorless(0);
} else {
@ -379,7 +362,7 @@ public final class CardUtil {
*
* @param number number to convert to text
* @param forOne if the number is 1, this string will be returnedinstead of
* "one".
* "one".
* @return
*/
public static String numberToText(int number, String forOne) {
@ -424,7 +407,7 @@ public final class CardUtil {
/**
* Creates and saves a (card + zoneChangeCounter) specific exileId.
*
* @param game the current game
* @param game the current game
* @param source source ability
* @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
* 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 game the game
* @param game the game
* @return
*/
public static String getCardZoneString(String text, UUID cardId, Game game) {
@ -521,91 +504,7 @@ public final class CardUtil {
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) {
return NON_CREATURE_SUBTYPES.contains(subtype);