From 486c0d7c2cb6f977b8d9e05daef62b011623ab16 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 17 Aug 2020 05:14:12 +0400 Subject: [PATCH] GUI: added problem cards selection on legality label clicks (#6854) --- .../java/mage/client/cards/DragCardGrid.java | 13 ++ .../mage/client/components/LegalityLabel.java | 4 +- .../client/deckeditor/DeckEditorPanel.java | 117 +++++++++++------- .../client/deckeditor/DeckLegalityPanel.java | 1 - .../src/mage/deck/AusHighlander.java | 2 +- .../src/mage/deck/Brawl.java | 16 +-- .../src/mage/deck/CanadianHighlander.java | 2 +- .../src/mage/deck/Commander.java | 20 +-- .../src/mage/deck/FreeformCommander.java | 10 +- .../src/mage/deck/Momir.java | 2 +- .../src/mage/deck/Oathbreaker.java | 12 +- .../src/mage/deck/PennyDreadfulCommander.java | 18 +-- .../src/mage/deck/TinyLeaders.java | 18 +-- .../src/mage/deck/Limited.java | 2 +- .../java/mage/cards/decks/Constructed.java | 12 +- .../java/mage/cards/decks/DeckValidator.java | 15 ++- .../mage/cards/decks/DeckValidatorError.java | 8 +- 17 files changed, 167 insertions(+), 105 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java index 7be83dd13b8..7c872fd3d5f 100644 --- a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java +++ b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java @@ -1064,6 +1064,19 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg } } + public void selectByName(List cardNames) { + for (List> gridRow : cardGrid) { + for (List stack : gridRow) { + for (CardView card : stack) { + if (cardNames.contains(card.getName())) { + card.setSelected(true); + cardViews.get(card.getId()).update(card); + } + } + } + } + } + private void hideSelection() { Collection toHide = dragCardList(); for (DragCardGridListener l : listeners) { 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 5683375127f..aed4e61bf66 100644 --- a/Mage.Client/src/main/java/mage/client/components/LegalityLabel.java +++ b/Mage.Client/src/main/java/mage/client/components/LegalityLabel.java @@ -113,7 +113,7 @@ public class LegalityLabel extends JLabel { return sortedErrorsList.stream() .reduce("" + "

Deck is INVALID

" - + "The following problems have been found:" + + "The following problems have been found (click to select problem cards):" + "
" + "", (str, error) -> String.format("%s", str, escapeHtml(error.getGroup()), escapeHtml(error.getMessage())), String::concat) @@ -125,7 +125,7 @@ public class LegalityLabel extends JLabel { return sortedErrorsList.stream() .reduce("" + "

Deck is PARTLY VALID

" - + "The following problems have been found:" + + "The following problems have been found (click to select problem cards):" + "
" + "
%s%s
", (str, error) -> String.format("%s", str, escapeHtml(error.getGroup()), escapeHtml(error.getMessage())), String::concat) diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java index 887c193764d..982383c5a6c 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java @@ -9,6 +9,7 @@ import mage.client.MageFrame; import mage.client.SessionHandler; import mage.client.cards.BigCard; import mage.client.cards.ICardGrid; +import mage.client.components.LegalityLabel; import mage.client.constants.Constants.DeckEditorMode; import mage.client.deck.generator.DeckGenerator; import mage.client.deck.generator.DeckGenerator.DeckGeneratorException; @@ -27,12 +28,11 @@ import mage.view.SimpleCardView; import org.apache.log4j.Logger; import javax.swing.*; +import javax.swing.border.Border; import javax.swing.filechooser.FileFilter; import java.awt.*; import java.awt.dnd.DropTarget; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.HierarchyEvent; +import java.awt.event.*; import java.io.File; import java.io.IOException; import java.util.List; @@ -48,11 +48,15 @@ import static mage.cards.decks.DeckFormats.XMAGE_INFO; public class DeckEditorPanel extends javax.swing.JPanel { private static final Logger logger = Logger.getLogger(DeckEditorPanel.class); + private static final Border LEGALITY_LABEL_BORDER_SELECTED = BorderFactory.createLineBorder(Color.gray, 2); + private static final Border LEGALITY_LABEL_BORDER_EMPTY = BorderFactory.createEmptyBorder(); + private final JFileChooser fcSelectDeck; private final JFileChooser fcImportDeck; private final JFileChooser fcExportDeck; - private Deck deck = new Deck(); private final Map temporaryCards = new HashMap<>(); // Cards dragged out of one part of the view into another + private final String LAST_DECK_FOLDER = "lastDeckFolder"; + private Deck deck = new Deck(); private boolean isShowCardInfo = false; private UUID tableId; private DeckEditorMode mode; @@ -60,7 +64,41 @@ public class DeckEditorPanel extends javax.swing.JPanel { private javax.swing.Timer countdown; private UpdateDeckTask updateDeckTask; private int timeToSubmit = -1; - private final String LAST_DECK_FOLDER = "lastDeckFolder"; + // Variables declaration - do not modify//GEN-BEGIN:variables + private mage.client.cards.BigCard bigCard; + private javax.swing.JButton btnAddLand; + private javax.swing.JButton btnExit; + private javax.swing.JButton btnExport; + private javax.swing.JButton btnGenDeck; + private javax.swing.JButton btnImport; + private javax.swing.JButton btnLegality; + private javax.swing.JButton btnLoad; + private javax.swing.JButton btnNew; + private javax.swing.JButton btnSave; + private javax.swing.JButton btnSubmit; + private javax.swing.JButton btnSubmitTimer; + private JComponent cardInfoPane; + /* + private org.mage.plugins.card.info.CardInfoPaneImpl cardInfoPane; + */ + private mage.client.deckeditor.CardSelector cardSelector; + private mage.client.deckeditor.DeckArea deckArea; + private mage.client.deckeditor.DeckLegalityPanel deckLegalityDisplay; + private javax.swing.JLabel lblDeckName; + private javax.swing.JPanel panelDeck; + private javax.swing.JPanel panelDeckCreate; + private javax.swing.JPanel panelDeckDraft; + private javax.swing.JPanel panelDeckExit; + private javax.swing.JPanel panelDeckLands; + private javax.swing.JPanel panelDeckLoad; + private javax.swing.JPanel panelDeckName; + private javax.swing.JPanel panelDeckSave; + private javax.swing.JPanel panelInfo; + private javax.swing.JPanel panelLeft; + private javax.swing.JSplitPane panelRight; + private javax.swing.JScrollPane scrollPaneInfo; + private javax.swing.JTextField txtDeckName; + private javax.swing.JTextField txtTimeRemaining; public DeckEditorPanel() { initComponents(); @@ -105,6 +143,38 @@ public class DeckEditorPanel extends javax.swing.JPanel { } } }); + + // deck legality cards selection + Arrays.stream(deckLegalityDisplay.getComponents()) + .filter(c -> c instanceof LegalityLabel) + .forEach(c -> { + c.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + List cardNames = new ArrayList<>(); + LegalityLabel label = (LegalityLabel) e.getComponent(); + label.getValidator().getErrorsList().stream() + .map(DeckValidatorError::getCardName) + .filter(Objects::nonNull) + .forEach(cardNames::add); + deckArea.getDeckList().deselectAll(); + deckArea.getDeckList().selectByName(cardNames); + deckArea.getSideboardList().deselectAll(); + deckArea.getSideboardList().selectByName(cardNames); + } + + @Override + public void mouseEntered(MouseEvent e) { + LegalityLabel label = (LegalityLabel) e.getComponent(); + label.setBorder(LEGALITY_LABEL_BORDER_SELECTED); + } + + @Override + public void mouseExited(MouseEvent e) { + LegalityLabel label = (LegalityLabel) e.getComponent(); + label.setBorder(LEGALITY_LABEL_BORDER_EMPTY); + } + }); + }); } /** @@ -1447,43 +1517,6 @@ public class DeckEditorPanel extends javax.swing.JPanel { this.deckLegalityDisplay.setVisible(true); this.deckLegalityDisplay.validateDeck(deck); }//GEN-LAST:event_btnLegalityActionPerformed - - - // Variables declaration - do not modify//GEN-BEGIN:variables - private mage.client.cards.BigCard bigCard; - private javax.swing.JButton btnAddLand; - private javax.swing.JButton btnExit; - private javax.swing.JButton btnExport; - private javax.swing.JButton btnGenDeck; - private javax.swing.JButton btnImport; - private javax.swing.JButton btnLegality; - private javax.swing.JButton btnLoad; - private javax.swing.JButton btnNew; - private javax.swing.JButton btnSave; - private javax.swing.JButton btnSubmit; - private javax.swing.JButton btnSubmitTimer; - private JComponent cardInfoPane; - /* - private org.mage.plugins.card.info.CardInfoPaneImpl cardInfoPane; - */ - private mage.client.deckeditor.CardSelector cardSelector; - private mage.client.deckeditor.DeckArea deckArea; - private mage.client.deckeditor.DeckLegalityPanel deckLegalityDisplay; - private javax.swing.JLabel lblDeckName; - private javax.swing.JPanel panelDeck; - private javax.swing.JPanel panelDeckCreate; - private javax.swing.JPanel panelDeckDraft; - private javax.swing.JPanel panelDeckExit; - private javax.swing.JPanel panelDeckLands; - private javax.swing.JPanel panelDeckLoad; - private javax.swing.JPanel panelDeckName; - private javax.swing.JPanel panelDeckSave; - private javax.swing.JPanel panelInfo; - private javax.swing.JPanel panelLeft; - private javax.swing.JSplitPane panelRight; - private javax.swing.JScrollPane scrollPaneInfo; - private javax.swing.JTextField txtDeckName; - private javax.swing.JTextField txtTimeRemaining; // End of variables declaration//GEN-END:variables } diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckLegalityPanel.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckLegalityPanel.java index d253339dcde..6a7c79731e8 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckLegalityPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckLegalityPanel.java @@ -103,7 +103,6 @@ public class DeckLegalityPanel extends javax.swing.JPanel { protected LegalityLabel addLegalityLabel(DeckValidator validator) { LegalityLabel label = new LegalityLabel(validator); add(label); - return label; } 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 437b1fea683..98d16ef6f7c 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 @@ -140,7 +140,7 @@ public class AusHighlander extends Constructed { String cn = entry.getKey(); if (pointMap.containsKey(cn)) { totalPoints += pointMap.get(cn); - addError(DeckValidatorErrorType.OTHER, entry.getKey(), " " + pointMap.get(cn) + " point " + cn); + addError(DeckValidatorErrorType.OTHER, entry.getKey(), " " + pointMap.get(cn) + " point " + cn, true); } } if (totalPoints > 7) { 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 9a73bb9da72..9657f4df7de 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 @@ -73,12 +73,12 @@ public class Brawl extends Constructed { if (brawler != null) { ManaUtil.collectColorIdentity(colorIdentity, brawler.getColorIdentity()); if (bannedCommander.contains(brawler.getName())) { - addError(DeckValidatorErrorType.PRIMARY, "Brawl", "Brawler banned (" + brawler.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, brawler.getName(), "Brawler banned (" + brawler.getName() + ')', true); valid = false; } if (!((brawler.isCreature() && brawler.isLegendary()) || brawler.isPlaneswalker() || brawler.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) { - addError(DeckValidatorErrorType.PRIMARY, "Brawl", "Invalid Brawler (" + brawler.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, brawler.getName(), "Brawler Invalid (" + brawler.getName() + ')', true); valid = false; } } @@ -98,7 +98,7 @@ public class Brawl extends Constructed { for (String bannedCard : banned) { if (counts.containsKey(bannedCard)) { - addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard); + addError(DeckValidatorErrorType.BANNED, bannedCard, "Banned", true); valid = false; } } @@ -116,7 +116,7 @@ public class Brawl extends Constructed { && !(colorIdentity.isColorless() && basicsInDeck.size() == 1 && basicsInDeck.contains(card.getName()))) { - addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')', true); valid = false; } } @@ -125,14 +125,14 @@ public class Brawl extends Constructed { && !(colorIdentity.isColorless() && basicsInDeck.size() == 1 && basicsInDeck.contains(card.getName()))) { - addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')', true); valid = false; } } for (Card card : deck.getCards()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode(), true); valid = false; } } @@ -140,7 +140,7 @@ public class Brawl extends Constructed { for (Card card : deck.getSideboard()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode(), true); valid = false; } } @@ -153,7 +153,7 @@ public class Brawl extends Constructed { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; if (!companionAbility.isLegal(cards, getDeckMinSize())) { - addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion"); + addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Brawl Companion Invalid", true); 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 c2b819cab11..ae428975881 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 @@ -98,7 +98,7 @@ public class CanadianHighlander extends Constructed { String cn = entry.getKey(); if (pointMap.containsKey(cn)) { totalPoints += pointMap.get(cn); - addError(DeckValidatorErrorType.OTHER, entry.getKey(), " " + pointMap.get(cn) + " point " + cn); + addError(DeckValidatorErrorType.OTHER, entry.getKey(), " " + pointMap.get(cn) + " point " + cn, true); } } if (totalPoints > allowedPoints) { 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 dae753fe8b6..0a5dd23ddfa 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 @@ -160,7 +160,7 @@ public class Commander extends Constructed { for (String bannedCard : banned) { if (counts.containsKey(bannedCard)) { - addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard); + addError(DeckValidatorErrorType.BANNED, bannedCard, "Banned", true); valid = false; } } @@ -171,18 +171,18 @@ public class Commander extends Constructed { } for (Card commander : commanders) { if (bannedCommander.contains(commander.getName())) { - addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander banned (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander banned (" + commander.getName() + ')', true); valid = false; } if ((!commander.isCreature() || !commander.isLegendary()) && (!commander.isPlaneswalker() || !commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) { - addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander invalid (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander invalid (" + commander.getName() + ')', true); valid = false; } if (commanders.size() == 2) { if (commander.getAbilities().contains(PartnerAbility.getInstance())) { if (bannedPartner.contains(commander.getName())) { - addError(DeckValidatorErrorType.PRIMARY, "Commander", "Partner banned (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander Partner banned (" + commander.getName() + ')', true); valid = false; } } else { @@ -193,7 +193,7 @@ public class Commander extends Constructed { .map(PartnerWithAbility::getPartnerName) .anyMatch(commanderNames::contains); if (!partnersWith) { - addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander without Partner (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander without Partner (" + commander.getName() + ')', true); valid = false; } } @@ -208,20 +208,20 @@ public class Commander extends Constructed { for (Card card : deck.getCards()) { if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) { - addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')', true); valid = false; } } for (Card card : deck.getSideboard()) { if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) { - addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')', true); valid = false; } } for (Card card : deck.getCards()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode(), true); valid = false; } } @@ -229,7 +229,7 @@ public class Commander extends Constructed { for (Card card : deck.getSideboard()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode(), true); valid = false; } } @@ -242,7 +242,7 @@ public class Commander extends Constructed { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; if (!companionAbility.isLegal(cards, getDeckMinSize())) { - addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion"); + addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Commander Companion (deck invalid for companion)", true); valid = false; } break; 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 4c045f3c9a1..3f2fd77f884 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 @@ -120,7 +120,7 @@ public class FreeformCommander extends Constructed { } for (Card commander : commanders) { if (!commander.isCreature() || !commander.isLegendary()) { - addError(DeckValidatorErrorType.PRIMARY, "Commander", "For Freeform Commander, the commander must be a creature or be legendary. Yours was: " + commander.getName()); + addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "For Freeform Commander, the commander must be a creature or be legendary. Yours was: " + commander.getName(), true); valid = false; } if (commanders.size() == 2) { @@ -132,7 +132,7 @@ public class FreeformCommander extends Constructed { .map(PartnerWithAbility::getPartnerName) .anyMatch(commanderNames::contains); if (!partnersWith) { - addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander without Partner (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander without Partner (" + commander.getName() + ')', true); valid = false; } } @@ -147,13 +147,13 @@ public class FreeformCommander extends Constructed { for (Card card : deck.getCards()) { if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) { - addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')', true); valid = false; } } for (Card card : deck.getSideboard()) { if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) { - addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')', true); valid = false; } } @@ -165,7 +165,7 @@ public class FreeformCommander extends Constructed { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; if (!companionAbility.isLegal(cards, getDeckMinSize())) { - addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion"); + addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Commander Companion (deck invalid for companion)", true); valid = false; } break; 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 8e9a46bf44e..67dea63fd33 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 @@ -41,7 +41,7 @@ public class Momir extends DeckValidator { List basicLandNames = new ArrayList<>(Arrays.asList("Forest", "Island", "Mountain", "Swamp", "Plains", "Wastes")); for (Card card : deck.getCards()) { if (!basicLandNames.contains(card.getName())) { - addError(DeckValidatorErrorType.OTHER, card.getName(), "Only basic lands are allowed"); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Only basic lands are allowed", true); 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 7b3c8a8ee9d..6debaeebf60 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 @@ -96,7 +96,7 @@ public class Oathbreaker extends Vintage { for (String bannedCard : banned) { if (counts.containsKey(bannedCard)) { - addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard); + addError(DeckValidatorErrorType.BANNED, bannedCard, "Banned", true); valid = false; } } @@ -121,7 +121,7 @@ public class Oathbreaker extends Vintage { // color identity from commanders only, not spell ManaUtil.collectColorIdentity(allCommandersColor, commander.getColorIdentity()); } else { - addError(DeckValidatorErrorType.PRIMARY, "Oathbreaker", "Only planeswalker can be Oathbreaker, not " + commander.getName()); + addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Oathbreaker (only planeswalker can be Oathbreaker, not " + commander.getName(), true); valid = false; } } @@ -154,7 +154,7 @@ public class Oathbreaker extends Vintage { } } if (!partnersWith) { - addError(DeckValidatorErrorType.PRIMARY, "Oathbreaker", "Oathbreaker without Partner (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Oathbreaker without Partner (" + commander.getName() + ')', true); valid = false; } } @@ -176,7 +176,7 @@ public class Oathbreaker extends Vintage { } } if (!haveSameColor) { - addError(DeckValidatorErrorType.PRIMARY, "Signature Spell", "Can't find oathbreaker with compatible color identity (" + spell.getName() + " - " + spellColor + ")"); + addError(DeckValidatorErrorType.PRIMARY, spell.getName(), "Signature Spell (can't find oathbreaker with compatible color identity: " + spell.getName() + " - " + spellColor + ")", true); valid = false; } } @@ -190,7 +190,7 @@ public class Oathbreaker extends Vintage { for (Card card : deck.getCards()) { if (!ManaUtil.isColorIdentityCompatible(allCommandersColor, card.getColorIdentity())) { - addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + card.getColorIdentity() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + card.getColorIdentity() + ')', true); valid = false; } } @@ -198,7 +198,7 @@ public class Oathbreaker extends Vintage { for (Card card : deck.getSideboard()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode(), true); 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 06e6b594f75..f78cc373473 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 @@ -113,7 +113,7 @@ public class PennyDreadfulCommander extends Constructed { for (String wantedCard : counts.keySet()) { if (!(pdAllowed.containsKey(wantedCard))) { - addError(DeckValidatorErrorType.BANNED, "Banned", wantedCard); + addError(DeckValidatorErrorType.BANNED, wantedCard, "Banned", true); valid = false; } } @@ -124,12 +124,12 @@ public class PennyDreadfulCommander extends Constructed { } for (Card commander : commanders) { if (bannedCommander.contains(commander.getName())) { - addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander banned (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander banned (" + commander.getName() + ')', true); valid = false; } if ((!commander.isCreature() || !commander.isLegendary()) && (!commander.isPlaneswalker() || !commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) { - addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander invalid (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander invalid (" + commander.getName() + ')', true); valid = false; } if (commanders.size() == 2) { @@ -141,7 +141,7 @@ public class PennyDreadfulCommander extends Constructed { .map(PartnerWithAbility::getPartnerName) .anyMatch(commanderNames::contains); if (!partnersWith) { - addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander without Partner (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander without Partner (" + commander.getName() + ')', true); valid = false; } } @@ -156,20 +156,20 @@ public class PennyDreadfulCommander extends Constructed { for (Card card : deck.getCards()) { if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) { - addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')', true); valid = false; } } for (Card card : deck.getSideboard()) { if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) { - addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')', true); valid = false; } } for (Card card : deck.getCards()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode(), true); valid = false; } } @@ -177,7 +177,7 @@ public class PennyDreadfulCommander extends Constructed { for (Card card : deck.getSideboard()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode(), true); valid = false; } } @@ -190,7 +190,7 @@ public class PennyDreadfulCommander extends Constructed { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; if (!companionAbility.isLegal(cards, getDeckMinSize())) { - addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion"); + addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Commander Companion (deck invalid for companion)", true); valid = false; } break; 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 3db537c44bf..0d86bc7525f 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 @@ -119,7 +119,7 @@ public class TinyLeaders extends Constructed { for (String bannedCard : banned) { if (counts.containsKey(bannedCard)) { - addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard); + addError(DeckValidatorErrorType.BANNED, bannedCard, "Banned", true); valid = false; } } @@ -163,11 +163,11 @@ public class TinyLeaders extends Constructed { } } } else { - addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander banned (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander banned (" + commander.getName() + ')', true); valid = false; } } else { - addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander invalide (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander invalide (" + commander.getName() + ')', true); valid = false; } } else { @@ -177,7 +177,7 @@ public class TinyLeaders extends Constructed { for (Card card : deck.getCards()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set " + card.getExpansionSetCode(), true); valid = false; } } @@ -185,7 +185,7 @@ public class TinyLeaders extends Constructed { for (Card card : deck.getSideboard()) { if (!isSetAllowed(card.getExpansionSetCode())) { if (!legalSets(card)) { - addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set " + card.getExpansionSetCode(), true); valid = false; } } @@ -195,22 +195,22 @@ public class TinyLeaders extends Constructed { private boolean isCardFormatValid(Card card, Card commander, FilterMana color) { if (!cardHasValideColor(color, card)) { - addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + commander.getName() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + commander.getName() + ')', true); return false; } //905.5b - Converted mana cost must be 3 or less if (card instanceof SplitCard) { if (((SplitCard) card).getLeftHalfCard().getManaCost().convertedManaCost() > 3) { - addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + ((SplitCard) card).getLeftHalfCard().getManaCost().convertedManaCost() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + ((SplitCard) card).getLeftHalfCard().getManaCost().convertedManaCost() + ')', true); return false; } if (((SplitCard) card).getRightHalfCard().getManaCost().convertedManaCost() > 3) { - addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + ((SplitCard) card).getRightHalfCard().getManaCost().convertedManaCost() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + ((SplitCard) card).getRightHalfCard().getManaCost().convertedManaCost() + ')', true); return false; } } else if (card.getManaCost().convertedManaCost() > 3) { - addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + card.getManaCost().convertedManaCost() + ')'); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + card.getManaCost().convertedManaCost() + ')', true); 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 089398d6719..d2391aab2fc 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 @@ -39,7 +39,7 @@ public class Limited extends DeckValidator { countCards(counts, deck.getCards()); for (Map.Entry entry : counts.entrySet()) { if (entry.getValue() > 7 && entry.getKey().equals("Seven Dwarves")) { - addError(DeckValidatorErrorType.OTHER, entry.getKey(), "Too many: " + entry.getValue()); + addError(DeckValidatorErrorType.OTHER, entry.getKey(), "Too many: " + entry.getValue(), true); valid = false; } } diff --git a/Mage/src/main/java/mage/cards/decks/Constructed.java b/Mage/src/main/java/mage/cards/decks/Constructed.java index 9c6c74bbd01..da1a2928e14 100644 --- a/Mage/src/main/java/mage/cards/decks/Constructed.java +++ b/Mage/src/main/java/mage/cards/decks/Constructed.java @@ -77,7 +77,7 @@ public class Constructed extends DeckValidator { for (String bannedCard : banned) { if (counts.containsKey(bannedCard)) { - addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard); + addError(DeckValidatorErrorType.BANNED, bannedCard, "Banned", true); valid = false; } } @@ -86,7 +86,7 @@ public class Constructed extends DeckValidator { if (counts.containsKey(restrictedCard)) { int count = counts.get(restrictedCard); if (count > 1) { - addError(DeckValidatorErrorType.OTHER, restrictedCard, "Restricted amount: " + count); + addError(DeckValidatorErrorType.OTHER, restrictedCard, "Restricted amount: " + count, true); valid = false; } } @@ -143,7 +143,7 @@ public class Constructed extends DeckValidator { } } if (!legal && !errorsListContainsGroup(card.getName())) { - addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid rarity: " + card.getRarity()); + addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid rarity: " + card.getRarity(), true); } return legal; } @@ -181,7 +181,7 @@ public class Constructed extends DeckValidator { } if (!legal && !errorsListContainsGroup(card.getName())) { - addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Invalid set: " + card.getExpansionSetCode()); + addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Invalid set: " + card.getExpansionSetCode(), true); } return legal; } @@ -192,11 +192,11 @@ public class Constructed extends DeckValidator { if (entry.getValue() > maxCopies && !basicLandNames.contains(entry.getKey()) && !anyNumberCardsAllowed.contains(entry.getKey())) { - addError(DeckValidatorErrorType.OTHER, entry.getKey(), "Too many: " + entry.getValue()); + addError(DeckValidatorErrorType.OTHER, entry.getKey(), "Too many: " + entry.getValue(), true); valid = false; } if (entry.getValue() > 7 && entry.getKey().equals("Seven Dwarves")) { - addError(DeckValidatorErrorType.OTHER, entry.getKey(), "Too many: " + entry.getValue()); + addError(DeckValidatorErrorType.OTHER, entry.getKey(), "Too many: " + entry.getValue(), true); 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 465c708531e..8457f835698 100644 --- a/Mage/src/main/java/mage/cards/decks/DeckValidator.java +++ b/Mage/src/main/java/mage/cards/decks/DeckValidator.java @@ -93,7 +93,7 @@ public abstract class DeckValidator implements Serializable { int otherErrorsCount = list.size() - maxErrors; list = list.stream().limit(maxErrors).collect(Collectors.toList()); list.add(new DeckValidatorError(DeckValidatorErrorType.OTHER, "...", - "and more " + otherErrorsCount + " error" + (otherErrorsCount > 1 ? "s" : ""))); + "and more " + otherErrorsCount + " error" + (otherErrorsCount > 1 ? "s" : ""), null)); } return list; @@ -106,8 +106,19 @@ public abstract class DeckValidator implements Serializable { .collect(Collectors.joining(", ")); } + /** + * @param isCardError group contains card name that can be selected as wrong card + */ + public void addError(DeckValidatorErrorType errorType, String group, String message, boolean isCardError) { + addError(errorType, group, message, (isCardError ? group : null)); + } + public void addError(DeckValidatorErrorType errorType, String group, String message) { - this.errorsList.add(new DeckValidatorError(errorType, group, message)); + addError(errorType, group, message, null); + } + + private void addError(DeckValidatorErrorType errorType, String group, String message, String cardName) { + this.errorsList.add(new DeckValidatorError(errorType, group, message, cardName)); } public boolean errorsListContainsGroup(String group) { diff --git a/Mage/src/main/java/mage/cards/decks/DeckValidatorError.java b/Mage/src/main/java/mage/cards/decks/DeckValidatorError.java index 07650a0d5d9..e1329655fb9 100644 --- a/Mage/src/main/java/mage/cards/decks/DeckValidatorError.java +++ b/Mage/src/main/java/mage/cards/decks/DeckValidatorError.java @@ -8,11 +8,13 @@ public class DeckValidatorError { private final DeckValidatorErrorType errorType; private final String group; private final String message; + private final String cardName; - public DeckValidatorError(DeckValidatorErrorType errorType, String group, String message) { + public DeckValidatorError(DeckValidatorErrorType errorType, String group, String message, String cardName) { this.errorType = errorType; this.group = group; this.message = message; + this.cardName = cardName; } public DeckValidatorErrorType getErrorType() { @@ -26,4 +28,8 @@ public class DeckValidatorError { public String getMessage() { return this.message; } + + public String getCardName() { + return this.cardName; + } }
%s%s