diff --git a/Mage.Client/src/main/java/mage/client/deck/generator/DeckGeneratorPool.java b/Mage.Client/src/main/java/mage/client/deck/generator/DeckGeneratorPool.java index f95f1cd0fdd..904eea401a4 100644 --- a/Mage.Client/src/main/java/mage/client/deck/generator/DeckGeneratorPool.java +++ b/Mage.Client/src/main/java/mage/client/deck/generator/DeckGeneratorPool.java @@ -438,15 +438,15 @@ public class DeckGeneratorPool { } // more spells than needed - remove - else if (spellsSize > (deckSize - landCount)) { - int spellsRemoved = (spellsSize) - (deckSize - landCount); - for (int i = 0; i < spellsRemoved; ++i) { - deckCards.remove(RandomUtil.nextInt(deckCards.size())); + if (spellsSize > nonLandSize) { + int removeCount = spellsSize - nonLandSize; + for (int i = 0; i < removeCount; ++i) { + deckCards.remove(RandomUtil.randomFromCollection(deckCards)); } } if (deckCards.size() != nonLandSize) { - logger.info("Can't generate full deck for selected settings - try again or choose more sets and less colors"); + logger.info("Can't generate full deck for selected settings - try again or choose more sets and less colors (wrong non land cards amount)"); } return deckCards; @@ -610,10 +610,11 @@ public class DeckGeneratorPool { if (needCommandersCount > 0 && !genPool.cardCounts.isEmpty()) { throw new IllegalArgumentException("Wrong code usage: generateSpells with creatures and commanders must be called as first"); } - List cardPool = CardRepository.instance.findCards(criteria); - List commanderPool = cardPool.stream() + List cardsPool = CardRepository.instance.findCards(criteria).stream() .map(CardInfo::createMockCard) .filter(genPool::isValidSpellCard) + .collect(Collectors.toList()); + List commandersPool = cardsPool.stream() .filter(genPool::isValidCommander) .collect(Collectors.toList()); @@ -621,14 +622,16 @@ public class DeckGeneratorPool { int usedCardsCount = 0; int validCommanders = 0; int reservesAdded = 0; - if (cardPool.size() > 0 && cardPool.size() >= needCardsCount) { + if (cardsPool.size() > 0 && cardsPool.size() >= needCardsCount) { int tries = 0; + List possibleCards = new ArrayList<>(cardsPool); + List possibleCommanders = new ArrayList<>(commandersPool); while (true) { tries++; // can't finish deck, stop and use reserved cards later if (tries > DeckGenerator.MAX_TRIES) { - logger.info("Can't generate full deck for selected settings - try again or choose more sets and less colors"); + logger.info("Can't generate full deck for selected settings - try again or choose more sets and less colors (max tries exceeded)"); break; } @@ -640,23 +643,31 @@ public class DeckGeneratorPool { validCommanders = 0; deckCMCs = genPool.getCMCsForSpellCount(needCardsCount); genPool.clearCards(true); + possibleCards = new ArrayList<>(cardsPool); + possibleCommanders = new ArrayList<>(commandersPool); continue; } break; } + if (possibleCards.isEmpty()) { + throw new IllegalStateException("Not enough cards to generate deck (possible cards is empty)"); + } + // choose commander first Card card = null; - if (validCommanders < needCommandersCount && !commanderPool.isEmpty()) { - card = RandomUtil.randomFromCollection(commanderPool); + if (validCommanders < needCommandersCount && !possibleCommanders.isEmpty()) { + card = RandomUtil.randomFromCollection(possibleCommanders); } // choose other cards after commander if (card == null) { - card = RandomUtil.randomFromCollection(cardPool).createMockCard(); + card = RandomUtil.randomFromCollection(possibleCards); } if (!genPool.isValidSpellCard(card)) { + possibleCards.remove(card); + possibleCommanders.remove(card); continue; } @@ -681,7 +692,7 @@ public class DeckGeneratorPool { } } } else { - throw new IllegalStateException("Not enough cards to generate deck."); + throw new IllegalStateException("Not enough cards to generate deck (cards pool too small)"); } } 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 326b38bbea9..af9528f5e77 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java @@ -19,7 +19,6 @@ import mage.client.dialog.AddLandDialog; import mage.client.dialog.PreferencesDialog; import mage.client.plugins.impl.Plugins; import mage.client.util.Event; -import mage.client.util.GUISizeHelper; import mage.client.util.Listener; import mage.client.util.audio.AudioManager; import mage.components.CardInfoPane; @@ -31,7 +30,6 @@ import mage.util.XmageThreadFactory; import mage.view.CardView; import mage.view.SimpleCardView; import org.apache.log4j.Logger; -import org.mage.card.arcane.ManaSymbols; import javax.swing.*; import javax.swing.border.Border; @@ -534,7 +532,8 @@ public class DeckEditorPanel extends javax.swing.JPanel { } } }); - refreshDeck(true); + + refreshDeck(true, false); // auto-import dropped files from OS if (mode == DeckEditorMode.FREE_BUILDING) { @@ -673,20 +672,28 @@ public class DeckEditorPanel extends javax.swing.JPanel { private void refreshDeck() { if (this.isVisible()) { // TODO: test auto-close deck with active lands dialog, e.g. on timeout - refreshDeck(false); + refreshDeck(false, false); } } - private void refreshDeck(boolean useLayout) { + private void refreshDeck(boolean useLayout, boolean useDeckValidation) { try { - setCursor(new Cursor(Cursor.WAIT_CURSOR)); + MageFrame.getDesktop().setCursor(new Cursor(Cursor.WAIT_CURSOR)); this.txtDeckName.setText(deck.getName()); deckArea.loadDeck(deck, useLayout, bigCard); + if (useDeckValidation) { + validateDeck(); + } } finally { - setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + MageFrame.getDesktop().setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } } + private void validateDeck() { + this.deckLegalityDisplay.setVisible(true); + this.deckLegalityDisplay.validateDeck(deck); + } + private void setTimeout(int s) { int minute = s / 60; int second = s - (minute * 60); @@ -762,7 +769,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { if (newDeck != null) { deck = newDeck; - refreshDeck(); + refreshDeck(false, true); } // save last deck import folder @@ -818,7 +825,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { Deck deckToAppend = Deck.load(DeckImporter.importDeckFromFile(tempDeckPath, errorMessages, false), true, true); processAndShowImportErrors(errorMessages); this.deck = Deck.append(deckToAppend, this.deck); - refreshDeck(); + refreshDeck(false, true); } catch (GameException e1) { JOptionPane.showMessageDialog(MageFrame.getDesktop(), e1.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE); } finally { @@ -922,7 +929,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { if (newDeck != null) { deck = newDeck; - refreshDeck(); + refreshDeck(false, true); return true; } @@ -1441,7 +1448,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { if (newDeck != null) { deck = newDeck; - refreshDeck(true); + refreshDeck(true, true); } // save last deck history @@ -1474,7 +1481,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { // in deck editor mode - clear all cards deck = new Deck(); } - refreshDeck(); + refreshDeck(false, true); }//GEN-LAST:event_btnNewActionPerformed private void btnExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnExitActionPerformed @@ -1483,7 +1490,9 @@ public class DeckEditorPanel extends javax.swing.JPanel { private void btnAddLandActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddLandActionPerformed AddLandDialog dialog = new AddLandDialog(); - dialog.showDialog(deck, mode, this::refreshDeck); + dialog.showDialog(deck, mode, () -> { + this.refreshDeck(false, true); + }); }//GEN-LAST:event_btnAddLandActionPerformed private void btnGenDeckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGenDeckActionPerformed @@ -1501,7 +1510,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { } finally { MageFrame.getDesktop().setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } - refreshDeck(); + refreshDeck(false, true); }//GEN-LAST:event_btnGenDeckActionPerformed private void btnSubmitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSubmitActionPerformed @@ -1548,8 +1557,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { }//GEN-LAST:event_btnExportActionPerformed private void btnLegalityActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLegalityActionPerformed - this.deckLegalityDisplay.setVisible(true); - this.deckLegalityDisplay.validateDeck(deck); + validateDeck(); }//GEN-LAST:event_btnLegalityActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables