mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
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.
This commit is contained in:
@@ -18,6 +18,7 @@ package forge.gui.match;
|
|||||||
|
|
||||||
import forge.AllZone;
|
import forge.AllZone;
|
||||||
|
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
@@ -52,13 +53,17 @@ import forge.quest.QuestUtil;
|
|||||||
import forge.quest.bazaar.QuestItemType;
|
import forge.quest.bazaar.QuestItemType;
|
||||||
import forge.quest.data.QuestAssets;
|
import forge.quest.data.QuestAssets;
|
||||||
import forge.quest.data.QuestPreferences.QPref;
|
import forge.quest.data.QuestPreferences.QPref;
|
||||||
|
import forge.quest.io.ReadPriceList;
|
||||||
import forge.util.MyRandom;
|
import forge.util.MyRandom;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
@@ -226,6 +231,11 @@ public class QuestWinLoseHandler extends ControlWinLose {
|
|||||||
this.penalizeLoss();
|
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
|
// Grant booster on a win, or on a loss in easy mode
|
||||||
if (this.wonMatch || difficulty == 0) {
|
if (this.wonMatch || difficulty == 0) {
|
||||||
final int outcome = this.wonMatch ? qData.getAchievements().getWin() : qData.getAchievements().getLost();
|
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);
|
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<CardPrinted> 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<CardPrinted> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* awardRandomRare.
|
* 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<CardEdition> 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<String, Integer> mapPrices = prices.getPriceList();
|
||||||
|
|
||||||
|
List<Long> unlockPrices = new ArrayList<Long>();
|
||||||
|
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<String> options = new ArrayList<String>();
|
||||||
|
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<CardEdition> unlockableSets() {
|
||||||
|
if (qData.getFormat() == null || qData.getFormat().getExcludedSetCodes().isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int nrChoices = 5;
|
||||||
|
List<CardEdition> options = new ArrayList<CardEdition>();
|
||||||
|
|
||||||
|
// Sort current sets by index
|
||||||
|
TreeMap<Integer, CardEdition> sortedFormat = new TreeMap<Integer, CardEdition>();
|
||||||
|
for (String edCode : qData.getFormat().getAllowedSetCodes()) {
|
||||||
|
sortedFormat.put(new Integer(Singletons.getModel().getEditions().get(edCode).getIndex()), Singletons.getModel().getEditions().get(edCode));
|
||||||
|
}
|
||||||
|
List<CardEdition> currentSets = new ArrayList<CardEdition>(sortedFormat.values());
|
||||||
|
|
||||||
|
// Sort unlockable sets by index
|
||||||
|
TreeMap<Integer, CardEdition> sortedExcluded = new TreeMap<Integer, CardEdition>();
|
||||||
|
for (String edCode : qData.getFormat().getExcludedSetCodes()) {
|
||||||
|
sortedExcluded.put(new Integer(Singletons.getModel().getEditions().get(edCode).getIndex()), Singletons.getModel().getEditions().get(edCode));
|
||||||
|
}
|
||||||
|
List<CardEdition> excludedSets = new ArrayList<CardEdition>(sortedExcluded.values());
|
||||||
|
|
||||||
|
// Collect 'previous' and 'next' editions
|
||||||
|
CardEdition first = currentSets.get(0);
|
||||||
|
CardEdition last = currentSets.get(currentSets.size() - 1);
|
||||||
|
List<CardEdition> fillers = new ArrayList<CardEdition>();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* awardChallengeWin.
|
* awardChallengeWin.
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import java.util.ArrayList;
|
|||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
|
||||||
|
import forge.Singletons;
|
||||||
import forge.card.CardEdition;
|
import forge.card.CardEdition;
|
||||||
import forge.card.CardRulesPredicates;
|
import forge.card.CardRulesPredicates;
|
||||||
import forge.game.GameFormat;
|
import forge.game.GameFormat;
|
||||||
@@ -177,16 +179,54 @@ public final class GameFormatQuest {
|
|||||||
/**
|
/**
|
||||||
* Gets the set list.
|
* Gets the set list.
|
||||||
*
|
*
|
||||||
* @return list of allowed set codes
|
* @return unmodifiable list of allowed set codes
|
||||||
*/
|
*/
|
||||||
public List<String> getAllowedSetCodes() {
|
public List<String> getAllowedSetCodes() {
|
||||||
return Collections.unmodifiableList(this.allowedSetCodes);
|
return Collections.unmodifiableList(this.allowedSetCodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of excluded sets.
|
||||||
|
*
|
||||||
|
* @return unmodifiable list of excluded sets.
|
||||||
|
*/
|
||||||
|
public List<String> getExcludedSetCodes() {
|
||||||
|
if (this.allowedSetCodes == null || this.allowedSetCodes.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> exSets = new ArrayList<String>();
|
||||||
|
|
||||||
|
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<String>(); // 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.
|
* Gets the banned cards.
|
||||||
*
|
*
|
||||||
* @return list of banned card names
|
* @return unmodifiable list of banned card names
|
||||||
*/
|
*/
|
||||||
public List<String> getBannedCardNames() {
|
public List<String> getBannedCardNames() {
|
||||||
return Collections.unmodifiableList(this.bannedCardNames);
|
return Collections.unmodifiableList(this.bannedCardNames);
|
||||||
|
|||||||
Reference in New Issue
Block a user