diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java index 08e1f2e4aa7..8b1feca862b 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java @@ -5,6 +5,7 @@ import mage.cards.Card; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; import mage.filter.FilterMana; +import mage.util.ManaUtil; import java.util.*; @@ -78,25 +79,7 @@ public class Brawl extends Constructed { invalid.put("Brawl", "Invalid Commander (" + commander.getName() + ')'); valid = false; } - FilterMana commanderColor = commander.getColorIdentity(); - if (commanderColor.isWhite()) { - colorIdentity.setWhite(true); - } - if (commanderColor.isBlue()) { - colorIdentity.setBlue(true); - } - if (commanderColor.isBlack()) { - colorIdentity.setBlack(true); - } - if (commanderColor.isRed()) { - colorIdentity.setRed(true); - } - if (commanderColor.isGreen()) { - colorIdentity.setGreen(true); - } - if (commanderColor.isColorless()) { - colorIdentity.setColorless(true); - } + ManaUtil.collectColorIdentity(colorIdentity, commander.getColorIdentity()); } } Set basicsInDeck = new HashSet<>(); @@ -108,7 +91,7 @@ public class Brawl extends Constructed { } } for (Card card : deck.getCards()) { - if (!cardHasValidColor(colorIdentity, card) + if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity()) && !(colorIdentity.isColorless() && basicsInDeck.size() == 1 && basicsInDeck.contains(card.getName()))) { @@ -135,13 +118,4 @@ public class Brawl extends Constructed { return valid; } - public boolean cardHasValidColor(FilterMana commander, Card card) { - FilterMana cardColor = card.getColorIdentity(); - return !(cardColor.isBlack() && !commander.isBlack() - || cardColor.isBlue() && !commander.isBlue() - || cardColor.isGreen() && !commander.isGreen() - || cardColor.isRed() && !commander.isRed() - || cardColor.isWhite() && !commander.isWhite()); - } - } 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 720de03ebf9..59996d0b23c 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 @@ -12,6 +12,7 @@ import mage.cards.Sets; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; import mage.filter.FilterMana; +import mage.util.ManaUtil; import java.util.*; @@ -148,22 +149,7 @@ public class Commander extends Constructed { valid = false; } } - FilterMana commanderColor = commander.getColorIdentity(); - if (commanderColor.isWhite()) { - colorIdentity.setWhite(true); - } - if (commanderColor.isBlue()) { - colorIdentity.setBlue(true); - } - if (commanderColor.isBlack()) { - colorIdentity.setBlack(true); - } - if (commanderColor.isRed()) { - colorIdentity.setRed(true); - } - if (commanderColor.isGreen()) { - colorIdentity.setGreen(true); - } + ManaUtil.collectColorIdentity(colorIdentity, commander.getColorIdentity()); } } @@ -173,7 +159,7 @@ public class Commander extends Constructed { } for (Card card : deck.getCards()) { - if (!cardHasValidColor(colorIdentity, card)) { + if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) { invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); valid = false; } @@ -197,15 +183,6 @@ public class Commander extends Constructed { return valid; } - public boolean cardHasValidColor(FilterMana commander, Card card) { - FilterMana cardColor = card.getColorIdentity(); - return !(cardColor.isBlack() && !commander.isBlack() - || cardColor.isBlue() && !commander.isBlue() - || cardColor.isGreen() && !commander.isGreen() - || cardColor.isRed() && !commander.isRed() - || cardColor.isWhite() && !commander.isWhite()); - } - @Override public int getEdhPowerLevel(Deck deck) { if (deck == null) { diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java index 4a066bf665a..d9e57cac2de 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java @@ -9,6 +9,7 @@ import mage.cards.Sets; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; import mage.filter.FilterMana; +import mage.util.ManaUtil; import java.util.*; @@ -95,22 +96,7 @@ public class FreeformCommander extends Constructed { valid = false; } } - FilterMana commanderColor = commander.getColorIdentity(); - if (commanderColor.isWhite()) { - colorIdentity.setWhite(true); - } - if (commanderColor.isBlue()) { - colorIdentity.setBlue(true); - } - if (commanderColor.isBlack()) { - colorIdentity.setBlack(true); - } - if (commanderColor.isRed()) { - colorIdentity.setRed(true); - } - if (commanderColor.isGreen()) { - colorIdentity.setGreen(true); - } + ManaUtil.collectColorIdentity(colorIdentity, commander.getColorIdentity()); } } @@ -120,7 +106,7 @@ public class FreeformCommander extends Constructed { } for (Card card : deck.getCards()) { - if (!cardHasValidColor(colorIdentity, card)) { + if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) { invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); valid = false; } @@ -136,13 +122,4 @@ public class FreeformCommander extends Constructed { } return valid; } - - public boolean cardHasValidColor(FilterMana commander, Card card) { - FilterMana cardColor = card.getColorIdentity(); - return !(cardColor.isBlack() && !commander.isBlack() - || cardColor.isBlue() && !commander.isBlue() - || cardColor.isGreen() && !commander.isGreen() - || cardColor.isRed() && !commander.isRed() - || cardColor.isWhite() && !commander.isWhite()); - } } diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Oathbreaker.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Oathbreaker.java index a8223820aaf..63ff6dce1ee 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Oathbreaker.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Oathbreaker.java @@ -6,6 +6,7 @@ import mage.abilities.keyword.PartnerWithAbility; import mage.cards.Card; import mage.cards.decks.Deck; import mage.filter.FilterMana; +import mage.util.ManaUtil; import java.util.*; @@ -71,7 +72,7 @@ public class Oathbreaker extends Vintage { @Override public int getDeckMinSize() { - return 60 - (1 + 2); // spell + 2 x partner oathbreakers + return 60 - (2 + 2); // 2 x spells + 2 x partner oathbreakers } @Override @@ -82,7 +83,6 @@ public class Oathbreaker extends Vintage { @Override public boolean validate(Deck deck) { boolean valid = true; - FilterMana colorIdentity = new FilterMana(); if (deck.getCards().size() + deck.getSideboard().size() != 60) { invalid.put("Deck", "Must contain " + 60 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); @@ -103,22 +103,22 @@ public class Oathbreaker extends Vintage { } Set commanderNames = new HashSet<>(); - String signatureSpell = null; - if (deck.getSideboard().size() < 2 || deck.getSideboard().size() > 3) { - invalid.put("Oathbreaker", "Sideboard must contain only the oathbreaker(s) with signature spell"); + Set signatureSpells = new HashSet<>(); + FilterMana allCommandersColor = new FilterMana(); + if (deck.getSideboard().size() < 2 || deck.getSideboard().size() > 4) { + invalid.put("Oathbreaker", "Sideboard must contain only 2 or 4 cards (oathbreaker + signature spell)"); valid = false; } else { + // collect data for (Card commander : deck.getSideboard()) { if (commander.isInstantOrSorcery()) { - if (signatureSpell == null) { - signatureSpell = commander.getName(); - } else { - invalid.put("Signature spell", "Only one signature spell allows, but found: " + signatureSpell + " and " + commander.getName()); - valid = false; - } + signatureSpells.add(commander.getName()); } else { if (commander.isPlaneswalker()) { commanderNames.add(commander.getName()); + + // color identity from commanders only, not spell + ManaUtil.collectColorIdentity(allCommandersColor, commander.getColorIdentity()); } else { invalid.put("Oathbreaker", "Only planeswalker can be Oathbreaker, not " + commander.getName()); valid = false; @@ -126,6 +126,21 @@ public class Oathbreaker extends Vintage { } } + // check size (1+1 or 2+2 allows) + if (commanderNames.size() == 0 || commanderNames.size() > 2) { + invalid.put("Oathbreaker", "Sideboard must contains 1 or 2 oathbreakers, but found: " + commanderNames.size()); + valid = false; + } + if (signatureSpells.size() == 0 || signatureSpells.size() > 2) { + invalid.put("Signature Spell", "Sideboard must contains 1 or 2 signature spells, but found: " + signatureSpells.size()); + valid = false; + } + if (signatureSpells.size() != commanderNames.size()) { + invalid.put("Oathbreaker", "Sideboard must contains 1 + 1 or 2 + 2 cards, but found: " + commanderNames.size() + " + " + signatureSpells.size()); + valid = false; + } + + // check partners for (Card commander : deck.getSideboard()) { if (commanderNames.contains(commander.getName())) { // partner checks @@ -142,42 +157,28 @@ public class Oathbreaker extends Vintage { valid = false; } } - - // color identity from commanders only, not spell - FilterMana commanderColor = commander.getColorIdentity(); - if (commanderColor.isWhite()) { - colorIdentity.setWhite(true); - } - if (commanderColor.isBlue()) { - colorIdentity.setBlue(true); - } - if (commanderColor.isBlack()) { - colorIdentity.setBlack(true); - } - if (commanderColor.isRed()) { - colorIdentity.setRed(true); - } - if (commanderColor.isGreen()) { - colorIdentity.setGreen(true); - } } } - if (commanderNames.size() == 0) { - invalid.put("Sideboard", "Can't find any oathbreaker"); - valid = false; - } - if (signatureSpell == null) { - invalid.put("Sideboard", "Can't find signature spell"); - valid = false; - } - } - - // signature spell color - for (Card card : deck.getSideboard()) { - if (card.getName().equals(signatureSpell) && !cardHasValidColor(colorIdentity, card)) { - invalid.put(card.getName(), "Invalid color for signature spell (" + colorIdentity.toString() + ')'); - valid = false; + // check spell color (one spell must be used by one oathbreaker) + // xmage doesn't allows to select pairs of spell + oathbreaker, what's why it requires one color combo minimum + for (Card spell : deck.getSideboard()) { + if (signatureSpells.contains(spell.getName())) { + FilterMana spellColor = spell.getColorIdentity(); + boolean haveSameColor = false; + for (Card commander : deck.getSideboard()) { + if (commanderNames.contains(commander.getName())) { + FilterMana commanderColor = commander.getColorIdentity(); + if (ManaUtil.isColorIdentityCompatible(commanderColor, spellColor)) { + haveSameColor = true; + } + } + } + if (!haveSameColor) { + invalid.put("Signature Spell", "Can't find oathbreaker with compatible color identity (" + spell.getName() + " - " + spellColor + ")"); + valid = false; + } + } } } @@ -187,8 +188,8 @@ public class Oathbreaker extends Vintage { } for (Card card : deck.getCards()) { - if (!cardHasValidColor(colorIdentity, card)) { - invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + if (!ManaUtil.isColorIdentityCompatible(allCommandersColor, card.getColorIdentity())) { + invalid.put(card.getName(), "Invalid color (" + card.getColorIdentity() + ')'); valid = false; } } @@ -203,13 +204,4 @@ public class Oathbreaker extends Vintage { } return valid; } - - public boolean cardHasValidColor(FilterMana commander, Card card) { - FilterMana cardColor = card.getColorIdentity(); - return !(cardColor.isBlack() && !commander.isBlack() - || cardColor.isBlue() && !commander.isBlue() - || cardColor.isGreen() && !commander.isGreen() - || cardColor.isRed() && !commander.isRed() - || cardColor.isWhite() && !commander.isWhite()); - } } diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java index 2e8acf10d8b..63cf9f20db7 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java @@ -10,6 +10,7 @@ import mage.cards.Sets; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; import mage.filter.FilterMana; +import mage.util.ManaUtil; import java.util.*; import java.util.Map.Entry; @@ -106,22 +107,7 @@ public class PennyDreadfulCommander extends Constructed { valid = false; } } - FilterMana commanderColor = commander.getColorIdentity(); - if (commanderColor.isWhite()) { - colorIdentity.setWhite(true); - } - if (commanderColor.isBlue()) { - colorIdentity.setBlue(true); - } - if (commanderColor.isBlack()) { - colorIdentity.setBlack(true); - } - if (commanderColor.isRed()) { - colorIdentity.setRed(true); - } - if (commanderColor.isGreen()) { - colorIdentity.setGreen(true); - } + ManaUtil.collectColorIdentity(colorIdentity, commander.getColorIdentity()); } } @@ -131,7 +117,7 @@ public class PennyDreadfulCommander extends Constructed { } for (Card card : deck.getCards()) { - if (!cardHasValidColor(colorIdentity, card)) { + if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) { invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); valid = false; } @@ -155,15 +141,6 @@ public class PennyDreadfulCommander extends Constructed { return valid; } - public boolean cardHasValidColor(FilterMana commander, Card card) { - FilterMana cardColor = card.getColorIdentity(); - return !(cardColor.isBlack() && !commander.isBlack() - || cardColor.isBlue() && !commander.isBlue() - || cardColor.isGreen() && !commander.isGreen() - || cardColor.isRed() && !commander.isRed() - || cardColor.isWhite() && !commander.isWhite()); - } - public void generatePennyDreadfulHash() { if (setupAllowed == false) { setupAllowed = true; diff --git a/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/src/mage/game/OathbreakerFreeForAll.java b/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/src/mage/game/OathbreakerFreeForAll.java index 4add5af79e6..37d687032a2 100644 --- a/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/src/mage/game/OathbreakerFreeForAll.java +++ b/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/src/mage/game/OathbreakerFreeForAll.java @@ -3,7 +3,6 @@ package mage.game; import mage.abilities.Ability; import mage.abilities.common.SignatureSpellCastOnlyWithOathbreakerEffect; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; import mage.abilities.condition.common.OathbreakerOnBattlefieldCondition; import mage.abilities.effects.common.InfoEffect; import mage.abilities.hint.ConditionHint; @@ -24,8 +23,8 @@ import java.util.*; public class OathbreakerFreeForAll extends GameCommanderImpl { private int numPlayers; - private Map playerSignatureSpell = new HashMap<>(); - private Map> playerCommanders = new HashMap<>(); + private Map> playerSignatureSpells = new HashMap<>(); + private Map> playerOathbreakers = new HashMap<>(); public OathbreakerFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { super(attackOption, range, mulligan, startLife); @@ -34,8 +33,8 @@ public class OathbreakerFreeForAll extends GameCommanderImpl { public OathbreakerFreeForAll(final OathbreakerFreeForAll game) { super(game); this.numPlayers = game.numPlayers; - this.playerSignatureSpell.putAll(game.playerSignatureSpell); - game.playerCommanders.forEach((key, value) -> this.playerCommanders.put(key, new ArrayList<>(value))); + game.playerSignatureSpells.forEach((key, value) -> this.playerSignatureSpells.put(key, new HashSet<>(value))); + game.playerOathbreakers.forEach((key, value) -> this.playerOathbreakers.put(key, new HashSet<>(value))); } @Override @@ -58,38 +57,41 @@ public class OathbreakerFreeForAll extends GameCommanderImpl { @Override public void initCommanderEffects(Card commander, Player player, Ability commanderAbility) { - // all commander effects must be independent from sourceId or controllerId + // all commander effects must be independent from sourceId or controllerId (it's limitation of current commander effects) super.initCommanderEffects(commander, player, commanderAbility); // signature spell restrict (spell can be casted on player's commander on battlefield) - if (commander.getId().equals(this.playerSignatureSpell.getOrDefault(player.getId(), null))) { - Condition condition = new OathbreakerOnBattlefieldCondition(player.getId(), this.playerCommanders.getOrDefault(player.getId(), null)); + if (this.playerSignatureSpells.getOrDefault(player.getId(), new HashSet<>()).contains(commander.getId())) { + OathbreakerOnBattlefieldCondition condition = new OathbreakerOnBattlefieldCondition(this, player.getId(), commander.getId(), + this.playerOathbreakers.getOrDefault(player.getId(), new HashSet<>())); commanderAbility.addEffect(new SignatureSpellCastOnlyWithOathbreakerEffect(condition, commander.getId())); // hint must be added to card, not global ability Ability ability = new SimpleStaticAbility(new InfoEffect("Signature spell hint")); - ability.addHint(new ConditionHint(condition, "Oathbreaker on battlefield")); + ability.addHint(new ConditionHint(condition, "Oathbreaker on battlefield (" + condition.getCompatibleNames() + ")")); ability.setRuleVisible(false); commander.addAbility(ability); } } + private void addInnerCommander(Map> destList, UUID playerId, UUID cardId) { + Set list = destList.getOrDefault(playerId, null); + if (list == null) { + list = new HashSet<>(); + destList.put(playerId, list); + } + list.add(cardId); + } + @Override public void addCommander(Card card, Player player) { super.addCommander(card, player); // prepare signature and commanders info if (card.isInstantOrSorcery()) { - this.playerSignatureSpell.put(player.getId(), card.getId()); + addInnerCommander(this.playerSignatureSpells, player.getId(), card.getId()); } else { - List list = this.playerCommanders.getOrDefault(player.getId(), null); - if (list == null) { - list = new ArrayList<>(); - this.playerCommanders.put(player.getId(), list); - } - if (!list.contains(card.getId())) { - list.add(card.getId()); - } + addInnerCommander(this.playerOathbreakers, player.getId(), card.getId()); } } @@ -116,8 +118,8 @@ public class OathbreakerFreeForAll extends GameCommanderImpl { public Set getCommandersIds(Player player, CommanderCardType commanderCardType) { Set res = new HashSet<>(); if (player != null) { - List commanders = this.playerCommanders.getOrDefault(player.getId(), new ArrayList<>()); - UUID spell = this.playerSignatureSpell.getOrDefault(player.getId(), null); + Set commanders = this.playerOathbreakers.getOrDefault(player.getId(), new HashSet<>()); + Set spells = this.playerSignatureSpells.getOrDefault(player.getId(), new HashSet<>()); for (UUID id : player.getCommandersIds()) { switch (commanderCardType) { case ANY: @@ -129,7 +131,7 @@ public class OathbreakerFreeForAll extends GameCommanderImpl { } break; case SIGNATURE_SPELL: - if (id.equals(spell)) { + if (spells.contains(id)) { res.add(id); } break; diff --git a/Mage/src/main/java/mage/abilities/condition/common/OathbreakerOnBattlefieldCondition.java b/Mage/src/main/java/mage/abilities/condition/common/OathbreakerOnBattlefieldCondition.java index 06b9e57718d..ad26f8a79d1 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/OathbreakerOnBattlefieldCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/OathbreakerOnBattlefieldCondition.java @@ -2,13 +2,17 @@ package mage.abilities.condition.common; import mage.abilities.Ability; import mage.abilities.condition.Condition; +import mage.cards.Card; +import mage.filter.FilterMana; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.permanent.PermanentIdPredicate; import mage.game.Game; +import mage.util.ManaUtil; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.UUID; /** @@ -20,23 +24,42 @@ public class OathbreakerOnBattlefieldCondition implements Condition { private UUID playerId; private FilterControlledPermanent filter; + private String compatibleNames; - public OathbreakerOnBattlefieldCondition(UUID playerId, List oathbreakersToSearch) { + public OathbreakerOnBattlefieldCondition(Game game, UUID playerId, UUID signatureSpellId, Set oathbreakersToSearch) { this.playerId = playerId; this.filter = new FilterControlledPermanent("oathbreaker on battlefield"); + + Card spell = game.getCard(signatureSpellId); + FilterMana spellColors = spell != null ? spell.getColorIdentity() : null; + + // spell can be casted by any compatible oathbreakers + List compatibleList = new ArrayList<>(); + List compatibleNames = new ArrayList<>(); if (oathbreakersToSearch != null && !oathbreakersToSearch.isEmpty()) { - // any commander on battlefield - List idsList = new ArrayList<>(); for (UUID id : oathbreakersToSearch) { - idsList.add(new PermanentIdPredicate(id)); + Card commander = game.getCard(id); + if (commander != null && ManaUtil.isColorIdentityCompatible(commander.getColorIdentity(), spellColors)) { + compatibleList.add(new PermanentIdPredicate(id)); + compatibleNames.add(commander.getName()); + } } - this.filter.add(Predicates.or(idsList)); - } else { + } + this.compatibleNames = String.join("; ", compatibleNames); + + if (compatibleList.isEmpty()) { // random id to disable condition this.filter.add(new PermanentIdPredicate(UUID.randomUUID())); + } else { + // oathbreaker on battlefield + this.filter.add(Predicates.or(compatibleList)); } } + public String getCompatibleNames() { + return !this.compatibleNames.isEmpty() ? this.compatibleNames : "you haven't compatible oathbreaker"; + } + @Override public boolean apply(Game game, Ability source) { // source.getSourceId() is null for commander's effects diff --git a/Mage/src/main/java/mage/util/ManaUtil.java b/Mage/src/main/java/mage/util/ManaUtil.java index b9c7d31f88e..8e49f964403 100644 --- a/Mage/src/main/java/mage/util/ManaUtil.java +++ b/Mage/src/main/java/mage/util/ManaUtil.java @@ -11,6 +11,7 @@ import mage.abilities.mana.*; import mage.cards.Card; import mage.choices.Choice; import mage.constants.ColoredManaSymbol; +import mage.filter.FilterMana; import mage.game.Game; import java.util.*; @@ -26,23 +27,23 @@ public final class ManaUtil { /** * In case the choice of mana to be produced is obvious, let's discard all * other abilities. - * + *

* Example: Pay {W}{R} - * + *

* Land produces {W} or {G}. - * + *

* No need to ask what player wants to choose. {W} mana ability should be * left only. - * + *

* But we CAN do auto choice only in case we have basic mana abilities. * Example: we should pay {1} and we have Cavern of Souls that can produce * {1} or any mana of creature type choice. We can't simply auto choose {1} * as the second mana ability also makes spell uncounterable. - * + *

* In case we can't auto choose we'll simply return the useableAbilities map * back to caller without any modification. * - * @param unpaid Mana we need to pay. Can be null (it is for X costs now). + * @param unpaid Mana we need to pay. Can be null (it is for X costs now). * @param useableAbilities List of mana abilities permanent may produce * @return List of mana abilities permanent may produce and are reasonable * for unpaid mana @@ -430,7 +431,6 @@ public final class ManaUtil { * Converts a collection of mana symbols into a single condensed string e.g. * {1}{1}{1}{1}{1}{W} = {5}{W} {2}{B}{2}{B}{2}{B} = {6}{B}{B}{B} * {1}{2}{R}{U}{1}{1} = {5}{R}{U} {B}{G}{R} = {B}{G}{R} - * */ public static String condenseManaCostString(String rawCost) { int total = 0; @@ -466,4 +466,32 @@ public final class ManaUtil { // Return the condensed string return sb.toString(); } + + public static boolean isColorIdentityCompatible(FilterMana needColors, FilterMana cardColors) { + // colorless can be used with any color + return needColors != null + && !(cardColors.isBlack() && !needColors.isBlack() + || cardColors.isBlue() && !needColors.isBlue() + || cardColors.isGreen() && !needColors.isGreen() + || cardColors.isRed() && !needColors.isRed() + || cardColors.isWhite() && !needColors.isWhite()); + } + + public static void collectColorIdentity(FilterMana destColors, FilterMana newColors) { + if (newColors.isWhite()) { + destColors.setWhite(true); + } + if (newColors.isBlue()) { + destColors.setBlue(true); + } + if (newColors.isBlack()) { + destColors.setBlack(true); + } + if (newColors.isRed()) { + destColors.setRed(true); + } + if (newColors.isGreen()) { + destColors.setGreen(true); + } + } }