From ab4dc7d0867df9c34ddfcb3839df9505fb4f0a1d Mon Sep 17 00:00:00 2001 From: RumbleBBU Date: Tue, 16 Oct 2012 08:51:54 +0000 Subject: [PATCH] Added experimental new expansion unlocking scheme to limited-format quests. Once per every 100 wins, you get the option of using credits to "unlock" a new set and add it to your enforced format. --- .../forge/gui/match/QuestWinLoseHandler.java | 211 ++++++++++++++++++ .../forge/quest/data/GameFormatQuest.java | 44 +++- 2 files changed, 253 insertions(+), 2 deletions(-) diff --git a/src/main/java/forge/gui/match/QuestWinLoseHandler.java b/src/main/java/forge/gui/match/QuestWinLoseHandler.java index 9fb5997098d..f3f918a34c3 100644 --- a/src/main/java/forge/gui/match/QuestWinLoseHandler.java +++ b/src/main/java/forge/gui/match/QuestWinLoseHandler.java @@ -18,6 +18,7 @@ package forge.gui.match; import forge.AllZone; +import javax.swing.JOptionPane; import forge.Card; import forge.Singletons; @@ -52,13 +53,17 @@ import forge.quest.QuestUtil; import forge.quest.bazaar.QuestItemType; import forge.quest.data.QuestAssets; 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.TreeMap; import javax.swing.BorderFactory; import javax.swing.ImageIcon; @@ -226,6 +231,11 @@ public class QuestWinLoseHandler extends ControlWinLose { this.penalizeLoss(); } + // Unlock new sets? + if (this.wonMatch && qData.getAchievements().getWin() > 99 && (qData.getAchievements().getWin() % 100) == 0) { + unlockSets(); + } + // Grant booster on a win, or on a loss in easy mode if (this.wonMatch || difficulty == 0) { final int outcome = this.wonMatch ? qData.getAchievements().getWin() : qData.getAchievements().getLost(); @@ -510,6 +520,45 @@ public class QuestWinLoseHandler extends ControlWinLose { this.getView().getPnlCustom().add(this.lblTemp2, QuestWinLoseHandler.CONSTRAINTS_TEXT); } + /** + * Unlock new sets when applicable. + */ + private void unlockSets() { + CardEdition unlockedSet = unlockSet(); + + if (unlockedSet != null) { + + qData.getFormat().addSet(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, QuestWinLoseHandler.CONSTRAINTS_TITLE); + this.view.getPnlCustom().add(cv, QuestWinLoseHandler.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, QuestWinLoseHandler.CONSTRAINTS_TITLE); + this.view.getPnlCustom().add(cv, QuestWinLoseHandler.CONSTRAINTS_CARDS); + + qData.getCards().addAllCards(cardsWon); + } + } + } + } + /** *

* awardRandomRare. @@ -657,6 +706,168 @@ public class QuestWinLoseHandler 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() + " 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); + if (qData.getAssets().getCredits() < price) { + JOptionPane.showMessageDialog(null, "You have successfully unlocked " + chooseEd.getName() + "!", + chooseEd.getName() + " unlocked!", + JOptionPane.PLAIN_MESSAGE); + return null; + } + + 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 = 5; + 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()); + } + } + } + + // TODO: Check for currently incomplete blocks in the format, add the missing blocks to fillers + + 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/data/GameFormatQuest.java b/src/main/java/forge/quest/data/GameFormatQuest.java index 88bd19984e2..8fb434701c2 100644 --- a/src/main/java/forge/quest/data/GameFormatQuest.java +++ b/src/main/java/forge/quest/data/GameFormatQuest.java @@ -24,6 +24,8 @@ import java.util.ArrayList; import com.google.common.base.Function; import com.google.common.base.Predicate; + +import forge.Singletons; import forge.card.CardEdition; import forge.card.CardRulesPredicates; import forge.game.GameFormat; @@ -177,16 +179,54 @@ public final class GameFormatQuest { /** * Gets the set list. * - * @return list of allowed set codes + * @return unmodifiable list of allowed set codes */ public List getAllowedSetCodes() { return Collections.unmodifiableList(this.allowedSetCodes); } + /** + * Get the list of excluded sets. + * + * @return unmodifiable list of excluded sets. + */ + public List getExcludedSetCodes() { + if (this.allowedSetCodes == null || this.allowedSetCodes.isEmpty()) { + return null; + } + + List exSets = new ArrayList(); + + for (CardEdition ce : Singletons.getModel().getEditions()) { + if (!isSetLegal(ce.getCode())) { + // System.out.println("Added " + ce.getCode() + " to the list."); + exSets.add(ce.getCode()); + } + } + return Collections.unmodifiableList(exSets); + } + + /** + * Add a set to allowed set codes. + * + * @param setCode String, set code. + */ + public void addSet(final String setCode) { + if (this.allowedSetCodes == null) { + this.allowedSetCodes = new ArrayList(); // this should never happen. + } else if (this.allowedSetCodes.isEmpty()) { + return; // We are already allowing all sets! + } else if (this.allowedSetCodes.contains(setCode)) { + return; // Already on the list + } + // System.out.println("Adding " + setCode + " to allowed sets!"); + this.allowedSetCodes.add(setCode); + } + /** * Gets the banned cards. * - * @return list of banned card names + * @return unmodifiable list of banned card names */ public List getBannedCardNames() { return Collections.unmodifiableList(this.bannedCardNames);