From 94244f837e2c9a5ffa3840f6bae6ad8e45f0b74d Mon Sep 17 00:00:00 2001 From: RumbleBBU Date: Thu, 1 Nov 2012 09:36:52 +0000 Subject: [PATCH] Set unlocking is no longer a special reward for winning matches, instead it is an option button like spell store. More expensive than before, not random, and initially fewer sets to choose from. --- .gitattributes | 1 + .../gui/home/quest/CSubmenuChallenges.java | 4 + .../forge/gui/home/quest/CSubmenuDuels.java | 4 + .../forge/gui/home/quest/IVQuestStats.java | 3 + .../gui/home/quest/SSubmenuQuestUtil.java | 21 +- .../gui/home/quest/VSubmenuChallenges.java | 7 + .../forge/gui/home/quest/VSubmenuDuels.java | 7 + .../java/forge/gui/match/QuestWinLose.java | 247 ----------------- .../java/forge/quest/QuestController.java | 24 ++ .../java/forge/quest/QuestUtilUnlockSets.java | 254 ++++++++++++++++++ 10 files changed, 323 insertions(+), 249 deletions(-) create mode 100644 src/main/java/forge/quest/QuestUtilUnlockSets.java diff --git a/.gitattributes b/.gitattributes index 60e882cc7a0..052ca08d0d8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13074,6 +13074,7 @@ src/main/java/forge/quest/QuestMode.java -text src/main/java/forge/quest/QuestStartPool.java -text src/main/java/forge/quest/QuestUtil.java svneol=native#text/plain src/main/java/forge/quest/QuestUtilCards.java -text +src/main/java/forge/quest/QuestUtilUnlockSets.java -text src/main/java/forge/quest/SellRules.java -text src/main/java/forge/quest/bazaar/IQuestBazaarItem.java svneol=native#text/plain src/main/java/forge/quest/bazaar/QuestBazaarManager.java svneol=native#text/plain diff --git a/src/main/java/forge/gui/home/quest/CSubmenuChallenges.java b/src/main/java/forge/gui/home/quest/CSubmenuChallenges.java index e54beb38869..0c23a053da4 100644 --- a/src/main/java/forge/gui/home/quest/CSubmenuChallenges.java +++ b/src/main/java/forge/gui/home/quest/CSubmenuChallenges.java @@ -46,6 +46,10 @@ public enum CSubmenuChallenges implements ICDoc { new Command() { @Override public void execute() { SSubmenuQuestUtil.showBazaar(); } }); + view.getBtnUnlock().setCommand( + new Command() { @Override + public void execute() { SSubmenuQuestUtil.showSetUnlock(); } }); + view.getBtnStart().addActionListener( new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { SSubmenuQuestUtil.startGame(); } }); diff --git a/src/main/java/forge/gui/home/quest/CSubmenuDuels.java b/src/main/java/forge/gui/home/quest/CSubmenuDuels.java index f1980da8a23..a108bcb7e56 100644 --- a/src/main/java/forge/gui/home/quest/CSubmenuDuels.java +++ b/src/main/java/forge/gui/home/quest/CSubmenuDuels.java @@ -41,6 +41,10 @@ public enum CSubmenuDuels implements ICDoc { new Command() { @Override public void execute() { SSubmenuQuestUtil.showBazaar(); } }); + view.getBtnUnlock().setCommand( + new Command() { @Override + public void execute() { SSubmenuQuestUtil.showSetUnlock(); } }); + view.getBtnStart().addActionListener( new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { SSubmenuQuestUtil.startGame(); } }); diff --git a/src/main/java/forge/gui/home/quest/IVQuestStats.java b/src/main/java/forge/gui/home/quest/IVQuestStats.java index f8fc5f8cd50..311333c8663 100644 --- a/src/main/java/forge/gui/home/quest/IVQuestStats.java +++ b/src/main/java/forge/gui/home/quest/IVQuestStats.java @@ -15,6 +15,9 @@ public interface IVQuestStats { /** @return {@link forge.gui.toolbox.ExperimentalLabel} */ ExperimentalLabel getBtnSpellShop(); + /** @return {@link forge.gui.toolbox.ExperimentalLabel} */ + ExperimentalLabel getBtnUnlock(); + /** @return {@link javax.swing.JLabel} */ JLabel getLblCredits(); diff --git a/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java b/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java index 4a799108d38..7f7e83f34d7 100644 --- a/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java +++ b/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java @@ -12,6 +12,7 @@ import com.google.common.base.Supplier; import forge.Card; import forge.Singletons; +import forge.card.CardEdition; import forge.control.FControl; import forge.deck.Deck; import forge.game.GameType; @@ -157,6 +158,13 @@ public class SSubmenuQuestUtil { view0.getLblWins().setText("Wins: " + qA.getWin()); view0.getLblLosses().setText("Losses: " + qA.getLost()); + // Show or hide the set unlocking button + if (qCtrl.getFormatNumberUnlockable() > 0) { + view0.getBtnUnlock().setVisible(true); + } else { + view0.getBtnUnlock().setVisible(false); + } + // Challenge in wins final int num = SSubmenuQuestUtil.nextChallengeInWins(); final String str; @@ -235,6 +243,15 @@ public class SSubmenuQuestUtil { Singletons.getView().getFrame().validate(); } + /** */ + public static void showSetUnlock() { + final QuestController qData = Singletons.getModel().getQuest(); + CardEdition toUnlock = QuestUtil.unlockSet(qData, false, null); + if (toUnlock != null) { + + } + } + /** */ public static void startGame() { final QuestController qData = Singletons.getModel().getQuest(); @@ -286,7 +303,7 @@ public class SSubmenuQuestUtil { humanStart.setStartingLife(qData.getAssets().getLife(qData.getMode()) + extraLifeHuman); aiStart.setStartingLife(lifeAI); - + humanStart.setCardsOnTable(new Supplier>() { @Override public Iterable get() { return QuestUtil.getHumanStartingCards(qData, event); } }); aiStart.setCardsOnTable(new Supplier>() { @@ -299,7 +316,7 @@ public class SSubmenuQuestUtil { LobbyPlayer aiPlayer = Singletons.getControl().getLobby().findLocalPlayer(PlayerType.COMPUTER, event.getName()); aiPlayer.setPicture(event.getIconFilename()); msh.addPlayer( aiPlayer, aiStart ); - + Singletons.getModel().getMatch().initMatch(GameType.Quest, msh.getPlayerMap()); Singletons.getModel().getMatch().startRound(); return null; diff --git a/src/main/java/forge/gui/home/quest/VSubmenuChallenges.java b/src/main/java/forge/gui/home/quest/VSubmenuChallenges.java index 32d99d8f685..0f68526c983 100644 --- a/src/main/java/forge/gui/home/quest/VSubmenuChallenges.java +++ b/src/main/java/forge/gui/home/quest/VSubmenuChallenges.java @@ -83,6 +83,7 @@ public enum VSubmenuChallenges implements IVSubmenu, IVQuest .text("Next challenge in wins hasn't been set yet.") .fontSize(12).build(); + private final ExperimentalLabel btnUnlock = new ExperimentalLabel("Unlock Sets"); private final ExperimentalLabel btnBazaar = new ExperimentalLabel("Bazaar"); private final ExperimentalLabel btnSpellShop = new ExperimentalLabel("Spell Shop"); @@ -96,6 +97,7 @@ public enum VSubmenuChallenges implements IVSubmenu, IVQuest final String constraints = "h 30px!, gap 0 0 0 5px"; pnlStats.setLayout(new MigLayout("insets 0, gap 0, wrap, hidemode 3")); + pnlStats.add(btnUnlock, "w 150px!, h 30px!, gap 0 0 0 10px"); pnlStats.add(btnSpellShop, "w 150px!, h 30px!, gap 0 0 0 10px"); pnlStats.add(btnBazaar, "w 150px!, h 30px!, gap 0 0 0 10px"); pnlStats.add(lblWins, constraints); @@ -213,6 +215,11 @@ public enum VSubmenuChallenges implements IVSubmenu, IVQuest return btnBazaar; } + @Override + public ExperimentalLabel getBtnUnlock() { + return btnUnlock; + } + @Override public ExperimentalLabel getBtnSpellShop() { return btnSpellShop; diff --git a/src/main/java/forge/gui/home/quest/VSubmenuDuels.java b/src/main/java/forge/gui/home/quest/VSubmenuDuels.java index ffee61f66a4..0025028385c 100644 --- a/src/main/java/forge/gui/home/quest/VSubmenuDuels.java +++ b/src/main/java/forge/gui/home/quest/VSubmenuDuels.java @@ -81,6 +81,7 @@ public enum VSubmenuDuels implements IVSubmenu, IVQuestStats, IVD .text("Next challenge in wins hasn't been set yet.") .fontSize(12).build(); + private final ExperimentalLabel btnUnlock = new ExperimentalLabel("Unlock Sets"); private final ExperimentalLabel btnBazaar = new ExperimentalLabel("Bazaar"); private final ExperimentalLabel btnSpellShop = new ExperimentalLabel("Spell Shop"); @@ -94,6 +95,7 @@ public enum VSubmenuDuels implements IVSubmenu, IVQuestStats, IVD final String constraints = "h 30px!, gap 0 0 0 5px"; pnlStats.setLayout(new MigLayout("insets 0, gap 0, wrap, hidemode 0")); + pnlStats.add(btnUnlock, "w 150px!, h 30px!, gap 0 0 0 10px"); pnlStats.add(btnSpellShop, "w 150px!, h 30px!, gap 0 0 0 10px"); pnlStats.add(btnBazaar, "w 150px!, h 30px!, gap 0 0 0 10px"); pnlStats.add(lblWins, constraints); @@ -206,6 +208,11 @@ public enum VSubmenuDuels implements IVSubmenu, IVQuestStats, IVD return btnBazaar; } + @Override + public ExperimentalLabel getBtnUnlock() { + return btnUnlock; + } + @Override public ExperimentalLabel getBtnSpellShop() { return btnSpellShop; diff --git a/src/main/java/forge/gui/match/QuestWinLose.java b/src/main/java/forge/gui/match/QuestWinLose.java index b166603a2e2..d6565e7607e 100644 --- a/src/main/java/forge/gui/match/QuestWinLose.java +++ b/src/main/java/forge/gui/match/QuestWinLose.java @@ -16,7 +16,6 @@ */ package forge.gui.match; -import javax.swing.JOptionPane; import forge.Card; import forge.Singletons; @@ -50,18 +49,14 @@ import forge.quest.QuestEvent; import forge.quest.bazaar.QuestItemType; import forge.quest.data.QuestPreferences; import forge.quest.data.QuestPreferences.QPref; -import forge.quest.io.ReadPriceList; import forge.util.MyRandom; import java.awt.Color; import java.awt.Dimension; import java.awt.Image; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.Map.Entry; -import java.util.TreeMap; import javax.swing.BorderFactory; import javax.swing.ImageIcon; @@ -191,10 +186,6 @@ public class QuestWinLose extends ControlWinLose { this.awardJackpot(); } - // Unlock new sets? - if (wins % 50 == 49) { - unlockSets(); - } } // Lose case else { @@ -490,45 +481,6 @@ public class QuestWinLose extends ControlWinLose { this.getView().getPnlCustom().add(this.lblTemp2, QuestWinLose.CONSTRAINTS_TEXT); } - /** - * Unlock new sets when applicable. - */ - private void unlockSets() { - CardEdition unlockedSet = unlockSet(); - - if (unlockedSet != null) { - - qData.getFormat().unlockSet(unlockedSet.getCode()); - - if (Singletons.getModel().getTournamentPacks().contains(unlockedSet.getCode())) { - final List cardsWon = (new UnOpenedProduct(Singletons.getModel().getTournamentPacks().get(unlockedSet.getCode()))).open(); - - // Generate Swing components and attach. - this.lblTemp1 = new TitleLabel("A starter pack for the *UNLOCKED* " + unlockedSet.getName() + " set!"); - final QuestWinLoseCardViewer cv = new QuestWinLoseCardViewer(cardsWon); - - this.view.getPnlCustom().add(this.lblTemp1, QuestWinLose.CONSTRAINTS_TITLE); - this.view.getPnlCustom().add(cv, QuestWinLose.CONSTRAINTS_CARDS); - - qData.getCards().addAllCards(cardsWon); - } - else if (Singletons.getModel().getBoosters().contains(unlockedSet.getCode())) { - for (int i = 0; i < 3; i++) { - final List cardsWon = (new UnOpenedProduct(Singletons.getModel().getBoosters().get(unlockedSet.getCode()))).open(); - - // Generate Swing components and attach. - this.lblTemp1 = new TitleLabel("Booster pack " + (i + 1) + " for the *UNLOCKED* " + unlockedSet.getName() + " set!"); - final QuestWinLoseCardViewer cv = new QuestWinLoseCardViewer(cardsWon); - - this.view.getPnlCustom().add(this.lblTemp1, QuestWinLose.CONSTRAINTS_TITLE); - this.view.getPnlCustom().add(cv, QuestWinLose.CONSTRAINTS_CARDS); - - qData.getCards().addAllCards(cardsWon); - } - } - } - } - /** *

