diff --git a/Mage.Client/src/main/java/mage/client/components/LegalityLabel.java b/Mage.Client/src/main/java/mage/client/components/LegalityLabel.java index 537170d8df..9d0a70b4bb 100644 --- a/Mage.Client/src/main/java/mage/client/components/LegalityLabel.java +++ b/Mage.Client/src/main/java/mage/client/components/LegalityLabel.java @@ -2,6 +2,7 @@ package mage.client.components; import mage.cards.decks.Deck; import mage.cards.decks.DeckValidator; +import mage.cards.decks.DeckValidatorError; import mage.cards.decks.importer.DeckImporter; import org.unbescape.html.HtmlEscape; import org.unbescape.html.HtmlEscapeLevel; @@ -10,7 +11,6 @@ import org.unbescape.html.HtmlEscapeType; import javax.swing.*; import java.awt.*; import java.io.File; -import java.util.Map; /** * @author Elandril @@ -19,6 +19,7 @@ public class LegalityLabel extends JLabel { protected static final Color COLOR_UNKNOWN = new Color(174, 174, 174); protected static final Color COLOR_LEGAL = new Color(117, 152, 110); + protected static final Color COLOR_PARTLY_LEGAL = new Color(191, 176, 80); protected static final Color COLOR_NOT_LEGAL = new Color(191, 84, 74); protected static final Color COLOR_TEXT = new Color(255, 255, 255); protected static final Dimension DIM_MINIMUM = new Dimension(75, 25); @@ -105,11 +106,17 @@ public class LegalityLabel extends JLabel { return HtmlEscape.escapeHtml(string, HtmlEscapeType.HTML4_NAMED_REFERENCES_DEFAULT_TO_HEXA, HtmlEscapeLevel.LEVEL_0_ONLY_MARKUP_SIGNIFICANT_EXCEPT_APOS); } - protected String formatInvalidTooltip(Map invalid) { - return invalid.entrySet().stream() - .sorted(Map.Entry.comparingByKey()) + protected String formatInvalidTooltip(java.util.List sortedErrorsList) { + return sortedErrorsList.stream() .reduce("

Deck is INVALID

The following problems have been found:
", - (str, entry) -> String.format("%s", str, escapeHtml(entry.getKey()), escapeHtml(entry.getValue())), String::concat) + (str, error) -> String.format("%s", str, escapeHtml(error.getGroup()), escapeHtml(error.getMessage())), String::concat) + + "
%s%s
%s%s
"; + } + + protected String formatPartlyValidTooltip(java.util.List sortedErrorsList) { + return sortedErrorsList.stream() + .reduce("

Deck is PARTLY VALID

The following problems have been found:
", + (str, error) -> String.format("%s", str, escapeHtml(error.getGroup()), escapeHtml(error.getMessage())), String::concat) + "
%s%s
"; } @@ -139,6 +146,10 @@ public class LegalityLabel extends JLabel { showState(COLOR_LEGAL, tooltip); } + public void showStatePartlyLegal(String tooltip) { + showState(COLOR_PARTLY_LEGAL, tooltip); + } + public void showStateNotLegal(String tooltip) { showState(COLOR_NOT_LEGAL, tooltip); } @@ -157,8 +168,10 @@ public class LegalityLabel extends JLabel { try { if (validator.validate(deck)) { showStateLegal("Deck is VALID"); + } else if (validator.isPartlyValid()) { + showStatePartlyLegal(formatPartlyValidTooltip(validator.getErrorsListSorted())); } else { - showStateNotLegal(formatInvalidTooltip(validator.getInvalid())); + showStateNotLegal(formatInvalidTooltip(validator.getErrorsListSorted())); } } catch (Exception e) { showStateUnknown(String.format("Deck could not be validated!
The following error occurred while validating this deck:
%s", escapeHtml(e.getMessage()))); diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/AusHighlander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/AusHighlander.java index 8e25f052f7..437b1fea68 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/AusHighlander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/AusHighlander.java @@ -4,6 +4,7 @@ import mage.cards.ExpansionSet; import mage.cards.Sets; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; +import mage.cards.decks.DeckValidatorErrorType; import java.util.HashMap; import java.util.Map; @@ -92,14 +93,14 @@ public class AusHighlander extends Constructed { @Override public boolean validate(Deck deck) { boolean valid = true; - invalid.clear(); + errorsList.clear(); if (deck.getCards().size() != getDeckMinSize()) { - invalid.put("Deck", "Must contain " + getDeckMinSize() + " singleton cards: has " + (deck.getCards().size()) + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + getDeckMinSize() + " singleton cards: has " + (deck.getCards().size()) + " cards"); valid = false; } if (deck.getSideboard().size() > 15) { - invalid.put("Sideboard", "Must contain at most 15 singleton cards: has " + (deck.getSideboard().size()) + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Sideboard", "Must contain at most 15 singleton cards: has " + (deck.getSideboard().size()) + " cards"); valid = false; } @@ -139,12 +140,12 @@ public class AusHighlander extends Constructed { String cn = entry.getKey(); if (pointMap.containsKey(cn)) { totalPoints += pointMap.get(cn); - invalid.put(entry.getKey(), " " + pointMap.get(cn) + " point " + cn); + addError(DeckValidatorErrorType.OTHER, entry.getKey(), " " + pointMap.get(cn) + " point " + cn); } } if (totalPoints > 7) { - invalid.put("Total points too high", "Your calculated point total was " + totalPoints); - invalid.put("Only you can see this!", "Your opponents will not be able to see this message or what cards are in your deck!"); + addError(DeckValidatorErrorType.PRIMARY, "Total points too high", "Your calculated point total was " + totalPoints); + addError(DeckValidatorErrorType.PRIMARY, "Only you can see this!", "Your opponents will not be able to see this message or what cards are in your deck!"); valid = false; } return valid; 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 28534db325..0aba557354 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 @@ -6,6 +6,7 @@ import mage.abilities.keyword.CompanionAbility; import mage.cards.Card; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; +import mage.cards.decks.DeckValidatorErrorType; import mage.filter.FilterMana; import mage.util.ManaUtil; @@ -40,7 +41,7 @@ public class Brawl extends Constructed { @Override public boolean validate(Deck deck) { boolean valid = true; - invalid.clear(); + errorsList.clear(); Card brawler = null; Card companion = null; FilterMana colorIdentity = new FilterMana(); @@ -60,32 +61,32 @@ public class Brawl extends Constructed { companion = card2; brawler = card1; } else { - invalid.put("Brawl", "Sideboard must contain only the brawler and up to 1 companion"); + addError(DeckValidatorErrorType.PRIMARY, "Brawl", "Sideboard must contain only the brawler and up to 1 companion"); valid = false; } } else { - invalid.put("Brawl", "Sideboard must contain only the brawler and up to 1 companion"); + addError(DeckValidatorErrorType.PRIMARY, "Brawl", "Sideboard must contain only the brawler and up to 1 companion"); valid = false; } if (brawler != null) { ManaUtil.collectColorIdentity(colorIdentity, brawler.getColorIdentity()); if (bannedCommander.contains(brawler.getName())) { - invalid.put("Brawl", "Brawler banned (" + brawler.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, "Brawl", "Brawler banned (" + brawler.getName() + ')'); valid = false; } if (!((brawler.isCreature() && brawler.isLegendary()) || brawler.isPlaneswalker() || brawler.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) { - invalid.put("Brawl", "Invalid Brawler (" + brawler.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, "Brawl", "Invalid Brawler (" + brawler.getName() + ')'); valid = false; } } if (companion != null && deck.getCards().size() + deck.getSideboard().size() != getDeckMinSize() + 1) { - invalid.put("Deck", "Must contain " + (getDeckMinSize() + 1) + " cards (companion doesn't count in deck size requirement): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + (getDeckMinSize() + 1) + " cards (companion doesn't count in deck size requirement): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); valid = false; } else if (companion == null && deck.getCards().size() + deck.getSideboard().size() != getDeckMinSize()) { - invalid.put("Deck", "Must contain " + getDeckMinSize() + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + getDeckMinSize() + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); valid = false; } @@ -96,7 +97,7 @@ public class Brawl extends Constructed { for (String bannedCard : banned) { if (counts.containsKey(bannedCard)) { - invalid.put(bannedCard, "Banned"); + addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard); valid = false; } } @@ -114,7 +115,7 @@ public class Brawl extends Constructed { && !(colorIdentity.isColorless() && basicsInDeck.size() == 1 && basicsInDeck.contains(card.getName()))) { - invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); valid = false; } } @@ -123,14 +124,14 @@ public class Brawl extends Constructed { && !(colorIdentity.isColorless() && basicsInDeck.size() == 1 && basicsInDeck.contains(card.getName()))) { - invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); valid = false; } } for (Card card : deck.getCards()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - invalid.put(card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); valid = false; } } @@ -138,7 +139,7 @@ public class Brawl extends Constructed { for (Card card : deck.getSideboard()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - invalid.put(card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); valid = false; } } @@ -151,7 +152,7 @@ public class Brawl extends Constructed { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; if (!companionAbility.isLegal(cards, getDeckMinSize())) { - invalid.put(companion.getName(), "Deck invalid for companion"); + addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion"); valid = false; } break; diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java index aec2126784..c2b819cab1 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/CanadianHighlander.java @@ -4,6 +4,7 @@ import mage.cards.ExpansionSet; import mage.cards.Sets; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; +import mage.cards.decks.DeckValidatorErrorType; import java.util.HashMap; import java.util.Map; @@ -74,15 +75,15 @@ public class CanadianHighlander extends Constructed { @Override public boolean validate(Deck deck) { boolean valid = true; - invalid.clear(); + errorsList.clear(); if (deck.getCards().size() < 100) { - invalid.put("Deck", "Must contain 100 or more singleton cards: has " + (deck.getCards().size()) + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain 100 or more singleton cards: has " + (deck.getCards().size()) + " cards"); valid = false; } if (!deck.getSideboard().isEmpty()) { - invalid.put("Deck", "Sideboard can't contain any cards: has " + (deck.getSideboard().size()) + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Sideboard can't contain any cards: has " + (deck.getSideboard().size()) + " cards"); valid = false; } @@ -97,11 +98,11 @@ public class CanadianHighlander extends Constructed { String cn = entry.getKey(); if (pointMap.containsKey(cn)) { totalPoints += pointMap.get(cn); - invalid.put(entry.getKey(), " " + pointMap.get(cn) + " point " + cn); + addError(DeckValidatorErrorType.OTHER, entry.getKey(), " " + pointMap.get(cn) + " point " + cn); } } if (totalPoints > allowedPoints) { - invalid.put("Total points too high", "Your calculated point total was " + totalPoints); + addError(DeckValidatorErrorType.PRIMARY, "Total points too high", "Your calculated point total was " + totalPoints); valid = false; } return valid; 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 670146e404..dae753fe8b 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.ExpansionSet; import mage.cards.Sets; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; +import mage.cards.decks.DeckValidatorErrorType; import mage.filter.FilterMana; import mage.util.ManaUtil; @@ -97,7 +98,7 @@ public class Commander extends Constructed { @Override public boolean validate(Deck deck) { boolean valid = true; - invalid.clear(); + errorsList.clear(); FilterMana colorIdentity = new FilterMana(); Set commanders = new HashSet<>(); Card companion = null; @@ -136,19 +137,19 @@ public class Commander extends Constructed { commanders.add(card1); commanders.add(card2); } else { - invalid.put("Commander", "Sideboard must contain only the commander(s) and up to 1 companion"); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion"); valid = false; } } else { - invalid.put("Commander", "Sideboard must contain only the commander(s) and up to 1 companion"); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion"); valid = false; } if (companion != null && deck.getCards().size() + deck.getSideboard().size() != 101) { - invalid.put("Deck", "Must contain " + 101 + " cards (companion doesn't count for deck size): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 101 + " cards (companion doesn't count for deck size): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); valid = false; } else if (companion == null && deck.getCards().size() + deck.getSideboard().size() != 100) { - invalid.put("Deck", "Must contain " + 100 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 100 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); valid = false; } @@ -159,7 +160,7 @@ public class Commander extends Constructed { for (String bannedCard : banned) { if (counts.containsKey(bannedCard)) { - invalid.put(bannedCard, "Banned"); + addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard); valid = false; } } @@ -170,18 +171,18 @@ public class Commander extends Constructed { } for (Card commander : commanders) { if (bannedCommander.contains(commander.getName())) { - invalid.put("Commander", "Commander banned (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander banned (" + commander.getName() + ')'); valid = false; } if ((!commander.isCreature() || !commander.isLegendary()) && (!commander.isPlaneswalker() || !commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) { - invalid.put("Commander", "Commander invalid (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander invalid (" + commander.getName() + ')'); valid = false; } if (commanders.size() == 2) { if (commander.getAbilities().contains(PartnerAbility.getInstance())) { if (bannedPartner.contains(commander.getName())) { - invalid.put("Commander", "Partner banned (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Partner banned (" + commander.getName() + ')'); valid = false; } } else { @@ -192,7 +193,7 @@ public class Commander extends Constructed { .map(PartnerWithAbility::getPartnerName) .anyMatch(commanderNames::contains); if (!partnersWith) { - invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander without Partner (" + commander.getName() + ')'); valid = false; } } @@ -207,20 +208,20 @@ public class Commander extends Constructed { for (Card card : deck.getCards()) { if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) { - invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); valid = false; } } for (Card card : deck.getSideboard()) { if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) { - invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); valid = false; } } for (Card card : deck.getCards()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - invalid.put(card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); valid = false; } } @@ -228,7 +229,7 @@ public class Commander extends Constructed { for (Card card : deck.getSideboard()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - invalid.put(card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); valid = false; } } @@ -241,7 +242,7 @@ public class Commander extends Constructed { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; if (!companionAbility.isLegal(cards, getDeckMinSize())) { - invalid.put(companion.getName(), "Deck invalid for companion"); + addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion"); valid = false; } break; diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Freeform.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Freeform.java index d09bb6a8d4..f1336bf102 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Freeform.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Freeform.java @@ -2,6 +2,7 @@ package mage.deck; import mage.cards.decks.Deck; import mage.cards.decks.DeckValidator; +import mage.cards.decks.DeckValidatorErrorType; /** * @author fireshoes @@ -33,10 +34,10 @@ public class Freeform extends DeckValidator { @Override public boolean validate(Deck deck) { boolean valid = true; - invalid.clear(); + errorsList.clear(); // http://magic.wizards.com/en/gameinfo/gameplay/formats/freeform if (deck.getCards().size() < getDeckMinSize()) { - invalid.put("Deck", "Must contain at least " + getDeckMinSize() + " cards: has only " + deck.getCards().size() + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain at least " + getDeckMinSize() + " cards: has only " + deck.getCards().size() + " cards"); valid = false; } return valid; 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 9372f2e175..4c045f3c9a 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.ExpansionSet; import mage.cards.Sets; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; +import mage.cards.decks.DeckValidatorErrorType; import mage.filter.FilterMana; import mage.util.ManaUtil; @@ -53,7 +54,7 @@ public class FreeformCommander extends Constructed { @Override public boolean validate(Deck deck) { boolean valid = true; - invalid.clear(); + errorsList.clear(); FilterMana colorIdentity = new FilterMana(); Set commanders = new HashSet<>(); Card companion = null; @@ -92,19 +93,19 @@ public class FreeformCommander extends Constructed { commanders.add(card1); commanders.add(card2); } else { - invalid.put("Commander", "Sideboard must contain only the commander(s) and up to 1 companion"); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion"); valid = false; } } else { - invalid.put("Commander", "Sideboard must contain only the commander(s) and up to 1 companion"); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion"); valid = false; } if (companion != null && deck.getCards().size() + deck.getSideboard().size() != 101) { - invalid.put("Deck", "Must contain " + 101 + " cards (companion doesn't count for deck size): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 101 + " cards (companion doesn't count for deck size): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); valid = false; } else if (companion == null && deck.getCards().size() + deck.getSideboard().size() != 100) { - invalid.put("Deck", "Must contain " + 100 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 100 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); valid = false; } @@ -119,7 +120,7 @@ public class FreeformCommander extends Constructed { } for (Card commander : commanders) { if (!commander.isCreature() || !commander.isLegendary()) { - invalid.put("Commander", "For Freeform Commander, the commander must be a creature or be legendary. Yours was: " + commander.getName()); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "For Freeform Commander, the commander must be a creature or be legendary. Yours was: " + commander.getName()); valid = false; } if (commanders.size() == 2) { @@ -131,7 +132,7 @@ public class FreeformCommander extends Constructed { .map(PartnerWithAbility::getPartnerName) .anyMatch(commanderNames::contains); if (!partnersWith) { - invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander without Partner (" + commander.getName() + ')'); valid = false; } } @@ -146,13 +147,13 @@ public class FreeformCommander extends Constructed { for (Card card : deck.getCards()) { if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) { - invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); valid = false; } } for (Card card : deck.getSideboard()) { if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) { - invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); valid = false; } } @@ -164,7 +165,7 @@ public class FreeformCommander extends Constructed { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; if (!companionAbility.isLegal(cards, getDeckMinSize())) { - invalid.put(companion.getName(), "Deck invalid for companion"); + addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion"); valid = false; } break; diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/HistoricalType2.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/HistoricalType2.java index 9aee37fa22..6db8a823bc 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/HistoricalType2.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/HistoricalType2.java @@ -4,6 +4,7 @@ import mage.cards.ExpansionSet; import mage.cards.Sets; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; +import mage.cards.decks.DeckValidatorError; import java.util.*; @@ -104,10 +105,10 @@ public class HistoricalType2 extends Constructed { @Override public boolean validate(Deck deck) { - Map leastInvalid = null; + List leastInvalid = null; boolean valid = false; - invalid.clear(); + errorsList.clear(); // first, check whether misty and batterskull are in the same deck. Map counts = new HashMap<>(); @@ -125,7 +126,7 @@ public class HistoricalType2 extends Constructed { for (String[] sets : standards) { // clear the invalid list - invalid.clear(); + errorsList.clear(); // add the sets to the setCodes. setCodes = new ArrayList<>(Arrays.asList(sets)); @@ -139,15 +140,15 @@ public class HistoricalType2 extends Constructed { // if the map holding the invalid cards is empty, set it to a // copy of the current invalid list. if (leastInvalid == null) { - leastInvalid = new HashMap<>(this.getInvalid()); + leastInvalid = new ArrayList<>(this.getErrorsList()); continue; } // see how many invalid cards there are. if there are less invalid // cards than the stored invalid list, assign the current invalid // to leastInvalid. - if (leastInvalid.size() > this.getInvalid().size()) { - leastInvalid = new HashMap<>(this.getInvalid()); + if (leastInvalid.size() > this.getErrorsList().size()) { + leastInvalid = new ArrayList<>(this.getErrorsList()); } } @@ -165,7 +166,7 @@ public class HistoricalType2 extends Constructed { // clear the invalid list and set codes. setCodes.clear(); - invalid.clear(); + errorsList.clear(); // increment the start and end dates. start.set(Calendar.YEAR, start.get(Calendar.YEAR) + 1); @@ -183,7 +184,7 @@ public class HistoricalType2 extends Constructed { // validate it. If it validates, clear the invalid cards and break. if (super.validate(deck)) { - invalid.clear(); + errorsList.clear(); valid = true; break; } @@ -192,17 +193,16 @@ public class HistoricalType2 extends Constructed { // cards than the stored invalid list, assign the current invalid // to leastInvalid. if (leastInvalid == null) { - leastInvalid = new HashMap<>(this.getInvalid()); - - } else if (leastInvalid.size() > this.getInvalid().size()) { - leastInvalid = new HashMap<>(this.getInvalid()); + leastInvalid = new ArrayList<>(this.getErrorsList()); + } else if (leastInvalid.size() > this.getErrorsList().size()) { + leastInvalid = new ArrayList<>(this.getErrorsList()); } } // if no standard environment is valid, set the invalid to the // invalid that had the least errors. if (!valid) { - this.invalid = new HashMap<>(leastInvalid); + this.errorsList = new ArrayList<>(leastInvalid); } // return the validity. diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Momir.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Momir.java index bcd8e57227..8e9a46bf44 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Momir.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Momir.java @@ -3,6 +3,7 @@ package mage.deck; import mage.cards.Card; import mage.cards.decks.Deck; import mage.cards.decks.DeckValidator; +import mage.cards.decks.DeckValidatorErrorType; import java.util.ArrayList; import java.util.Arrays; @@ -30,17 +31,17 @@ public class Momir extends DeckValidator { @Override public boolean validate(Deck deck) { boolean valid = true; - invalid.clear(); + errorsList.clear(); if (deck.getCards().size() != getDeckMinSize()) { - invalid.put("Deck", "Must contain " + getDeckMinSize() + " cards: has " + deck.getCards().size() + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + getDeckMinSize() + " cards: has " + deck.getCards().size() + " cards"); valid = false; } List basicLandNames = new ArrayList<>(Arrays.asList("Forest", "Island", "Mountain", "Swamp", "Plains", "Wastes")); for (Card card : deck.getCards()) { if (!basicLandNames.contains(card.getName())) { - invalid.put(card.getName(), "Only basic lands are allowed"); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Only basic lands are allowed"); valid = false; } } 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 9c70b049ff..7b3c8a8ee9 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 @@ -5,6 +5,7 @@ import mage.abilities.keyword.PartnerAbility; import mage.abilities.keyword.PartnerWithAbility; import mage.cards.Card; import mage.cards.decks.Deck; +import mage.cards.decks.DeckValidatorErrorType; import mage.filter.FilterMana; import mage.util.ManaUtil; @@ -82,10 +83,10 @@ public class Oathbreaker extends Vintage { @Override public boolean validate(Deck deck) { boolean valid = true; - invalid.clear(); + errorsList.clear(); if (deck.getCards().size() + deck.getSideboard().size() != 60) { - invalid.put("Deck", "Must contain " + 60 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 60 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); valid = false; } @@ -95,7 +96,7 @@ public class Oathbreaker extends Vintage { for (String bannedCard : banned) { if (counts.containsKey(bannedCard)) { - invalid.put(bannedCard, "Banned"); + addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard); valid = false; } } @@ -106,7 +107,7 @@ public class Oathbreaker extends Vintage { 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)"); + addError(DeckValidatorErrorType.PRIMARY, "Oathbreaker", "Sideboard must contain only 2 or 4 cards (oathbreaker + signature spell)"); valid = false; } else { // collect data @@ -120,7 +121,7 @@ public class Oathbreaker extends Vintage { // color identity from commanders only, not spell ManaUtil.collectColorIdentity(allCommandersColor, commander.getColorIdentity()); } else { - invalid.put("Oathbreaker", "Only planeswalker can be Oathbreaker, not " + commander.getName()); + addError(DeckValidatorErrorType.PRIMARY, "Oathbreaker", "Only planeswalker can be Oathbreaker, not " + commander.getName()); valid = false; } } @@ -128,15 +129,15 @@ public class Oathbreaker extends Vintage { // check size (1+1 or 2+2 allows) if (commanderNames.isEmpty() || commanderNames.size() > 2) { - invalid.put("Oathbreaker", "Sideboard must contains 1 or 2 oathbreakers, but found: " + commanderNames.size()); + addError(DeckValidatorErrorType.PRIMARY, "Oathbreaker", "Sideboard must contains 1 or 2 oathbreakers, but found: " + commanderNames.size()); valid = false; } if (signatureSpells.isEmpty() || signatureSpells.size() > 2) { - invalid.put("Signature Spell", "Sideboard must contains 1 or 2 signature spells, but found: " + signatureSpells.size()); + addError(DeckValidatorErrorType.PRIMARY, "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()); + addError(DeckValidatorErrorType.PRIMARY, "Oathbreaker", "Sideboard must contains 1 + 1 or 2 + 2 cards, but found: " + commanderNames.size() + " + " + signatureSpells.size()); valid = false; } @@ -153,7 +154,7 @@ public class Oathbreaker extends Vintage { } } if (!partnersWith) { - invalid.put("Oathbreaker", "Oathbreaker without Partner (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, "Oathbreaker", "Oathbreaker without Partner (" + commander.getName() + ')'); valid = false; } } @@ -175,7 +176,7 @@ public class Oathbreaker extends Vintage { } } if (!haveSameColor) { - invalid.put("Signature Spell", "Can't find oathbreaker with compatible color identity (" + spell.getName() + " - " + spellColor + ")"); + addError(DeckValidatorErrorType.PRIMARY, "Signature Spell", "Can't find oathbreaker with compatible color identity (" + spell.getName() + " - " + spellColor + ")"); valid = false; } } @@ -189,7 +190,7 @@ public class Oathbreaker extends Vintage { for (Card card : deck.getCards()) { if (!ManaUtil.isColorIdentityCompatible(allCommandersColor, card.getColorIdentity())) { - invalid.put(card.getName(), "Invalid color (" + card.getColorIdentity() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + card.getColorIdentity() + ')'); valid = false; } } @@ -197,7 +198,7 @@ public class Oathbreaker extends Vintage { for (Card card : deck.getSideboard()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - invalid.put(card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); valid = false; } } 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 4a41c6c970..06e6b594f7 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,12 +10,12 @@ import mage.cards.ExpansionSet; import mage.cards.Sets; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; +import mage.cards.decks.DeckValidatorErrorType; import mage.cards.decks.PennyDreadfulLegalityUtil; import mage.filter.FilterMana; import mage.util.ManaUtil; import java.util.*; -import java.util.Map.Entry; /** * @author spjspj @@ -47,7 +47,7 @@ public class PennyDreadfulCommander extends Constructed { @Override public boolean validate(Deck deck) { boolean valid = true; - invalid.clear(); + errorsList.clear(); FilterMana colorIdentity = new FilterMana(); Set commanders = new HashSet<>(); Card companion = null; @@ -86,19 +86,19 @@ public class PennyDreadfulCommander extends Constructed { commanders.add(card1); commanders.add(card2); } else { - invalid.put("Commander", "Sideboard must contain only the commander(s) and up to 1 companion"); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion"); valid = false; } } else { - invalid.put("Commander", "Sideboard must contain only the commander(s) and up to 1 companion"); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion"); valid = false; } if (companion != null && deck.getCards().size() + deck.getSideboard().size() != 101) { - invalid.put("Deck", "Must contain " + 101 + " cards (companion doesn't count for deck size): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 101 + " cards (companion doesn't count for deck size): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); valid = false; } else if (companion == null && deck.getCards().size() + deck.getSideboard().size() != 100) { - invalid.put("Deck", "Must contain " + 100 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 100 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards"); valid = false; } @@ -113,7 +113,7 @@ public class PennyDreadfulCommander extends Constructed { for (String wantedCard : counts.keySet()) { if (!(pdAllowed.containsKey(wantedCard))) { - invalid.put(wantedCard, "Banned"); + addError(DeckValidatorErrorType.BANNED, "Banned", wantedCard); valid = false; } } @@ -124,12 +124,12 @@ public class PennyDreadfulCommander extends Constructed { } for (Card commander : commanders) { if (bannedCommander.contains(commander.getName())) { - invalid.put("Commander", "Commander banned (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander banned (" + commander.getName() + ')'); valid = false; } if ((!commander.isCreature() || !commander.isLegendary()) && (!commander.isPlaneswalker() || !commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) { - invalid.put("Commander", "Commander invalid (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander invalid (" + commander.getName() + ')'); valid = false; } if (commanders.size() == 2) { @@ -141,7 +141,7 @@ public class PennyDreadfulCommander extends Constructed { .map(PartnerWithAbility::getPartnerName) .anyMatch(commanderNames::contains); if (!partnersWith) { - invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander without Partner (" + commander.getName() + ')'); valid = false; } } @@ -156,20 +156,20 @@ public class PennyDreadfulCommander extends Constructed { for (Card card : deck.getCards()) { if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) { - invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); valid = false; } } for (Card card : deck.getSideboard()) { if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) { - invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); valid = false; } } for (Card card : deck.getCards()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - invalid.put(card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); valid = false; } } @@ -177,7 +177,7 @@ public class PennyDreadfulCommander extends Constructed { for (Card card : deck.getSideboard()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - invalid.put(card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); valid = false; } } @@ -190,7 +190,7 @@ public class PennyDreadfulCommander extends Constructed { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; if (!companionAbility.isLegal(cards, getDeckMinSize())) { - invalid.put(companion.getName(), "Deck invalid for companion"); + addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion"); valid = false; } break; diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/SuperType2.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/SuperType2.java index a9db25e7f8..053a0ee3fe 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/SuperType2.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/SuperType2.java @@ -4,6 +4,7 @@ import mage.cards.ExpansionSet; import mage.cards.Sets; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; +import mage.cards.decks.DeckValidatorError; import java.util.*; @@ -77,10 +78,10 @@ public class SuperType2 extends Constructed { @Override public boolean validate(Deck deck) { - Map leastInvalid = null; + List leastInvalid = null; boolean valid = false; - invalid.clear(); + errorsList.clear(); // first, check whether misty and batterskull are in the same deck. Map counts = new HashMap<>(); @@ -98,7 +99,7 @@ public class SuperType2 extends Constructed { for (String[] sets : standards) { // clear the invalid list - invalid.clear(); + errorsList.clear(); // add the sets to the setCodes. setCodes = new ArrayList<>(Arrays.asList(sets)); @@ -120,15 +121,15 @@ public class SuperType2 extends Constructed { // if the map holding the invalid cards is empty, set it to a // copy of the current invalid list. if (leastInvalid == null) { - leastInvalid = new HashMap<>(this.getInvalid()); + leastInvalid = new ArrayList<>(this.getErrorsList()); continue; } // see how many invalid cards there are. if there are less invalid // cards than the stored invalid list, assign the current invalid // to leastInvalid. - if (leastInvalid.size() > this.getInvalid().size()) { - leastInvalid = new HashMap<>(this.getInvalid()); + if (leastInvalid.size() > this.getErrorsList().size()) { + leastInvalid = new ArrayList<>(this.getErrorsList()); } } @@ -146,7 +147,7 @@ public class SuperType2 extends Constructed { // clear the invalid list and set codes. setCodes.clear(); - invalid.clear(); + errorsList.clear(); // increment the start and end dates. start.set(Calendar.YEAR, start.get(Calendar.YEAR) + 1); @@ -172,7 +173,7 @@ public class SuperType2 extends Constructed { // validate it. If it validates, clear the invalid cards and break. if (super.validate(deck)) { - invalid.clear(); + errorsList.clear(); valid = true; break; } @@ -181,17 +182,17 @@ public class SuperType2 extends Constructed { // cards than the stored invalid list, assign the current invalid // to leastInvalid. if (leastInvalid == null) { - leastInvalid = new HashMap<>(this.getInvalid()); + leastInvalid = new ArrayList<>(this.getErrorsList()); - } else if (leastInvalid.size() > this.getInvalid().size()) { - leastInvalid = new HashMap<>(this.getInvalid()); + } else if (leastInvalid.size() > this.getErrorsList().size()) { + leastInvalid = new ArrayList<>(this.getErrorsList()); } } // if no standard environment is valid, set the invalid to the // invalid that had the least errors. if (!valid) { - this.invalid = new HashMap<>(leastInvalid); + this.errorsList = new ArrayList<>(leastInvalid); } // return the validity. 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 e423a916a4..3db537c44b 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 @@ -6,6 +6,7 @@ import mage.cards.Sets; import mage.cards.SplitCard; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; +import mage.cards.decks.DeckValidatorErrorType; import mage.filter.FilterMana; import mage.game.GameTinyLeadersImpl; @@ -103,10 +104,10 @@ public class TinyLeaders extends Constructed { @Override public boolean validate(Deck deck) { boolean valid = true; - invalid.clear(); + errorsList.clear(); if (deck.getCards().size() != getDeckMinSize()) { - invalid.put("Deck", "Must contain " + getDeckMinSize() + " cards: has " + deck.getCards().size() + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + getDeckMinSize() + " cards: has " + deck.getCards().size() + " cards"); valid = false; } @@ -118,7 +119,7 @@ public class TinyLeaders extends Constructed { for (String bannedCard : banned) { if (counts.containsKey(bannedCard)) { - invalid.put(bannedCard, "Banned"); + addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard); valid = false; } } @@ -135,16 +136,16 @@ public class TinyLeaders extends Constructed { if (commander == null || commander.getManaCost().convertedManaCost() > 3) { if (commander == null) { if (deck.getName() == null) { - invalid.put("Leader", "You have to save your deck with the leader card name entered to the DECK NAME field of the DECK EDITOR (top left) so that XMage knows your leader." + addError(DeckValidatorErrorType.PRIMARY, "Leader", "You have to save your deck with the leader card name entered to the DECK NAME field of the DECK EDITOR (top left) so that XMage knows your leader." + "(You can use the \"Sultai\" for a UBG (3/3) default Commander or \"Glass\" for a colorless 3/3 default Commander.)"); } else { - invalid.put("Leader", "Leader [" + deck.getName() + "] not found. You have to enter the name of the leader card into the DECK NAME field of the DECK EDITOR (top left). Check your spelling " + addError(DeckValidatorErrorType.PRIMARY, "Leader", "Leader [" + deck.getName() + "] not found. You have to enter the name of the leader card into the DECK NAME field of the DECK EDITOR (top left). Check your spelling " + "(use the \"Sultai\" for a UBG (3/3) default Commander or \"Glass\" for a colorless (3/3) default Commander)"); } } if (commander != null && commander.getManaCost().convertedManaCost() > 3) { - invalid.put("Leader", "Commanders converted mana cost is greater than 3"); + addError(DeckValidatorErrorType.PRIMARY, "Leader", "Commanders converted mana cost is greater than 3"); } return false; } @@ -162,21 +163,21 @@ public class TinyLeaders extends Constructed { } } } else { - invalid.put("Commander", "Commander banned (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander banned (" + commander.getName() + ')'); valid = false; } } else { - invalid.put("Commander", "Commander invalide (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander invalide (" + commander.getName() + ')'); valid = false; } } else { - invalid.put("Commander", "Sideboard must contain only a maximum of 10 sideboard cards (the Tiny Leader name must be written to the deck name)"); + addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only a maximum of 10 sideboard cards (the Tiny Leader name must be written to the deck name)"); valid = false; } for (Card card : deck.getCards()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - invalid.put(card.getName(), "Not allowed Set " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set " + card.getExpansionSetCode()); valid = false; } } @@ -184,7 +185,7 @@ public class TinyLeaders extends Constructed { for (Card card : deck.getSideboard()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - invalid.put(card.getName(), "Not allowed Set " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set " + card.getExpansionSetCode()); valid = false; } } @@ -194,22 +195,22 @@ public class TinyLeaders extends Constructed { private boolean isCardFormatValid(Card card, Card commander, FilterMana color) { if (!cardHasValideColor(color, card)) { - invalid.put(card.getName(), "Invalid color (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + commander.getName() + ')'); return false; } //905.5b - Converted mana cost must be 3 or less if (card instanceof SplitCard) { if (((SplitCard) card).getLeftHalfCard().getManaCost().convertedManaCost() > 3) { - invalid.put(card.getName(), "Invalid cost (" + ((SplitCard) card).getLeftHalfCard().getManaCost().convertedManaCost() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + ((SplitCard) card).getLeftHalfCard().getManaCost().convertedManaCost() + ')'); return false; } if (((SplitCard) card).getRightHalfCard().getManaCost().convertedManaCost() > 3) { - invalid.put(card.getName(), "Invalid cost (" + ((SplitCard) card).getRightHalfCard().getManaCost().convertedManaCost() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + ((SplitCard) card).getRightHalfCard().getManaCost().convertedManaCost() + ')'); return false; } } else if (card.getManaCost().convertedManaCost() > 3) { - invalid.put(card.getName(), "Invalid cost (" + card.getManaCost().convertedManaCost() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + card.getManaCost().convertedManaCost() + ')'); return false; } return true; diff --git a/Mage.Server.Plugins/Mage.Deck.Limited/src/mage/deck/Limited.java b/Mage.Server.Plugins/Mage.Deck.Limited/src/mage/deck/Limited.java index 404a6c91b7..089398d671 100644 --- a/Mage.Server.Plugins/Mage.Deck.Limited/src/mage/deck/Limited.java +++ b/Mage.Server.Plugins/Mage.Deck.Limited/src/mage/deck/Limited.java @@ -2,6 +2,7 @@ package mage.deck; import mage.cards.decks.Deck; import mage.cards.decks.DeckValidator; +import mage.cards.decks.DeckValidatorErrorType; import java.util.HashMap; import java.util.Map; @@ -28,17 +29,17 @@ public class Limited extends DeckValidator { @Override public boolean validate(Deck deck) { boolean valid = true; - invalid.clear(); + errorsList.clear(); //20091005 - 100.2b if (deck.getCards().size() < getDeckMinSize()) { - invalid.put("Deck", "Must contain at least " + getDeckMinSize() + " cards: has only " + deck.getCards().size() + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain at least " + getDeckMinSize() + " cards: has only " + deck.getCards().size() + " cards"); valid = false; } Map counts = new HashMap<>(); countCards(counts, deck.getCards()); for (Map.Entry entry : counts.entrySet()) { if (entry.getValue() > 7 && entry.getKey().equals("Seven Dwarves")) { - invalid.put(entry.getKey(), "Too many: " + entry.getValue()); + addError(DeckValidatorErrorType.OTHER, entry.getKey(), "Too many: " + entry.getValue()); valid = false; } } diff --git a/Mage.Server/src/main/java/mage/server/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java index 5301e89334..5f42a4c927 100644 --- a/Mage.Server/src/main/java/mage/server/TableController.java +++ b/Mage.Server/src/main/java/mage/server/TableController.java @@ -3,6 +3,7 @@ package mage.server; import mage.MageException; import mage.cards.decks.Deck; import mage.cards.decks.DeckCardLists; +import mage.cards.decks.DeckValidatorError; import mage.cards.decks.DeckValidatorFactory; import mage.constants.RangeOfInfluence; import mage.constants.TableState; @@ -32,11 +33,8 @@ import mage.server.util.ThreadExecutor; import mage.view.ChatMessage; import org.apache.log4j.Logger; -import java.util.Locale; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Optional; -import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -150,9 +148,10 @@ public class TableController { } if (!Main.isTestMode() && !table.getValidator().validate(deck)) { StringBuilder sb = new StringBuilder("You (").append(name).append(") have an invalid deck for the selected ").append(table.getValidator().getName()).append(" Format. \n\n"); - for (Map.Entry entry : table.getValidator().getInvalid().entrySet()) { - sb.append(entry.getKey()).append(": ").append(entry.getValue()).append('\n'); - } + List errorsList = table.getValidator().getErrorsListSorted(); + errorsList.stream().forEach(error -> { + sb.append(error.getGroup()).append(": ").append(error.getMessage()).append("\n"); + }); sb.append("\n\nSelect a deck that is appropriate for the selected format and try again!"); user.showUserMessage("Join Table", sb.toString()); if (isOwner(userId)) { @@ -267,9 +266,10 @@ public class TableController { if (!Main.isTestMode() && !table.getValidator().validate(deck)) { StringBuilder sb = new StringBuilder("You (").append(name).append(") have an invalid deck for the selected ").append(table.getValidator().getName()).append(" Format. \n\n"); - for (Map.Entry entry : table.getValidator().getInvalid().entrySet()) { - sb.append(entry.getKey()).append(": ").append(entry.getValue()).append('\n'); - } + List errorsList = table.getValidator().getErrorsListSorted(); + errorsList.stream().forEach(error -> { + sb.append(error.getGroup()).append(": ").append(error.getMessage()).append("\n"); + }); sb.append("\n\nSelect a deck that is appropriate for the selected format and try again!"); user.showUserMessage("Join Table", sb.toString()); if (isOwner(userId)) { @@ -425,9 +425,10 @@ public class TableController { return false; } StringBuilder sb = new StringBuilder("Invalid deck for the selected ").append(table.getValidator().getName()).append(" format. \n\n"); - for (Map.Entry entry : table.getValidator().getInvalid().entrySet()) { - sb.append(entry.getKey()).append(": ").append(entry.getValue()).append('\n'); - } + List errorsList = table.getValidator().getErrorsListSorted(); + errorsList.stream().forEach(error -> { + sb.append(error.getGroup()).append(": ").append(error.getMessage()).append("\n"); + }); sb.append("\n\nAdd enough cards and try again!"); _user.get().showUserMessage("Submit deck", sb.toString()); return false; diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/deck/DeckValidatorTest.java b/Mage.Tests/src/test/java/org/mage/test/serverside/deck/DeckValidatorTest.java index abbbb3e156..f6e9f6ac39 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/deck/DeckValidatorTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/deck/DeckValidatorTest.java @@ -1,8 +1,5 @@ - package org.mage.test.serverside.deck; -import java.util.ArrayList; -import java.util.List; import mage.cards.decks.Deck; import mage.cards.decks.DeckValidator; import mage.cards.repository.CardInfo; @@ -14,8 +11,10 @@ import org.junit.Assert; import org.junit.Test; import org.mage.test.serverside.base.MageTestBase; +import java.util.ArrayList; +import java.util.List; + /** - * * @author LevelX2 */ public class DeckValidatorTest extends MageTestBase { @@ -65,7 +64,7 @@ public class DeckValidatorTest extends MageTestBase { DeckValidator validator = new Standard(); boolean validationSuccessful = testDeckValid(validator, deck); - Assert.assertTrue(validator.getInvalid().toString(), validationSuccessful); + Assert.assertTrue(validator.getErrorsListInfo(), validationSuccessful); } @Test @@ -79,7 +78,7 @@ public class DeckValidatorTest extends MageTestBase { DeckValidator validator = new Standard(); testDeckValid(validator, deck, sideboard); Assert.assertEquals("invalid message not correct", - "{Sideboard=Must contain no more than 15 cards : has 16 cards, Deck=Must contain at least 60 cards: has only 59 cards}", validator.getInvalid().toString()); + "Deck=Must contain at least 60 cards: has only 59 cards, Sideboard=Must contain no more than 15 cards : has 16 cards", validator.getErrorsListInfo()); } @Test @@ -229,119 +228,119 @@ public class DeckValidatorTest extends MageTestBase { deckList.add(new CardNameAmount("Ancestral Vision", 4)); deckList.add(new CardNameAmount("Mountain", 56)); boolean validationSuccessful = testDeckValid(validator, deckList); - Assert.assertTrue(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertTrue(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.clear(); deckList.add(new CardNameAmount("Ancient Den", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.add(new CardNameAmount("Birthing Pod", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.clear(); deckList.add(new CardNameAmount("Blazing Shoal", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.clear(); deckList.add(new CardNameAmount("Bloodbraid Elf", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertTrue(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertTrue(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.clear(); deckList.add(new CardNameAmount("Chrome Mox", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.clear(); deckList.add(new CardNameAmount("Cloudpost", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.clear(); deckList.add(new CardNameAmount("Dark Depths", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.clear(); deckList.add(new CardNameAmount("Deathrite Shaman", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.clear(); deckList.add(new CardNameAmount("Dig Through Time", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.clear(); deckList.add(new CardNameAmount("Dread Return", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.clear(); deckList.add(new CardNameAmount("Glimpse of Nature", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.clear(); deckList.add(new CardNameAmount("Great Furnace", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.clear(); deckList.add(new CardNameAmount("Green Sun's Zenith", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.clear(); deckList.add(new CardNameAmount("Hypergenesis", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.clear(); deckList.add(new CardNameAmount("Jace, the Mind Sculptor", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertTrue(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertTrue(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); deckList.clear(); deckList.add(new CardNameAmount("Mental Misstep", 4)); deckList.add(new CardNameAmount("Mountain", 56)); validationSuccessful = testDeckValid(validator, deckList); - Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful); - validator.getInvalid().clear(); + Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful); + validator.getErrorsList().clear(); } private boolean testDeckValid(DeckValidator validator, List cards) { diff --git a/Mage/src/main/java/mage/cards/decks/Constructed.java b/Mage/src/main/java/mage/cards/decks/Constructed.java index 66303911ef..9c6c74bbd0 100644 --- a/Mage/src/main/java/mage/cards/decks/Constructed.java +++ b/Mage/src/main/java/mage/cards/decks/Constructed.java @@ -58,15 +58,15 @@ public class Constructed extends DeckValidator { @Override public boolean validate(Deck deck) { boolean valid = true; - invalid.clear(); + errorsList.clear(); //20091005 - 100.2a if (deck.getCards().size() < getDeckMinSize()) { - invalid.put("Deck", "Must contain at least " + getDeckMinSize() + " cards: has only " + deck.getCards().size() + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain at least " + getDeckMinSize() + " cards: has only " + deck.getCards().size() + " cards"); valid = false; } //20130713 - 100.4a if (deck.getSideboard().size() > 15) { - invalid.put("Sideboard", "Must contain no more than 15 cards : has " + deck.getSideboard().size() + " cards"); + addError(DeckValidatorErrorType.DECK_SIZE, "Sideboard", "Must contain no more than 15 cards : has " + deck.getSideboard().size() + " cards"); valid = false; } @@ -77,7 +77,7 @@ public class Constructed extends DeckValidator { for (String bannedCard : banned) { if (counts.containsKey(bannedCard)) { - invalid.put(bannedCard, "Banned"); + addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard); valid = false; } } @@ -86,7 +86,7 @@ public class Constructed extends DeckValidator { if (counts.containsKey(restrictedCard)) { int count = counts.get(restrictedCard); if (count > 1) { - invalid.put(restrictedCard, "Restricted: " + count); + addError(DeckValidatorErrorType.OTHER, restrictedCard, "Restricted amount: " + count); valid = false; } } @@ -142,8 +142,8 @@ public class Constructed extends DeckValidator { break; } } - if (!legal && !invalid.containsKey(card.getName())) { - invalid.put(card.getName(), "Invalid rarity: " + card.getRarity()); + if (!legal && !errorsListContainsGroup(card.getName())) { + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid rarity: " + card.getRarity()); } return legal; } @@ -180,8 +180,8 @@ public class Constructed extends DeckValidator { legal = true; } - if (!legal && !invalid.containsKey(card.getName())) { - invalid.put(card.getName(), "Invalid set: " + card.getExpansionSetCode()); + if (!legal && !errorsListContainsGroup(card.getName())) { + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Invalid set: " + card.getExpansionSetCode()); } return legal; } @@ -192,11 +192,11 @@ public class Constructed extends DeckValidator { if (entry.getValue() > maxCopies && !basicLandNames.contains(entry.getKey()) && !anyNumberCardsAllowed.contains(entry.getKey())) { - invalid.put(entry.getKey(), "Too many: " + entry.getValue()); + addError(DeckValidatorErrorType.OTHER, entry.getKey(), "Too many: " + entry.getValue()); valid = false; } if (entry.getValue() > 7 && entry.getKey().equals("Seven Dwarves")) { - invalid.put(entry.getKey(), "Too many: " + entry.getValue()); + addError(DeckValidatorErrorType.OTHER, entry.getKey(), "Too many: " + entry.getValue()); valid = false; } } diff --git a/Mage/src/main/java/mage/cards/decks/DeckValidator.java b/Mage/src/main/java/mage/cards/decks/DeckValidator.java index af8f4d0115..b36c03c553 100644 --- a/Mage/src/main/java/mage/cards/decks/DeckValidator.java +++ b/Mage/src/main/java/mage/cards/decks/DeckValidator.java @@ -3,9 +3,8 @@ package mage.cards.decks; import mage.cards.Card; import java.io.Serializable; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; /** * @author BetaSteward_at_googlemail.com @@ -14,8 +13,7 @@ public abstract class DeckValidator implements Serializable { protected String name; protected String shortName; - - protected Map invalid = new HashMap<>(); + protected List errorsList = new ArrayList<>(); public DeckValidator(String name) { setName(name); @@ -49,8 +47,62 @@ public abstract class DeckValidator implements Serializable { this.shortName = shortName; } - public Map getInvalid() { - return invalid; + public List getErrorsList() { + return this.errorsList; + } + + /** + * Get errors list sorted by error type and texts + * + * @return + */ + public List getErrorsListSorted() { + List list = new ArrayList<>(this.getErrorsList()); + + Collections.sort(list, new Comparator() { + @Override + public int compare(DeckValidatorError e1, DeckValidatorError e2) { + int res = 0; + + // sort by error type + Integer order1 = e1.getErrorType().getSortOrder(); + Integer order2 = e2.getErrorType().getSortOrder(); + res = order2.compareTo(order1); + + // sort by group + if (res != 0) { + res = e2.getGroup().compareTo(e1.getGroup()); + } + + // sort by message + if (res != 0) { + res = e2.getMessage().compareTo(e1.getMessage()); + } + + return res; + } + }); + + return list; + } + + public String getErrorsListInfo() { + // for tests + return this.errorsList.stream() + .map(e -> e.getGroup() + "=" + e.getMessage()) + .collect(Collectors.joining(", ")); + } + + public void addError(DeckValidatorErrorType errorType, String group, String message) { + this.errorsList.add(new DeckValidatorError(errorType, group, message)); + } + + public boolean errorsListContainsGroup(String group) { + return this.errorsList.stream().anyMatch(e -> e.getGroup().equals(group)); + } + + public boolean isPartlyValid() { + return errorsList.size() == 0 || !errorsList.stream().anyMatch(e -> !e.getErrorType().isPartlyLegal()); } protected void countCards(Map counts, Collection cards) { diff --git a/Mage/src/main/java/mage/cards/decks/DeckValidatorError.java b/Mage/src/main/java/mage/cards/decks/DeckValidatorError.java new file mode 100644 index 0000000000..07650a0d5d --- /dev/null +++ b/Mage/src/main/java/mage/cards/decks/DeckValidatorError.java @@ -0,0 +1,29 @@ +package mage.cards.decks; + +/** + * @author JayDi85 + */ +public class DeckValidatorError { + + private final DeckValidatorErrorType errorType; + private final String group; + private final String message; + + public DeckValidatorError(DeckValidatorErrorType errorType, String group, String message) { + this.errorType = errorType; + this.group = group; + this.message = message; + } + + public DeckValidatorErrorType getErrorType() { + return this.errorType; + } + + public String getGroup() { + return this.group; + } + + public String getMessage() { + return this.message; + } +} diff --git a/Mage/src/main/java/mage/cards/decks/DeckValidatorErrorType.java b/Mage/src/main/java/mage/cards/decks/DeckValidatorErrorType.java new file mode 100644 index 0000000000..af43662ca6 --- /dev/null +++ b/Mage/src/main/java/mage/cards/decks/DeckValidatorErrorType.java @@ -0,0 +1,29 @@ +package mage.cards.decks; + +/** + * @author JayDi85 + */ +public enum DeckValidatorErrorType { + + PRIMARY(false, 10), // first errors to show (e.g. missing commander) + DECK_SIZE(true, 20), // wrong deck size (deck must be legal while building) + BANNED(false, 30), + WRONG_SET(false, 40), + OTHER(false, 50); + + private final boolean partlyLegal; // for deck legality panel: is it partly legal (e.g. show deck legal even without full deck size) + private final int sortOrder; // errors list sort order from small to big + + DeckValidatorErrorType(boolean partlyLegal, int sortOrder) { + this.partlyLegal = partlyLegal; + this.sortOrder = sortOrder; + } + + public boolean isPartlyLegal() { + return this.partlyLegal; + } + + public int getSortOrder() { + return this.sortOrder; + } +}