From f0f741ace4e57cdf49182b7b78312aab09727095 Mon Sep 17 00:00:00 2001
From: Krazy
Date: Sat, 2 May 2015 00:39:34 +0000
Subject: [PATCH] Cleaned up and the new quest section for readability and
added an option to allow duplicate cards in a quest's starting pool
---
.../screens/home/quest/CSubmenuQuestData.java | 78 ++++----
.../screens/home/quest/VSubmenuQuestData.java | 174 +++++++++---------
.../forge/screens/quest/NewQuestScreen.java | 73 +++-----
.../main/java/forge/quest/BoosterUtils.java | 74 ++++----
.../main/java/forge/quest/QuestSpellShop.java | 35 ++--
.../forge/quest/StartingPoolPreferences.java | 40 ++--
6 files changed, 227 insertions(+), 247 deletions(-)
diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestData.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestData.java
index 88ca50d2a60..f0bbc94b99e 100644
--- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestData.java
+++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestData.java
@@ -1,17 +1,5 @@
package forge.screens.home.quest;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import javax.swing.SwingUtilities;
-
import forge.UiCommand;
import forge.deck.Deck;
import forge.deck.DeckSection;
@@ -20,18 +8,19 @@ import forge.gui.framework.ICDoc;
import forge.item.PaperCard;
import forge.model.FModel;
import forge.properties.ForgeConstants;
-import forge.quest.QuestController;
-import forge.quest.QuestMode;
-import forge.quest.QuestUtil;
-import forge.quest.QuestWorld;
-import forge.quest.StartingPoolPreferences;
-import forge.quest.StartingPoolType;
+import forge.quest.*;
import forge.quest.data.GameFormatQuest;
import forge.quest.data.QuestData;
import forge.quest.data.QuestPreferences.QPref;
import forge.quest.io.QuestDataIO;
import forge.toolbox.FOptionPane;
+import javax.swing.*;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.*;
+import java.util.Map.Entry;
+
/**
* Controls the quest data submenu in the home UI.
*
@@ -80,27 +69,33 @@ public enum CSubmenuQuestData implements ICDoc {
unselectableSets.add("ARC");
unselectableSets.add("PC2");
- view.getBtnCustomFormat().setCommand(new UiCommand() { @Override public void run() {
- final DialogChooseSets dialog = new DialogChooseSets(customFormatCodes, unselectableSets, false);
- dialog.setOkCallback(new Runnable() {
- @Override
- public void run() {
- customFormatCodes.clear();
- customFormatCodes.addAll(dialog.getSelectedSets());
- }
- });
- } });
+ view.getBtnCustomFormat().setCommand(new UiCommand() {
+ @Override
+ public void run() {
+ final DialogChooseSets dialog = new DialogChooseSets(customFormatCodes, unselectableSets, false);
+ dialog.setOkCallback(new Runnable() {
+ @Override
+ public void run() {
+ customFormatCodes.clear();
+ customFormatCodes.addAll(dialog.getSelectedSets());
+ }
+ });
+ }
+ });
- view.getBtnPrizeCustomFormat().setCommand(new UiCommand() { @Override public void run() {
- final DialogChooseSets dialog = new DialogChooseSets(customPrizeFormatCodes, unselectableSets, false);
- dialog.setOkCallback(new Runnable() {
- @Override
- public void run() {
- customPrizeFormatCodes.clear();
- customPrizeFormatCodes.addAll(dialog.getSelectedSets());
- }
- });
- } });
+ view.getBtnPrizeCustomFormat().setCommand(new UiCommand() {
+ @Override
+ public void run() {
+ final DialogChooseSets dialog = new DialogChooseSets(customPrizeFormatCodes, unselectableSets, false);
+ dialog.setOkCallback(new Runnable() {
+ @Override
+ public void run() {
+ customPrizeFormatCodes.clear();
+ customPrizeFormatCodes.addAll(dialog.getSelectedSets());
+ }
+ });
+ }
+ });
}
/* (non-Javadoc)
@@ -152,7 +147,10 @@ public enum CSubmenuQuestData implements ICDoc {
view.getLstQuests().setEditCommand(cmdQuestUpdate);
SwingUtilities.invokeLater(new Runnable() {
- @Override public void run() { view.getBtnEmbark().requestFocusInWindow(); }
+ @Override
+ public void run() {
+ view.getBtnEmbark().requestFocusInWindow();
+ }
});
}
@@ -253,7 +251,7 @@ public enum CSubmenuQuestData implements ICDoc {
// } else {
// fmtPrizes = worldFormat;
// }
- final StartingPoolPreferences userPrefs = new StartingPoolPreferences(view.randomizeColorDistribution(), view.getPreferredColor(), view.startWithCompleteSet());
+ final StartingPoolPreferences userPrefs = new StartingPoolPreferences(view.randomizeColorDistribution(), view.getPreferredColor(), view.startWithCompleteSet(), view.allowDuplicateCards());
String questName;
while (true) {
diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestData.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestData.java
index 3e3165942fa..ca73483b50e 100644
--- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestData.java
+++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestData.java
@@ -1,20 +1,5 @@
package forge.screens.home.quest;
-import java.awt.Component;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.swing.JList;
-import javax.swing.JPanel;
-import javax.swing.SwingConstants;
-import javax.swing.plaf.basic.BasicComboBoxRenderer;
-
-import net.miginfocom.swing.MigLayout;
-
-import org.apache.commons.lang3.text.WordUtils;
-
import forge.card.MagicColor;
import forge.deck.Deck;
import forge.deck.DeckGroup;
@@ -32,29 +17,32 @@ import forge.quest.StartingPoolType;
import forge.screens.home.EMenuGroup;
import forge.screens.home.IVSubmenu;
import forge.screens.home.VHomeUI;
-import forge.toolbox.FCheckBox;
-import forge.toolbox.FComboBoxWrapper;
-import forge.toolbox.FLabel;
-import forge.toolbox.FRadioButton;
-import forge.toolbox.FScrollPane;
-import forge.toolbox.FSkin;
-import forge.toolbox.JXButtonPanel;
+import forge.toolbox.*;
import forge.util.storage.IStorage;
+import net.miginfocom.swing.MigLayout;
+import org.apache.commons.lang3.text.WordUtils;
+
+import javax.swing.*;
+import javax.swing.plaf.basic.BasicComboBoxRenderer;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.HashMap;
+import java.util.Map;
/**
* Assembles Swing components of quest data submenu singleton.
*
* (V at beginning of class name denotes a view class.)
*/
+@SuppressWarnings("FieldCanBeLocal")
public enum VSubmenuQuestData implements IVSubmenu {
- /** */
SINGLETON_INSTANCE;
// Fields used with interface IVDoc
private DragCell parentCell;
private final DragTab tab = new DragTab("Quest Data");
- /** */
private final FLabel lblTitle = new FLabel.Builder()
.text("Load Quest Data").fontAlign(SwingConstants.CENTER)
.opaque(true).fontSize(16).build();
@@ -70,50 +58,52 @@ public enum VSubmenuQuestData implements IVSubmenu {
private final FScrollPane scrQuests = new FScrollPane(lstQuests, false);
private final JPanel pnlOptions = new JPanel();
- /* Fist column */
+ /* First column */
private final FRadioButton radEasy = new FRadioButton("Easy");
private final FRadioButton radMedium = new FRadioButton("Medium");
private final FRadioButton radHard = new FRadioButton("Hard");
private final FRadioButton radExpert = new FRadioButton("Expert");
private final FCheckBox boxFantasy = new FCheckBox("Fantasy Mode");
- private final FCheckBox boxCompleteSet = new FCheckBox("Start with all cards in selected sets");
private final FLabel lblStartingWorld = new FLabel.Builder().text("Starting world:").build();
- private final FComboBoxWrapper cbxStartingWorld = new FComboBoxWrapper();
-
- private final FLabel lblPreferredColor = new FLabel.Builder().text("Starting pool colors:").build();
- private final FComboBoxWrapper cbxPreferredColor = new FComboBoxWrapper();
- private final String stringBalancedDistribution = new String("balanced distribution");
- private final String stringRandomizedDistribution = new String("randomized distribution");
- private final String stringBias = new String(" bias");
+ private final FComboBoxWrapper cbxStartingWorld = new FComboBoxWrapper<>();
/* Second column */
-
private final FLabel lblStartingPool = new FLabel.Builder().text("Starting pool:").build();
- private final FComboBoxWrapper cbxStartingPool = new FComboBoxWrapper();
+ private final FComboBoxWrapper cbxStartingPool = new FComboBoxWrapper<>();
private final FLabel lblUnrestricted = new FLabel.Builder().text("All cards will be available to play.").build();
private final FLabel lblPreconDeck = new FLabel.Builder().text("Starter/Event deck:").build();
- private final FComboBoxWrapper cbxPreconDeck = new FComboBoxWrapper();
+ private final FComboBoxWrapper cbxPreconDeck = new FComboBoxWrapper<>();
private final FLabel lblFormat = new FLabel.Builder().text("Sanctioned format:").build();
- private final FComboBoxWrapper cbxFormat = new FComboBoxWrapper();
+ private final FComboBoxWrapper cbxFormat = new FComboBoxWrapper<>();
private final FLabel lblCustomDeck = new FLabel.Builder().text("Custom deck:").build();
- private final FComboBoxWrapper cbxCustomDeck = new FComboBoxWrapper();
+ private final FComboBoxWrapper cbxCustomDeck = new FComboBoxWrapper<>();
private final FLabel btnDefineCustomFormat = new FLabel.Builder().opaque(true).hoverable(true).text("Define custom format").build();
+
+ private final FCheckBox boxCompleteSet = new FCheckBox("Start with all cards in selected sets");
+ private final FCheckBox boxAllowDuplicates = new FCheckBox("Allow duplicate cards");
+
+ private final FLabel lblPreferredColor = new FLabel.Builder().text("Starting pool colors:").build();
+ private final FComboBoxWrapper cbxPreferredColor = new FComboBoxWrapper<>();
+ private final String stringBalancedDistribution = "balanced distribution";
+ private final String stringRandomizedDistribution = "randomized distribution";
+ private final String stringBias = " bias";
+
private final FLabel btnPrizeDefineCustomFormat = new FLabel.Builder().opaque(true).hoverable(true).text("Define custom format").build();
private final FLabel lblPrizedCards = new FLabel.Builder().text("Prized cards:").build();
- private final FComboBoxWrapper cbxPrizedCards = new FComboBoxWrapper();
+ private final FComboBoxWrapper cbxPrizedCards = new FComboBoxWrapper<>();
private final FLabel lblPrizeFormat = new FLabel.Builder().text("Sanctioned format:").build();
- private final FComboBoxWrapper cbxPrizeFormat = new FComboBoxWrapper();
+ private final FComboBoxWrapper cbxPrizeFormat = new FComboBoxWrapper<>();
private final FLabel lblPrizeUnrestricted = new FLabel.Builder().text("All cards will be available to win.").build();
- private final FLabel lblPrizeSameAsStarting = new FLabel.Builder().text("Only sets found in starting pool will be available.").build();
+ private final FLabel lblPrizeSameAsStarting = new FLabel.Builder().text("Only sets in starting pool will be available.").build();
private final FCheckBox cboAllowUnlocks = new FCheckBox("Allow unlock of additional editions");
@@ -145,15 +135,15 @@ public enum VSubmenuQuestData implements IVSubmenu {
cbxCustomDeck.removeAllItems();
final CardCollections decks = FModel.getDecks();
switch (newVal) {
- case SealedDeck:
- for (final DeckGroup d : decks.getSealed()) { cbxCustomDeck.addItem(d.getHumanDeck()); }
- break;
- case DraftDeck:
- for (final DeckGroup d : decks.getDraft()) { cbxCustomDeck.addItem(d.getHumanDeck()); }
- break;
- case Cube:
- for (final Deck d : decks.getCubes()) { cbxCustomDeck.addItem(d); }
- break;
+ case SealedDeck:
+ for (final DeckGroup d : decks.getSealed()) { cbxCustomDeck.addItem(d.getHumanDeck()); }
+ break;
+ case DraftDeck:
+ for (final DeckGroup d : decks.getDraft()) { cbxCustomDeck.addItem(d.getHumanDeck()); }
+ break;
+ case Cube:
+ for (final Deck d : decks.getCubes()) { cbxCustomDeck.addItem(d); }
+ break;
}
}
}
@@ -202,12 +192,13 @@ public enum VSubmenuQuestData implements IVSubmenu {
* Constructor.
*/
@SuppressWarnings("unchecked")
- private VSubmenuQuestData() {
+ VSubmenuQuestData() {
+
lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
lblTitleNew.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
final JXButtonPanel difficultyPanel = new JXButtonPanel();
- final String difficulty_constraints = "h 27px!, gapbottom 5";
+ final String difficulty_constraints = "h 25px!, gapbottom 5";
difficultyPanel.add(radEasy, difficulty_constraints);
difficultyPanel.add(radMedium, difficulty_constraints);
difficultyPanel.add(radHard, difficulty_constraints);
@@ -215,6 +206,7 @@ public enum VSubmenuQuestData implements IVSubmenu {
radEasy.setSelected(true);
boxCompleteSet.setToolTipText("You will start the quest with 4 of each card in the sets you have selected.");
+ boxAllowDuplicates.setToolTipText("When your starting pool is generated duplicates of cards may be included.");
cbxStartingPool.addItem(StartingPoolType.Complete);
cbxStartingPool.addItem(StartingPoolType.Rotating);
@@ -261,7 +253,7 @@ public enum VSubmenuQuestData implements IVSubmenu {
cboAllowUnlocks.setSelected(true);
- final Map preconDescriptions = new HashMap();
+ final Map preconDescriptions = new HashMap<>();
final IStorage preconDecks = QuestController.getPrecons();
for (final PreconDeck preconDeck : preconDecks) {
@@ -297,6 +289,7 @@ public enum VSubmenuQuestData implements IVSubmenu {
boxFantasy.setSelected(true);
boxFantasy.setEnabled(true);
boxCompleteSet.setEnabled(true);
+ boxAllowDuplicates.setEnabled(true);
cbxPreferredColor.setEnabled(true);
@@ -305,60 +298,59 @@ public enum VSubmenuQuestData implements IVSubmenu {
final JPanel pnlDifficultyMode = new JPanel(new MigLayout("insets 0, gap 1%, flowy"));
pnlDifficultyMode.add(difficultyPanel, "gapright 4%");
- pnlDifficultyMode.add(boxFantasy, difficulty_constraints + ", gapright 4%");
+ pnlDifficultyMode.add(boxFantasy, "h 27px!, gapbottom 15, gapright 4%");
+ pnlDifficultyMode.add(lblStartingWorld, "h 27px!, hidemode 3");
+ cbxStartingWorld.addTo(pnlDifficultyMode, "h 27px!, w 40%, pushx, hidemode 3");
pnlDifficultyMode.setOpaque(false);
pnlOptions.add(pnlDifficultyMode, "w 40%");
final JPanel pnlRestrictions = new JPanel();
- final String constraints = "h 27px!, ";
- final String lblWidth = "w 40%, ";
+ final String constraints = "h 25px!, ";
final String hidemode = "hidemode 3, ";
- final String lblWidthStart = lblWidth + hidemode;
- final String cboWidth = "pushx, ";
+ final String cboWidth = "w 240px!, pushx, ";
final String cboWidthStart = cboWidth + hidemode;
+ final String btnStartingCustomFormatWidth = "w " + (4 + cbxStartingPool.getAutoSizeWidth()) + "px!, ";
- pnlRestrictions.setLayout(new MigLayout("insets 0, gap 0, wrap 2", "[120, al right][240, fill]", "[|]12[|]6[]"));
+ pnlRestrictions.setLayout(new MigLayout("insets 0, gap 10", "[right][left]"));
- pnlRestrictions.add(lblStartingPool, constraints + lblWidthStart);
- cbxStartingPool.addTo(pnlRestrictions, constraints + cboWidthStart);
+ pnlRestrictions.add(lblStartingPool, "h 15px!, cell 0 0");
+ cbxStartingPool.addTo(pnlRestrictions, constraints + cboWidthStart + " cell 1 0");
- /* out of these 3 groups only one will be visible */
- pnlRestrictions.add(lblUnrestricted, constraints + hidemode + "spanx 2");
+ /* --vvv-- out of these 3 groups only one will be visible --vvv-- */
+ pnlRestrictions.add(lblUnrestricted, constraints + hidemode + " cell 1 1, ");
- pnlRestrictions.add(lblPreconDeck, constraints + lblWidthStart);
- cbxPreconDeck.addTo(pnlRestrictions, constraints + cboWidthStart);
+ pnlRestrictions.add(lblPreconDeck, constraints + hidemode + " cell 0 1");
+ cbxPreconDeck.addTo(pnlRestrictions, constraints + cboWidthStart + " cell 1 1");
- pnlRestrictions.add(lblCustomDeck, constraints + lblWidthStart);
- cbxCustomDeck.addTo(pnlRestrictions, constraints + cboWidthStart); // , skip 1
+ pnlRestrictions.add(lblCustomDeck, constraints + hidemode + " cell 0 1");
+ cbxCustomDeck.addTo(pnlRestrictions, constraints + cboWidthStart + " cell 1 1");
+ /* --^^^-- out of these 3 groups only one will be visible --^^^-- */
- pnlRestrictions.add(lblFormat, constraints + lblWidthStart);
- cbxFormat.addTo(pnlRestrictions, constraints + cboWidthStart); // , skip 1
+ pnlRestrictions.add(lblFormat, constraints + hidemode + " cell 0 1");
+ cbxFormat.addTo(pnlRestrictions, constraints + cboWidthStart + " cell 1 1");
- pnlRestrictions.add(btnDefineCustomFormat, constraints + hidemode + "spanx 2, w 240px");
+ pnlRestrictions.add(btnDefineCustomFormat, btnStartingCustomFormatWidth + constraints + hidemode + " cell 1 1");
+
+ pnlRestrictions.add(boxAllowDuplicates, "h 15px!, cell 1 2");
+ pnlRestrictions.add(boxCompleteSet, "h 15px!, cell 1 3");
+
+ pnlRestrictions.add(lblPreferredColor, constraints + hidemode + "cell 0 4");
+ cbxPreferredColor.addTo(pnlRestrictions, constraints + cboWidthStart + "cell 1 4");
// Prized cards options
- pnlRestrictions.add(lblPrizedCards, constraints + lblWidth);
- cbxPrizedCards.addTo(pnlRestrictions, constraints + cboWidth);
+ pnlRestrictions.add(lblPrizedCards, constraints + " cell 0 5");
+ cbxPrizedCards.addTo(pnlRestrictions, constraints + cboWidth + " cell 1 5");
- pnlRestrictions.add(lblPrizeFormat, constraints + lblWidthStart);
- cbxPrizeFormat.addTo(pnlRestrictions, constraints + cboWidthStart); // , skip 1
- pnlRestrictions.add(btnPrizeDefineCustomFormat, constraints + hidemode + "spanx 2, w 240px");
- pnlRestrictions.add(lblPrizeSameAsStarting, constraints + hidemode + "spanx 2");
- pnlRestrictions.add(lblPrizeUnrestricted, constraints + hidemode + "spanx 2");
+ pnlRestrictions.add(lblPrizeFormat, constraints + hidemode + "cell 0 6");
+ cbxPrizeFormat.addTo(pnlRestrictions, constraints + cboWidthStart + "cell 1 6"); // , skip 1
+ pnlRestrictions.add(btnPrizeDefineCustomFormat, constraints + hidemode + "cell 1 6");
+ pnlRestrictions.add(lblPrizeSameAsStarting, constraints + hidemode + "cell 1 6");
+ pnlRestrictions.add(lblPrizeUnrestricted, constraints + hidemode + "cell 1 6");
- pnlRestrictions.add(cboAllowUnlocks, constraints + "spanx 2, ax right");
- pnlRestrictions.add(boxCompleteSet, constraints + "spanx 2, ax right");
+ pnlRestrictions.add(cboAllowUnlocks, constraints + "cell 1 7");
-
- pnlRestrictions.add(lblPreferredColor, constraints + lblWidthStart);
- cbxPreferredColor.addTo(pnlRestrictions, constraints + cboWidthStart + ", wrap");
-
- pnlRestrictions.add(lblStartingWorld, constraints + lblWidthStart);
- cbxStartingWorld.addTo(pnlRestrictions, constraints + cboWidthStart);
-
- // cboAllowUnlocks.setOpaque(false);
pnlRestrictions.setOpaque(false);
pnlOptions.add(pnlRestrictions, "pushx, ay top");
@@ -477,12 +469,12 @@ public enum VSubmenuQuestData implements IVSubmenu {
}
public String getSelectedPrecon() {
- return cbxPreconDeck.getSelectedItem().toString();
+ return cbxPreconDeck.getSelectedItem();
}
public Deck getSelectedDeck() {
final Object sel = cbxCustomDeck.getSelectedItem();
- return sel instanceof Deck ? (Deck) sel : null;
+ return sel != null ? (Deck) sel : null;
}
public boolean isUnlockSetsAllowed() {
@@ -510,6 +502,10 @@ public enum VSubmenuQuestData implements IVSubmenu {
return boxCompleteSet.isSelected();
}
+ public boolean allowDuplicateCards() {
+ return boxAllowDuplicates.isSelected();
+ }
+
public boolean randomizeColorDistribution() {
return stringRandomizedDistribution.equals(cbxPreferredColor.getSelectedItem());
}
diff --git a/forge-gui-mobile/src/forge/screens/quest/NewQuestScreen.java b/forge-gui-mobile/src/forge/screens/quest/NewQuestScreen.java
index 565f7902bd6..47b27d26f93 100644
--- a/forge-gui-mobile/src/forge/screens/quest/NewQuestScreen.java
+++ b/forge-gui-mobile/src/forge/screens/quest/NewQuestScreen.java
@@ -1,17 +1,6 @@
package forge.screens.quest;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-import org.apache.commons.lang3.text.WordUtils;
-
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
-
import forge.FThreads;
import forge.assets.FSkinFont;
import forge.assets.FSkinImage;
@@ -25,38 +14,31 @@ import forge.item.PreconDeck;
import forge.model.CardCollections;
import forge.model.FModel;
import forge.properties.ForgeConstants;
-import forge.quest.QuestController;
-import forge.quest.QuestMode;
-import forge.quest.QuestUtil;
-import forge.quest.QuestWorld;
-import forge.quest.StartingPoolPreferences;
-import forge.quest.StartingPoolType;
+import forge.quest.*;
import forge.quest.data.GameFormatQuest;
import forge.quest.data.QuestPreferences.QPref;
import forge.screens.FScreen;
import forge.screens.LoadingOverlay;
import forge.screens.home.NewGameMenu;
import forge.screens.quest.QuestMenu.LaunchReason;
-import forge.toolbox.FCheckBox;
-import forge.toolbox.FComboBox;
-import forge.toolbox.FDisplayObject;
-import forge.toolbox.FEvent;
+import forge.toolbox.*;
import forge.toolbox.FEvent.FEventHandler;
-import forge.toolbox.FLabel;
-import forge.toolbox.FOptionPane;
-import forge.toolbox.FScrollPane;
import forge.util.FileUtil;
import forge.util.ThreadUtil;
import forge.util.Utils;
import forge.util.gui.SOptionPane;
import forge.util.storage.IStorage;
+import org.apache.commons.lang3.text.WordUtils;
+
+import java.util.*;
+import java.util.Map.Entry;
public class NewQuestScreen extends FScreen {
private static final float EMBARK_BTN_HEIGHT = 2 * Utils.AVG_FINGER_HEIGHT;
private static final float PADDING = FOptionPane.PADDING;
- private final List customFormatCodes = new ArrayList();
- private final List customPrizeFormatCodes = new ArrayList();
+ private final List customFormatCodes = new ArrayList<>();
+ private final List customPrizeFormatCodes = new ArrayList<>();
private final FScrollPane scroller = add(new FScrollPane() {
@Override
@@ -99,15 +81,15 @@ public class NewQuestScreen extends FScreen {
@SuppressWarnings("unused")
private final FLabel lblDifficulty = scroller.add(new FLabel.Builder().text("Difficulty:").build());
- private final FComboBox cbxDifficulty = scroller.add(new FComboBox(new String[]{ "Easy", "Medium", "Hard", "Expert" }));
+ private final FComboBox cbxDifficulty = scroller.add(new FComboBox<>(new String[]{ "Easy", "Medium", "Hard", "Expert" }));
@SuppressWarnings("unused")
private final FLabel lblPreferredColor = scroller.add(new FLabel.Builder().text("Starting pool colors:").build());
private final FComboBox cbxPreferredColor = scroller.add(new FComboBox());
- private final String stringBalancedDistribution = new String("balanced distribution");
- private final String stringRandomizedDistribution = new String("randomized distribution");
- private final String stringBias = new String(" bias");
-
+ private final String stringBalancedDistribution = "balanced distribution";
+ private final String stringRandomizedDistribution = "randomized distribution";
+ private final String stringBias = " bias";
+
@SuppressWarnings("unused")
private final FLabel lblStartingPool = scroller.add(new FLabel.Builder().text("Starting pool:").build());
private final FComboBox cbxStartingPool = scroller.add(new FComboBox());
@@ -127,7 +109,7 @@ public class NewQuestScreen extends FScreen {
@SuppressWarnings("unused")
private final FLabel lblPrizedCards = scroller.add(new FLabel.Builder().text("Prized cards:").build());
- private final FComboBox cbxPrizedCards = scroller.add(new FComboBox());
+ private final FComboBox cbxPrizedCards = scroller.add(new FComboBox<>());
private final FLabel lblPrizeFormat = scroller.add(new FLabel.Builder().text("Sanctioned format:").build());
private final FComboBox cbxPrizeFormat = scroller.add(new FComboBox());
@@ -138,6 +120,7 @@ public class NewQuestScreen extends FScreen {
private final FCheckBox cbAllowUnlocks = scroller.add(new FCheckBox("Allow unlock of additional editions"));
private final FCheckBox cbCompleteSet = scroller.add(new FCheckBox("Start with all cards in selected sets"));
+ private final FCheckBox cbDuplicateCards = scroller.add(new FCheckBox("Allow duplicates in starting pool"));
private final FCheckBox cbFantasy = scroller.add(new FCheckBox("Fantasy Mode"));
private final FLabel btnEmbark = add(new FLabel.ButtonBuilder()
@@ -218,7 +201,7 @@ public class NewQuestScreen extends FScreen {
cbAllowUnlocks.setSelected(true);
- final Map preconDescriptions = new HashMap();
+ final Map preconDescriptions = new HashMap<>();
IStorage preconDecks = QuestController.getPrecons();
for (PreconDeck preconDeck : preconDecks) {
@@ -237,7 +220,7 @@ public class NewQuestScreen extends FScreen {
btnPrizeDefineCustomFormat.setEnabled(false);
// disable the very powerful sets -- they can be unlocked later for a high price
- final List unselectableSets = new ArrayList();
+ final List unselectableSets = new ArrayList<>();
unselectableSets.add("LEA");
unselectableSets.add("LEB");
unselectableSets.add("MBP");
@@ -359,12 +342,12 @@ public class NewQuestScreen extends FScreen {
}
public String getSelectedPrecon() {
- return cbxPreconDeck.getSelectedItem().toString();
+ return cbxPreconDeck.getSelectedItem();
}
public Deck getSelectedDeck() {
Object sel = cbxCustomDeck.getSelectedItem();
- return sel instanceof Deck ? (Deck) sel : null;
+ return sel != null ? (Deck) sel : null;
}
public boolean isUnlockSetsAllowed() {
@@ -375,8 +358,12 @@ public class NewQuestScreen extends FScreen {
return cbCompleteSet.isSelected();
}
+ public boolean allowDuplicateCards() {
+ return cbDuplicateCards.isSelected();
+ }
+
public StartingPoolType getStartingPoolType() {
- return (StartingPoolType) cbxStartingPool.getSelectedItem();
+ return cbxStartingPool.getSelectedItem();
}
public StartingPoolType getPrizedPoolType() {
@@ -405,11 +392,11 @@ public class NewQuestScreen extends FScreen {
}
public GameFormat getRotatingFormat() {
- return (GameFormat) cbxFormat.getSelectedItem();
+ return cbxFormat.getSelectedItem();
}
public GameFormat getPrizedRotatingFormat() {
- return (GameFormat) cbxPrizeFormat.getSelectedItem();
+ return cbxPrizeFormat.getSelectedItem();
}
@Override
@@ -468,7 +455,7 @@ public class NewQuestScreen extends FScreen {
fmtStartPool = worldFormat;
}
- GameFormat fmtPrizes = null;
+ GameFormat fmtPrizes;
// The starting QuestWorld format should NOT affect what you get if you travel to a world that doesn't have one...
// if (worldFormat == null) {
@@ -476,7 +463,7 @@ public class NewQuestScreen extends FScreen {
if (null == prizedPoolType) {
fmtPrizes = fmtStartPool;
if (null == fmtPrizes && dckStartPool != null) { // build it form deck
- Set sets = new HashSet();
+ Set sets = new HashSet<>();
for (Entry c : dckStartPool.getMain()) {
sets.add(c.getKey().getEdition());
}
@@ -500,7 +487,7 @@ public class NewQuestScreen extends FScreen {
return;
}
}
- fmtPrizes = customPrizeFormatCodes.isEmpty() ? null : new GameFormat("Custom Prizes", customPrizeFormatCodes, null); // chosen sets and no banend cards
+ fmtPrizes = customPrizeFormatCodes.isEmpty() ? null : new GameFormat("Custom Prizes", customPrizeFormatCodes, null); // chosen sets and no banned cards
break;
case Rotating:
fmtPrizes = getPrizedRotatingFormat();
@@ -539,7 +526,7 @@ public class NewQuestScreen extends FScreen {
@Override
public void run() {
final QuestMode mode = isFantasy() ? QuestMode.Fantasy : QuestMode.Classic;
- final StartingPoolPreferences userPrefs = new StartingPoolPreferences(randomizeColorDistribution(), getPreferredColor(), startWithCompleteSet());
+ final StartingPoolPreferences userPrefs = new StartingPoolPreferences(randomizeColorDistribution(), getPreferredColor(), startWithCompleteSet(), allowDuplicateCards());
QuestController qc = FModel.getQuest();
qc.newGame(questName, getSelectedDifficulty(), mode, fmtPrizes, isUnlockSetsAllowed(), dckStartPool, fmtStartPool, getStartingWorldName(), userPrefs);
qc.save();
diff --git a/forge-gui/src/main/java/forge/quest/BoosterUtils.java b/forge-gui/src/main/java/forge/quest/BoosterUtils.java
index 793bd73d6b0..fdf4134c695 100644
--- a/forge-gui/src/main/java/forge/quest/BoosterUtils.java
+++ b/forge-gui/src/main/java/forge/quest/BoosterUtils.java
@@ -6,12 +6,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
@@ -39,12 +39,11 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
-// The BoosterPack generates cards for the Card Pool in Quest Mode
/**
*
- * QuestBoosterPack class.
+ * QuestBoosterPack class. Generates cards for the Card Pool in Quest Mode
*
- *
+ *
* @author Forge
* @version $Id$
*/
@@ -52,7 +51,7 @@ public final class BoosterUtils {
/**
* Gets the quest starter deck.
- *
+ *
* @param filter
* the filter
* @param numCommon
@@ -68,13 +67,13 @@ public final class BoosterUtils {
public static List getQuestStarterDeck(final Predicate filter, final int numCommon,
final int numUncommon, final int numRare, final StartingPoolPreferences userPrefs) {
- final ArrayList cards = new ArrayList();
+ final ArrayList cards = new ArrayList<>();
// Each color should have around the same amount of monocolored cards
// There should be 3 Colorless cards for every 4 cards in a single color
// There should be 1 Multicolor card for every 4 cards in a single color
- final List> colorFilters = new ArrayList>();
+ final List> colorFilters = new ArrayList<>();
final boolean preferred = (userPrefs != null && userPrefs.getPreferredColor() != MagicColor.ALL_COLORS);
final boolean randomized = userPrefs != null && userPrefs.useRandomPool();
final int colorBias = (preferred && !randomized) ? FModel.getQuestPreferences().getPrefInt(QPref.STARTING_POOL_COLOR_BIAS) : 0;
@@ -108,23 +107,24 @@ public final class BoosterUtils {
// This will save CPU time when sets are limited
final List cardpool = Lists.newArrayList(Iterables.filter(FModel.getMagicDb().getCommonCards().getAllCards(), filter));
- if (userPrefs.grantCompleteSet()) {
- for (PaperCard card : cardpool) {
- cards.add(card);
- cards.add(card);
- cards.add(card);
- cards.add(card);
- }
- return cards;
- }
-
+ assert userPrefs != null;
+ if (userPrefs.grantCompleteSet()) {
+ for (PaperCard card : cardpool) {
+ cards.add(card);
+ cards.add(card);
+ cards.add(card);
+ cards.add(card);
+ }
+ return cards;
+ }
+
final Predicate pCommon = IPaperCard.Predicates.Presets.IS_COMMON;
- cards.addAll(BoosterUtils.generateDefinetlyColouredCards(cardpool, pCommon, biasAdjustedCommons, colorFilters));
+ cards.addAll(BoosterUtils.generateCards(cardpool, pCommon, biasAdjustedCommons, colorFilters, userPrefs.allowDuplicates()));
final Predicate pUncommon = IPaperCard.Predicates.Presets.IS_UNCOMMON;
- cards.addAll(BoosterUtils.generateDefinetlyColouredCards(cardpool, pUncommon, biasAdjustedUncommons, colorFilters));
+ cards.addAll(BoosterUtils.generateCards(cardpool, pUncommon, biasAdjustedUncommons, colorFilters, userPrefs.allowDuplicates()));
- int nRares = biasAdjustedRares, nMythics = 0;
+ int nRares = biasAdjustedRares, nMythics = 0;
final Predicate filterMythics = IPaperCard.Predicates.Presets.IS_MYTHIC_RARE;
final boolean haveMythics = Iterables.any(cardpool, filterMythics);
for (int iSlot = 0; haveMythics && (iSlot < numRare); iSlot++) {
@@ -136,16 +136,16 @@ public final class BoosterUtils {
}
final Predicate pRare = IPaperCard.Predicates.Presets.IS_RARE;
- cards.addAll(BoosterUtils.generateDefinetlyColouredCards(cardpool, pRare, nRares, colorFilters));
+ cards.addAll(BoosterUtils.generateCards(cardpool, pRare, nRares, colorFilters, false));
if (nMythics > 0) {
- cards.addAll(BoosterUtils.generateDefinetlyColouredCards(cardpool, filterMythics, nMythics, colorFilters));
+ cards.addAll(BoosterUtils.generateCards(cardpool, filterMythics, nMythics, colorFilters, userPrefs.allowDuplicates()));
}
return cards;
}
/**
* Create the list of card names at random from the given pool.
- *
+ *
* @param source
* an Iterable
* @param filter
@@ -154,12 +154,16 @@ public final class BoosterUtils {
* an int
* @param allowedColors
* a List>
+ * @param allowDuplicates
+ * If true, multiple copies of the same card will be allowed to be generated.
* @return a list of card names
*/
- private static ArrayList generateDefinetlyColouredCards(final Iterable source,
- final Predicate filter, final int cntNeeded, final List> allowedColors) {
+ private static ArrayList generateCards(
+ final Iterable source, final Predicate filter, final int cntNeeded,
+ final List> allowedColors, final boolean allowDuplicates) {
+
// If color is null, use colorOrder progression to grab cards
- final ArrayList result = new ArrayList();
+ final ArrayList result = new ArrayList<>();
final int size = allowedColors == null ? 0 : allowedColors.size();
if (allowedColors != null) {
@@ -169,8 +173,7 @@ public final class BoosterUtils {
int cntMade = 0, iAttempt = 0;
// This will prevent endless loop @ wh
- int allowedMisses = (2 + size + 2) * cntNeeded; // lol, 2+2 is not magic
- // constant!
+ int allowedMisses = (size + 4) * cntNeeded; // lol, 2+2 is not magic constant!
while ((cntMade < cntNeeded) && (allowedMisses > 0)) {
PaperCard card = null;
@@ -188,7 +191,7 @@ public final class BoosterUtils {
card = Aggregates.random(Iterables.filter(source, filter));
}
- if ((card != null) && !result.contains(card)) {
+ if ((card != null) && (allowDuplicates || !result.contains(card))) {
result.add(card);
cntMade++;
} else {
@@ -206,7 +209,7 @@ public final class BoosterUtils {
* @param input
* String, the limitation as text.
* @return Predicate the text parsed into a CardRules predicate.
- *
+ *
*/
public static Predicate parseRulesLimitation(final String input) {
if (null == input || "random".equalsIgnoreCase(input)) {
@@ -240,18 +243,19 @@ public final class BoosterUtils {
private static List parseReward(final String s) {
String[] temp = s.split(" ");
- List rewards = new ArrayList();
+ List rewards = new ArrayList<>();
// last word starts with 'rare' ignore case
if (temp.length > 1 && temp[temp.length - 1].regionMatches(true, 0, "rare", 0, 4)) {
// Type 1: 'n [color] rares'
final int qty = Integer.parseInt(temp[0]);
- List> preds = new ArrayList>();
+ List> preds = new ArrayList<>();
preds.add(IPaperCard.Predicates.Presets.IS_RARE_OR_MYTHIC); // Determine rarity
if (temp.length > 2) {
Predicate cr = parseRulesLimitation(temp[1]);
+ //noinspection RedundantCast
if (Predicates.alwaysTrue() != (Object) cr) { // guava has a single instance for always-const predicates
preds.add(Predicates.compose(cr, PaperCard.FN_GET_RULES));
}
@@ -295,7 +299,7 @@ public final class BoosterUtils {
* generateCardRewardList.
*
* Takes a reward list string, parses, and returns list of cards rewarded.
- *
+ *
* @param s
* Properties string of reward (97 multicolor rares)
* @return List
@@ -307,7 +311,7 @@ public final class BoosterUtils {
}
final String[] items = s.split(";");
- final List rewards = new ArrayList();
+ final List rewards = new ArrayList<>();
for (final String item : items) {
diff --git a/forge-gui/src/main/java/forge/quest/QuestSpellShop.java b/forge-gui/src/main/java/forge/quest/QuestSpellShop.java
index 84fcbc437a8..2007e518c84 100644
--- a/forge-gui/src/main/java/forge/quest/QuestSpellShop.java
+++ b/forge-gui/src/main/java/forge/quest/QuestSpellShop.java
@@ -1,29 +1,11 @@
package forge.quest;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.commons.lang3.tuple.Pair;
-
import com.google.common.base.Function;
-
import forge.GuiBase;
import forge.deck.CardPool;
import forge.deck.Deck;
import forge.deck.DeckSection;
-import forge.item.BoosterBox;
-import forge.item.BoosterPack;
-import forge.item.BoxedProduct;
-import forge.item.FatPack;
-import forge.item.IPaperCard;
-import forge.item.InventoryItem;
-import forge.item.PaperCard;
-import forge.item.PreconDeck;
-import forge.item.SealedProduct;
-import forge.item.TournamentPack;
+import forge.item.*;
import forge.itemmanager.IItemManager;
import forge.itemmanager.SItemManagerUtil;
import forge.model.FModel;
@@ -31,6 +13,13 @@ import forge.properties.ForgePreferences.FPref;
import forge.quest.io.ReadPriceList;
import forge.util.ItemPool;
import forge.util.gui.SOptionPane;
+import org.apache.commons.lang3.tuple.Pair;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
public class QuestSpellShop {
private static Map mapPrices;
@@ -211,9 +200,9 @@ public class QuestSpellShop {
final List newCards = booster.getCards();
itemsToAdd.addAllFlat(newCards);
-
+
if (booster instanceof BoxedProduct && FModel.getPreferences().getPrefBoolean(FPref.UI_OPEN_PACKS_INDIV)) {
-
+
int totalPacks = ((BoxedProduct) booster).boosterPacksRemaining();
boolean skipTheRest = false;
final List remainingCards = new ArrayList<>();
@@ -233,7 +222,7 @@ public class QuestSpellShop {
if (remainingCards.size() > 0) {
GuiBase.getInterface().showCardList(booster.getName(), "You have found the following cards inside:", remainingCards);
}
-
+
}
else {
GuiBase.getInterface().showCardList(booster.getName(), "You have found the following cards inside:", newCards);
@@ -279,7 +268,7 @@ public class QuestSpellShop {
String suffix = SItemManagerUtil.getItemDisplayString(itemFlatList, 1, true);
String displayList = SItemManagerUtil.buildDisplayList(itemsToSell);
String title = "Sell " + suffix;
-
+
if (!SOptionPane.showConfirmDialog("Sell the following " + suffix.toLowerCase() + " for " + totalReceived +
" credit" + (totalReceived != 1 ? "s" : "") + "?\n" + displayList, title, "Sell", "Cancel")) {
return;
diff --git a/forge-gui/src/main/java/forge/quest/StartingPoolPreferences.java b/forge-gui/src/main/java/forge/quest/StartingPoolPreferences.java
index b37101251d8..db67207e968 100644
--- a/forge-gui/src/main/java/forge/quest/StartingPoolPreferences.java
+++ b/forge-gui/src/main/java/forge/quest/StartingPoolPreferences.java
@@ -6,18 +6,18 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package forge.quest;
-/**
+/**
* This class is used to store the Quest starting pool preferences.
* (It could be expanded to store other Quest starting preferences as well,
* in order to reduce the number of parameters that need to be passed to
@@ -28,20 +28,22 @@ public final class StartingPoolPreferences {
private final boolean randomPool;
private final byte preferredColor;
- private final boolean completeSet;
+ private final boolean completeSet;
+ private final boolean allowDuplicates;
/**
- * The constructor.
- * @param random
- * true = use completely random pool without filter restrictions
- * (Note that this does NOT bypass card rarity restrictions!)
- * @param preference
- * preferred color/COLORLESS (ALL_COLORS = no preference)
+ * Creates a new StartingPoolPreferences instance.
+ * @param random If true, a completely random pool will be generated without filter restrictions. This does not
+ * bypass rarity restrictions.
+ * @param preference Preferred color or colorless. All colors == no preference. See {@link forge.card.MagicColor}.
+ * @param completeSet If true, four of each card in the starting pool will be generated.
+ * @param allowDuplicates If true, multiples of each card will be allowed to be generated.
*/
- public StartingPoolPreferences(final boolean random, final byte preference, final boolean completeSet) {
+ public StartingPoolPreferences(final boolean random, final byte preference, final boolean completeSet, final boolean allowDuplicates) {
randomPool = random;
preferredColor = preference;
- this.completeSet = completeSet;
+ this.completeSet = completeSet;
+ this.allowDuplicates = allowDuplicates;
}
/**
@@ -60,9 +62,13 @@ public final class StartingPoolPreferences {
public byte getPreferredColor() {
return preferredColor;
}
-
- public boolean grantCompleteSet() {
- return completeSet;
- }
-
+
+ public boolean grantCompleteSet() {
+ return completeSet;
+ }
+
+ public boolean allowDuplicates() {
+ return allowDuplicates;
+ }
+
}