* awardRandomRare. @@ -676,205 +628,6 @@ public class QuestWinLose extends ControlWinLose { } - /** - * Consider unlocking a new expansion in limited quest format. - * - * @return CardEdition, the unlocked edition if any. - */ - private CardEdition unlockSet() { - - if (qData.getFormat() == null || qData.getFormat().getExcludedSetCodes().isEmpty()) { - return null; - } - - List choices = unlockableSets(); - - if (choices == null || choices.size() < 1) { - return null; - } - - final int unlockSets = JOptionPane.showConfirmDialog(null, - "You have now won " + (qData.getAchievements().getWin() + 1) + " matches.\n" - + "With this achievement, you have the option of unlocking more sets. " - + "You have " + qData.getAssets().getCredits() + " credits.\n\n" - + "Do you want to unlock new sets?", - "CONGRATULATIONS!", JOptionPane.YES_NO_OPTION); - - if (unlockSets == JOptionPane.NO_OPTION) { - return null; - } - - - final ReadPriceList prices = new ReadPriceList(); - final Map mapPrices = prices.getPriceList(); - - List unlockPrices = new ArrayList(); - for (int i = 0; i < choices.size(); i++) { - if (mapPrices.containsKey(choices.get(i).getName() + " Booster Pack")) { - unlockPrices.add((long) 20 * mapPrices.get(choices.get(i).getName() + " Booster Pack")); - } - else { - unlockPrices.add((long) 8000); - } - } - - final String setPrompt = "You have " + qData.getAssets().getCredits() + " credits. Try to unlock:"; - List options = new ArrayList(); - for (int i = 0; i < choices.size(); i++) { - options.add(choices.get(i).getName() + " [PRICE: " + unlockPrices.get(i) + " credits]"); - } - options.add("None, thank you."); - final String choice = GuiChoose.one(setPrompt, options); - CardEdition chooseEd = null; - long price = 0; - - /* Examine choice */ - for (int i = 0; i < options.size(); i++) { - if (choice.equals(options.get(i))) { - if (i >= choices.size()) { - return null; - } - chooseEd = choices.get(i); - price = unlockPrices.get(i); - break; - } - } - - if (qData.getAssets().getCredits() < price) { - JOptionPane.showMessageDialog(null, "Unfortunately, you cannot afford that set yet.\n" - + "To unlock " + chooseEd.getName() + ", you need " + price + " credits.\n" - + "You have only " + qData.getAssets().getCredits() + " credits.", - "Failed to unlock " + chooseEd.getName(), - JOptionPane.PLAIN_MESSAGE); - return null; - } - - qData.getAssets().subtractCredits(price); - JOptionPane.showMessageDialog(null, "You have successfully unlocked " + chooseEd.getName() + "!", - chooseEd.getName() + " unlocked!", - JOptionPane.PLAIN_MESSAGE); - - return chooseEd; - } - - /** - * Helper function for unlockSet(). - * - * @return unmodifiable list, assorted sets that are not currently in the format. - */ - private List unlockableSets() { - if (qData.getFormat() == null || qData.getFormat().getExcludedSetCodes().isEmpty()) { - return null; - } - - final int nrChoices = 7; - List options = new ArrayList(); - - // Sort current sets by index - TreeMap sortedFormat = new TreeMap(); - for (String edCode : qData.getFormat().getAllowedSetCodes()) { - sortedFormat.put(new Integer(Singletons.getModel().getEditions().get(edCode).getIndex()), Singletons.getModel().getEditions().get(edCode)); - } - List currentSets = new ArrayList(sortedFormat.values()); - - // Sort unlockable sets by index - TreeMap sortedExcluded = new TreeMap(); - for (String edCode : qData.getFormat().getExcludedSetCodes()) { - sortedExcluded.put(new Integer(Singletons.getModel().getEditions().get(edCode).getIndex()), Singletons.getModel().getEditions().get(edCode)); - } - List excludedSets = new ArrayList(sortedExcluded.values()); - - // Collect 'previous' and 'next' editions - CardEdition first = currentSets.get(0); - CardEdition last = currentSets.get(currentSets.size() - 1); - List fillers = new ArrayList(); - - for (CardEdition ce : excludedSets) { - if (first.getIndex() == ce.getIndex() + 1 || last.getIndex() + 1 == ce.getIndex()) - { - options.add(ce); - // System.out.println("Added adjacent set: " + ce.getName()); - } else if (first.getIndex() == ce.getIndex() + 2 || first.getIndex() == ce.getIndex() + 3 - || last.getIndex() + 2 == ce.getIndex() || last.getIndex() + 3 == ce.getIndex() - || (last.getIndex() > ce.getIndex() && ce.getIndex() > first.getIndex())) { - if (MyRandom.getRandom().nextFloat() < 0.6f) { - fillers.add(ce); - // System.out.println("Added nearby or enclosed set: " + ce.getName()); - } - } - } - - // Look for nearby core sets or block starting sets... - for (BoosterData bd : Singletons.getModel().getTournamentPacks()) { - if (qData.getFormat().getExcludedSetCodes().contains(bd.getEdition()) - && !(fillers.contains(Singletons.getModel().getEditions().get(bd.getEdition()))) - && !(options.contains(Singletons.getModel().getEditions().get(bd.getEdition())))) { - // Set is not yet on any of the lists, see if it is 'close' to any of the sets we currently have - CardEdition curEd = Singletons.getModel().getEditions().get(bd.getEdition()); - int edIdx = curEd.getIndex(); - for (String cmpCode : qData.getFormat().getAllowedSetCodes()) { - int cmpIdx = Singletons.getModel().getEditions().get(cmpCode).getIndex(); - // Note that we need to check for fillers.contains() again inside this 'for' loop! - if (!fillers.contains(curEd) && (cmpIdx == edIdx + 1 || edIdx == cmpIdx + 1)) { - fillers.add(curEd); - // System.out.println("Added nearby starter/core set " + curEd.getName()); - } - else if (!fillers.contains(curEd) && (cmpIdx == edIdx + 2 || edIdx == cmpIdx + 2) && MyRandom.getRandom().nextFloat() < 0.7f) { - fillers.add(curEd); - //System.out.println("Added nearby2 starter/core set " + curEd.getName()); - } - else if (!fillers.contains(curEd) && (cmpIdx == edIdx + 3 || edIdx == cmpIdx + 3) && MyRandom.getRandom().nextFloat() < 0.45f) { - fillers.add(curEd); - // System.out.println("Added nearby3 starter/core set " + curEd.getName()); - } - } - } - } - - // Fill in the in-between sets... - int j = 0; - // Find the first excluded set between current sets first and current sets last - while (j < excludedSets.size() && excludedSets.get(j).getIndex() < currentSets.get(0).getIndex()) { - j++; - } - // Consider all sets until current sets last - while (j < excludedSets.size() && excludedSets.get(j).getIndex() < currentSets.get(currentSets.size() - 1).getIndex()) { - if (!options.contains(excludedSets.get(j)) && !fillers.contains(excludedSets.get(j))) { - // System.out.println("Added in-between set " + excludedSets.get(j).getCode()); - fillers.add(excludedSets.get(j)); - } - j++; - } - - if (fillers.size() + options.size() < nrChoices && excludedSets.size() > fillers.size() + options.size()) { - if (excludedSets.size() == 1 + fillers.size() + options.size()) { - // Only one set exists that isn't on the list yet - for (CardEdition ce : excludedSets) { - if (!fillers.contains(ce) && !options.contains(ce)) { - fillers.add(ce); - break; - } - } - } else { - while (fillers.size() + options.size() < nrChoices) { - CardEdition ce = excludedSets.get(MyRandom.getRandom().nextInt(excludedSets.size())); - if (!fillers.contains(ce) && !options.contains(ce)) { - fillers.add(ce); - // System.out.println("Randomly padded with set: " + ce.getName()); - } - } - } - } - - for (int i = 0; (options.size() < nrChoices) && i < fillers.size(); i++) { - options.add(fillers.get(i)); - // System.out.println("Padded with: " + fillers.get(i).getName()); - } - - return Collections.unmodifiableList(options); - } - - /** *

* awardChallengeWin. diff --git a/src/main/java/forge/quest/QuestController.java b/src/main/java/forge/quest/QuestController.java index 9398040f9d6..b4432d13cf2 100644 --- a/src/main/java/forge/quest/QuestController.java +++ b/src/main/java/forge/quest/QuestController.java @@ -356,4 +356,28 @@ public class QuestController { return this.pets; } + /** + * Quest format has unlockable sets available at the moment. + * @return int number of unlockable sets. + */ + public int getFormatNumberUnlockable() { + if (this.questFormat == null) { + return 0; + } + + final int wins = this.model.getAchievements().getWin(); + if (wins < 10) { + return 0; + } + + int toUnlock = this.questFormat.getExcludedSetCodes().size(); + if (toUnlock > (wins + 50) / 50) { + toUnlock = (wins + 50) / 50; + } + if (toUnlock > 8) { + toUnlock = 8; + } + return toUnlock; + } + } diff --git a/src/main/java/forge/quest/QuestUtilUnlockSets.java b/src/main/java/forge/quest/QuestUtilUnlockSets.java new file mode 100644 index 00000000000..b98a7fab5bb --- /dev/null +++ b/src/main/java/forge/quest/QuestUtilUnlockSets.java @@ -0,0 +1,254 @@ +package forge.quest; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import javax.swing.JOptionPane; + +import forge.Singletons; +import forge.card.BoosterData; +import forge.card.CardEdition; +import forge.card.UnOpenedProduct; +import forge.gui.CardListViewer; +import forge.gui.GuiChoose; +import forge.item.CardPrinted; +import forge.quest.io.ReadPriceList; + +/** + * TODO: Write javadoc for this type. + * + */ +public class QuestUtilUnlockSets { + + /** + * Consider unlocking a new expansion in limited quest format. + * @param qData the QuestController for the current quest + * @param freeUnlock this unlock is free (e.g., a challenge reward), NOT IMPLEMENTED YET + * @param presetChoices List a pregenerated list of options, NOT IMPLEMENTED YET + * @return CardEdition, the unlocked edition if any. + */ + public static CardEdition unlockSet(final QuestController qData, final boolean freeUnlock, + List presetChoices) { + + if (qData.getFormat() == null || qData.getFormat().getExcludedSetCodes().isEmpty()) { + return null; + } + + List choices = unlockableSets(qData); + + if (choices == null || choices.size() < 1) { + return null; + } + + final ReadPriceList prices = new ReadPriceList(); + final Map mapPrices = prices.getPriceList(); + + List unlockPrices = new ArrayList(); + for (int i = 0; i < choices.size(); i++) { + if (mapPrices.containsKey(choices.get(i).getName() + " Booster Pack")) { + long newPrice = (long) 35 * mapPrices.get(choices.get(i).getName() + " Booster Pack"); + if (newPrice < 10000) { newPrice = 10000; } + unlockPrices.add(newPrice); + } + else { + unlockPrices.add((long) 10000); + } + } + + final String setPrompt = "You have " + qData.getAssets().getCredits() + " credits. Unlock:"; + List options = new ArrayList(); + for (int i = 0; i < choices.size(); i++) { + options.add(choices.get(i).getName() + " [PRICE: " + unlockPrices.get(i) + " credits]"); + } + final String choice = GuiChoose.oneOrNone(setPrompt, options); + CardEdition chooseEd = null; + long price = 0; + + if (choice == null) { + return null; + } + + /* Examine choice */ + for (int i = 0; i < options.size(); i++) { + if (choice.equals(options.get(i))) { + chooseEd = choices.get(i); + price = unlockPrices.get(i); + break; + } + } + + if (qData.getAssets().getCredits() < price) { + JOptionPane.showMessageDialog(null, "Unfortunately, you cannot afford that set yet.\n" + + "To unlock " + chooseEd.getName() + ", you need " + price + " credits.\n" + + "You have only " + qData.getAssets().getCredits() + " credits.", + "Failed to unlock " + chooseEd.getName(), + JOptionPane.PLAIN_MESSAGE); + return null; + } + + final int unlockConfirm = JOptionPane.showConfirmDialog(null, + "Unlocking " + chooseEd.getName() + " will cost you " + price + " credits.\n" + + "You have " + qData.getAssets().getCredits() + " credits.\n\n" + + "Are you sure you want to unlock " + chooseEd.getName() + "?", + "Confirm Unlocking " + chooseEd.getName(), JOptionPane.YES_NO_OPTION); + if (unlockConfirm == JOptionPane.NO_OPTION) { + return null; + } + + qData.getAssets().subtractCredits(price); + JOptionPane.showMessageDialog(null, "You have successfully unlocked " + chooseEd.getName() + "!", + chooseEd.getName() + " unlocked!", + JOptionPane.PLAIN_MESSAGE); + + return chooseEd; + } + + /** + * Helper function for unlockSet(). + * + * @return unmodifiable list, assorted sets that are not currently in the format. + */ + private static List unlockableSets(final QuestController qData) { + if (qData.getFormat() == null || qData.getFormat().getExcludedSetCodes().isEmpty()) { + return null; + } + + final int nrChoices = qData.getFormatNumberUnlockable(); + if (nrChoices < 1) { // Should never happen if we made it this far but better safe than sorry... + throw new RuntimeException("BUG? Could not find unlockable sets even though we should."); + } + List options = new ArrayList(); + + // Sort current sets by index + TreeMap sortedFormat = new TreeMap(); + for (String edCode : qData.getFormat().getAllowedSetCodes()) { + sortedFormat.put(new Integer(Singletons.getModel().getEditions().get(edCode).getIndex()), Singletons.getModel().getEditions().get(edCode)); + } + List currentSets = new ArrayList(sortedFormat.values()); + + // Sort unlockable sets by index + TreeMap sortedExcluded = new TreeMap(); + for (String edCode : qData.getFormat().getExcludedSetCodes()) { + sortedExcluded.put(new Integer(Singletons.getModel().getEditions().get(edCode).getIndex()), Singletons.getModel().getEditions().get(edCode)); + } + List excludedSets = new ArrayList(sortedExcluded.values()); + + // Collect 'previous' and 'next' editions + CardEdition first = currentSets.get(0); + CardEdition last = currentSets.get(currentSets.size() - 1); + List fillers = new ArrayList(); + + // Add nearby sets first + for (CardEdition ce : excludedSets) { + if (first.getIndex() == ce.getIndex() + 1 || last.getIndex() + 1 == ce.getIndex()) + { + options.add(ce); + // System.out.println("Added adjacent set: " + ce.getName()); + } + } + + // Fill in the in-between sets + int j = 0; + // Find the first excluded set between current sets first and current sets last + while (j < excludedSets.size() && excludedSets.get(j).getIndex() < currentSets.get(0).getIndex()) { + j++; + } + // Consider all sets until current sets last + while (j < excludedSets.size() && excludedSets.get(j).getIndex() < currentSets.get(currentSets.size() - 1).getIndex()) { + if (!options.contains(excludedSets.get(j)) && !fillers.contains(excludedSets.get(j))) { + // System.out.println("Added in-between set " + excludedSets.get(j).getCode()); + fillers.add(excludedSets.get(j)); + } + j++; + } + // Add more nearby sets + for (CardEdition ce : excludedSets) { + if (first.getIndex() == ce.getIndex() + 2 || last.getIndex() + 2 == ce.getIndex()) + { + if (!fillers.contains(ce) && !options.contains(ce)) { + fillers.add(ce); + // System.out.println("Added adjacent filler set: " + ce.getName()); + } + } + } + + // Look for nearby core sets or block starting sets... + for (BoosterData bd : Singletons.getModel().getTournamentPacks()) { + if (qData.getFormat().getExcludedSetCodes().contains(bd.getEdition()) + && !(fillers.contains(Singletons.getModel().getEditions().get(bd.getEdition()))) + && !(options.contains(Singletons.getModel().getEditions().get(bd.getEdition())))) { + // Set is not yet on any of the lists, see if it is 'close' to any of the sets we currently have + CardEdition curEd = Singletons.getModel().getEditions().get(bd.getEdition()); + int edIdx = curEd.getIndex(); + for (String cmpCode : qData.getFormat().getAllowedSetCodes()) { + int cmpIdx = Singletons.getModel().getEditions().get(cmpCode).getIndex(); + // Note that we need to check for fillers.contains() again inside this 'for' loop! + if (!fillers.contains(curEd) && (cmpIdx == edIdx + 1 || edIdx == cmpIdx + 1)) { + fillers.add(curEd); + // System.out.println("Added nearby starter/core set " + curEd.getName()); + } + else if (!fillers.contains(curEd) && (cmpIdx == edIdx + 2 || edIdx == cmpIdx + 2)) { + fillers.add(curEd); + //System.out.println("Added nearby2 starter/core set " + curEd.getName()); + } + } + } + } + + // Add padding if necessary + if (fillers.size() + options.size() < nrChoices && excludedSets.size() > fillers.size() + options.size()) { + // Pad in order. + for (CardEdition ce : excludedSets) { + if (!fillers.contains(ce) && !options.contains(ce)) { + fillers.add(ce); + if (fillers.size() + options.size() >= nrChoices) { + break; + } + } + } + } + + for (int i = 0; (options.size() < nrChoices) && i < fillers.size(); i++) { + options.add(fillers.get(i)); + // System.out.println("Padded with: " + fillers.get(i).getName()); + } + + return Collections.unmodifiableList(options); + } + + /** + * + * Unlock a set and get some free cards, if a tournament pack or boosters are available. + * @param qData the quest controller + * @param unlockedSet the edition to unlock + */ + public static void doUnlock(QuestController qData, final CardEdition unlockedSet) { + + qData.getFormat().unlockSet(unlockedSet.getCode()); + + List displayCards = new ArrayList(); + + if (Singletons.getModel().getTournamentPacks().contains(unlockedSet.getCode())) { + final List cardsWon = (new UnOpenedProduct(Singletons.getModel().getTournamentPacks().get(unlockedSet.getCode()))).open(); + + qData.getCards().addAllCards(cardsWon); + displayCards.addAll(cardsWon); + } + else if (Singletons.getModel().getBoosters().contains(unlockedSet.getCode())) { + for (int i = 0; i < 3; i++) { + final List cardsWon = (new UnOpenedProduct(Singletons.getModel().getBoosters().get(unlockedSet.getCode()))).open(); + + qData.getCards().addAllCards(cardsWon); + displayCards.addAll(cardsWon); + } + } + + final CardListViewer cardView = new CardListViewer(unlockedSet.getName(), + "You get the following bonus cards:", displayCards); + cardView.show(); + + } +}