diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java index 5d3bf90c67..1854a9ff3e 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java @@ -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); } diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/TinyLeaders.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/TinyLeaders.java index 6fb852e129..11a170899a 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/TinyLeaders.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/TinyLeaders.java @@ -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() diff --git a/Mage.Sets/src/mage/cards/c/Counterbalance.java b/Mage.Sets/src/mage/cards/c/Counterbalance.java index 920c06f7b2..7149248f74 100644 --- a/Mage.Sets/src/mage/cards/c/Counterbalance.java +++ b/Mage.Sets/src/mage/cards/c/Counterbalance.java @@ -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); } } diff --git a/Mage.Sets/src/mage/cards/h/HisokaMinamoSensei.java b/Mage.Sets/src/mage/cards/h/HisokaMinamoSensei.java index af67d55df0..bd37ebd2f8 100644 --- a/Mage.Sets/src/mage/cards/h/HisokaMinamoSensei.java +++ b/Mage.Sets/src/mage/cards/h/HisokaMinamoSensei.java @@ -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); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/commander/CommanderColorIdentityTest.java b/Mage.Tests/src/test/java/org/mage/test/commander/CommanderColorIdentityTest.java index 346839bac5..f6d0fc77bf 100644 --- a/Mage.Tests/src/test/java/org/mage/test/commander/CommanderColorIdentityTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/commander/CommanderColorIdentityTest.java @@ -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(); } } diff --git a/Mage/src/main/java/mage/abilities/mana/CommanderColorIdentityManaAbility.java b/Mage/src/main/java/mage/abilities/mana/CommanderColorIdentityManaAbility.java index 8e2a7c2330..3f0a768997 100644 --- a/Mage/src/main/java/mage/abilities/mana/CommanderColorIdentityManaAbility.java +++ b/Mage/src/main/java/mage/abilities/mana/CommanderColorIdentityManaAbility.java @@ -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"); } diff --git a/Mage/src/main/java/mage/cards/Card.java b/Mage/src/main/java/mage/cards/Card.java index 49e41a9b21..8e7debf751 100644 --- a/Mage/src/main/java/mage/cards/Card.java +++ b/Mage/src/main/java/mage/cards/Card.java @@ -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)", ""); // 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)", ""); // 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; + } } diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java index 7298f274c6..676967c654 100644 --- a/Mage/src/main/java/mage/util/CardUtil.java +++ b/Mage/src/main/java/mage/util/CardUtil.java @@ -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,38 +53,30 @@ 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"; static final String[] numberStrings = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", - "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "ninteen", "twenty"}; + "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "ninteen", "twenty"}; public static final String[] NON_CHANGELING_SUBTYPES_VALUES = new String[]{ - // basic lands subtypes - "Mountain", "Forest", "Plains", "Swamp", "Island", - // Enchantment subtypes - "Aura", "Curse", "Shrine", - // Artifact subtypes - "Clue", "Equipment", "Fortification", "Contraption", "Vehicle", - // Land subtypes - "Desert", "Gate", "Lair", "Locus", "Urza's", "Mine", "Power-Plant", "Tower", - // Planeswalker subtypes - "Ajani", "Arlinn", "Ashiok", "Bolas", "Chandra", "Dack", "Daretti", "Domri", "Dovin", "Elspeth", "Freyalise", "Garruk", "Gideon", "Jace", - "Karn", "Kiora", "Koth", "Liliana", "Nahiri", "Nissa", "Narset", "Nixilis", "Ral", "Saheeli", "Sarkhan", "Sorin", "Tamiyo", "Teferi", - "Tezzeret", "Tibalt", "Ugin", "Venser", "Vraska", "Xenagos", - // Instant sorcery subtypes - "Trap", "Arcane"}; + // basic lands subtypes + "Mountain", "Forest", "Plains", "Swamp", "Island", + // Enchantment subtypes + "Aura", "Curse", "Shrine", + // Artifact subtypes + "Clue", "Equipment", "Fortification", "Contraption", "Vehicle", + // Land subtypes + "Desert", "Gate", "Lair", "Locus", "Urza's", "Mine", "Power-Plant", "Tower", + // Planeswalker subtypes + "Ajani", "Arlinn", "Ashiok", "Bolas", "Chandra", "Dack", "Daretti", "Domri", "Dovin", "Elspeth", "Freyalise", "Garruk", "Gideon", "Jace", + "Karn", "Kiora", "Koth", "Liliana", "Nahiri", "Nissa", "Narset", "Nixilis", "Ral", "Saheeli", "Sarkhan", "Sorin", "Tamiyo", "Teferi", + "Tezzeret", "Tibalt", "Ugin", "Venser", "Vraska", "Xenagos", + // Instant sorcery subtypes + "Trap", "Arcane"}; public static final Set NON_CREATURE_SUBTYPES = new HashSet<>(Arrays.asList(NON_CHANGELING_SUBTYPES_VALUES)); - - - /** * Increase spell or ability cost to be paid. * @@ -164,7 +157,6 @@ public final class CardUtil { } - public static void reduceCost(SpellAbility spellAbility, ManaCosts manaCostsToReduce) { adjustCost(spellAbility, manaCostsToReduce, true); } @@ -185,8 +177,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 manaCostsToReduce, boolean convertToGeneric) { ManaCosts previousCost = spellAbility.getManaCostsToPay(); @@ -276,8 +268,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 { @@ -371,7 +363,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) { @@ -416,7 +408,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 */ @@ -451,9 +443,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) { @@ -513,91 +505,7 @@ public final class CardUtil { return "" + text + ""; } - public static boolean convertedManaCostsIsEqual(MageObject object1, MageObject object2) { - Set cmcObject1 = getCMC(object1); - Set cmcObject2 = getCMC(object2); - for (Integer integer : cmcObject1) { - if (cmcObject2.contains(integer)) { - return true; - } - } - return false; - } - public static Set getCMC(MageObject object) { - Set 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)", ""); // 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)", ""); // 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);