Added experimental 'limited Quest mode'. If selected, it will impose format-based restrictions on the available cards during the game. Current exceptions: theme decks in spell stores (deliberate). enemy decks (more in-format enemy decks would be needed first).

This commit is contained in:
RumbleBBU
2012-10-05 11:47:56 +00:00
parent 2005faddcc
commit e5d2b805ea
11 changed files with 485 additions and 29 deletions

1
.gitattributes vendored
View File

@@ -12592,6 +12592,7 @@ src/main/java/forge/error/ExceptionHandler.java svneol=native#text/plain
src/main/java/forge/error/package-info.java svneol=native#text/plain src/main/java/forge/error/package-info.java svneol=native#text/plain
src/main/java/forge/game/GameEndReason.java -text src/main/java/forge/game/GameEndReason.java -text
src/main/java/forge/game/GameFormat.java -text src/main/java/forge/game/GameFormat.java -text
src/main/java/forge/game/GameFormatQuest.java -text
src/main/java/forge/game/GameLossReason.java -text src/main/java/forge/game/GameLossReason.java -text
src/main/java/forge/game/GameNew.java -text src/main/java/forge/game/GameNew.java -text
src/main/java/forge/game/GamePlayerRating.java -text src/main/java/forge/game/GamePlayerRating.java -text

View File

@@ -22,6 +22,7 @@ import com.google.common.base.Predicate;
import forge.Singletons; import forge.Singletons;
import forge.game.GameFormat; import forge.game.GameFormat;
import forge.game.GameFormatQuest;
import forge.util.FileSection; import forge.util.FileSection;
import forge.util.StorageReaderFile; import forge.util.StorageReaderFile;
@@ -223,6 +224,29 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
return this.format.isSetLegal(subject.getCode()); return this.format.isSetLegal(subject.getCode());
} }
} }
/**
* Checks if is legal in quest format.
*
* @param qFormat the format
* @return the predicate
*/
public static final Predicate<CardEdition> isLegalInFormatQuest(final GameFormatQuest qFormat) {
return new LegalInFormatQuest(qFormat);
}
private static class LegalInFormatQuest implements Predicate<CardEdition> {
private final GameFormatQuest qFormat;
public LegalInFormatQuest(final GameFormatQuest fmt) {
this.qFormat = fmt;
}
@Override
public boolean apply(final CardEdition subject) {
return this.qFormat.isSetLegal(subject.getCode());
}
}
} }
public static class Reader extends StorageReaderFile<CardEdition> { public static class Reader extends StorageReaderFile<CardEdition> {

View File

@@ -83,6 +83,24 @@ public final class GameFormat {
return this.name; return this.name;
} }
/**
* Gets the set list (for GameFormatQuest).
*
* @return list of allowed set codes
*/
public List<String> getAllowedSetCodes() {
return this.allowedSetCodes;
}
/**
* Gets the banned cards (for GameFormatQuest).
*
* @return list of banned card names
*/
public List<String> getBannedCardNames() {
return this.bannedCardNames;
}
/** /**
* Gets the filter rules. * Gets the filter rules.
* *

View File

@@ -0,0 +1,221 @@
/*
* Forge: Play Magic: the Gathering.
* Copyright (C) 2011 Forge Team
*
* This program is free software: you can redistribute it and/or modify
* 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 <http://www.gnu.org/licenses/>.
*/
package forge.game;
import java.util.List;
import java.util.ArrayList;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import forge.card.CardRulesPredicates;
import forge.item.CardPrinted;
/**
* This is an alternate game format type, the main difference is that this
* is not immutable. This class is necessary because we may wish to update
* its contents in certain circumstances, and it was safer to create a new
* class than to make the preset game formats modifiable.
*/
public final class GameFormatQuest {
private final String name;
// contains allowed sets, when empty allows all sets
private List<String> allowedSetCodes;
private List<String> bannedCardNames;
private Predicate<CardPrinted> filterRules;
private Predicate<CardPrinted> filterPrinted;
/**
* Instantiates a new game format based on an existing format.
*
* @param toCopy
* an existing format
*/
public GameFormatQuest(final GameFormat toCopy) {
this.name = new String(toCopy.getName());
this.allowedSetCodes = new ArrayList<String>();
allowedSetCodes.addAll(toCopy.getAllowedSetCodes());
this.bannedCardNames = new ArrayList<String>();
bannedCardNames.addAll(toCopy.getBannedCardNames());
this.filterRules = this.buildFilterRules();
this.filterPrinted = this.buildFilterPrinted();
}
/**
* Instantiates an empty new game format.
*
* @param newName
* String, the name
*/
public GameFormatQuest(final String newName) {
this.name = new String(newName);
this.allowedSetCodes = new ArrayList<String>();
this.bannedCardNames = new ArrayList<String>();
}
/**
* Instantiates a new game format based on two lists.
*
* @param newName
* String, the name
* @param setsToAllow
* List<String>, these are the allowed sets
* @param cardsToBan
* List<String>, these will be the banned cards
*/
public GameFormatQuest(final String newName, final List<String> setsToAllow, final List<String> cardsToBan) {
this.name = new String(newName);
this.allowedSetCodes = new ArrayList<String>();
allowedSetCodes.addAll(setsToAllow);
this.bannedCardNames = new ArrayList<String>();
bannedCardNames.addAll(cardsToBan);
this.filterRules = this.buildFilterRules();
this.filterPrinted = this.buildFilterPrinted();
}
private Predicate<CardPrinted> buildFilterPrinted() {
final Predicate<CardPrinted> banNames = CardPrinted.Predicates.namesExcept(this.bannedCardNames);
if (this.allowedSetCodes == null || this.allowedSetCodes.isEmpty()) {
return banNames;
}
return Predicates.and(banNames, CardPrinted.Predicates.printedInSets(this.allowedSetCodes, true));
}
private Predicate<CardPrinted> buildFilterRules() {
final Predicate<CardPrinted> banNames = CardPrinted.Predicates.namesExcept(this.bannedCardNames);
if (this.allowedSetCodes == null || this.allowedSetCodes.isEmpty()) {
return banNames;
}
return Predicates.and(banNames, Predicates.compose(CardRulesPredicates.wasPrintedInSets(this.allowedSetCodes), CardPrinted.FN_GET_RULES));
}
/**
*
* Updates the filters based on the current list data.
*/
public void updateFilters() {
this.filterRules = this.buildFilterRules();
this.filterPrinted = this.buildFilterPrinted();
}
/**
* @param setCode
* the set code to add
*/
public void addAllowedSet(final String setCode) {
if (!allowedSetCodes.contains(setCode)) {
allowedSetCodes.add(setCode);
}
}
/**
* @param banCard
* the card to ban
*/
public void addBannedCard(final String banCard) {
if (!bannedCardNames.contains(banCard)) {
bannedCardNames.add(banCard);
}
}
/**
* Gets the name.
*
* @return the name
*/
public String getName() {
return this.name;
}
/**
* Gets the filter rules.
*
* @return the filter rules
*/
public Predicate<CardPrinted> getFilterRules() {
return this.filterRules;
}
/**
* Gets the filter printed.
*
* @return the filter printed
*/
public Predicate<CardPrinted> getFilterPrinted() {
return this.filterPrinted;
}
/**
* Gets the set list.
*
* @return list of allowed set codes
*/
public List<String> getAllowedSetCodes() {
return this.allowedSetCodes;
}
/**
* Gets the banned cards.
*
* @return list of banned card names
*/
public List<String> getBannedCardNames() {
return this.bannedCardNames;
}
/**
* Checks if is sets the legal.
*
* @param setCode
* the set code
* @return true, if is sets the legal
*/
public boolean isSetLegal(final String setCode) {
return this.allowedSetCodes.isEmpty() || this.allowedSetCodes.contains(setCode);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.name + " (format)";
}
public static final Function<GameFormat, String> FN_GET_NAME = new Function<GameFormat, String>() {
@Override
public String apply(GameFormat arg1) {
return arg1.getName();
}
};
}

View File

@@ -158,7 +158,7 @@ public enum CSubmenuQuestData implements ICDoc {
} }
// Give the user a few cards to build a deck // Give the user a few cards to build a deck
AllZone.getQuest().newGame(questName, difficulty, mode, startPool, rotatingFormat, startPrecon); AllZone.getQuest().newGame(questName, difficulty, mode, startPool, rotatingFormat, startPrecon, view.getBoxPersist().isSelected());
AllZone.getQuest().save(); AllZone.getQuest().save();
// Save in preferences. // Save in preferences.

View File

@@ -61,6 +61,7 @@ public enum VSubmenuQuestData implements IVSubmenu {
private final JRadioButton radExpert = new FRadioButton("Expert"); private final JRadioButton radExpert = new FRadioButton("Expert");
private final JCheckBox boxFantasy = new FCheckBox("Fantasy Mode"); private final JCheckBox boxFantasy = new FCheckBox("Fantasy Mode");
private final JCheckBox boxFormatPersist = new FCheckBox("Enforce format during quest");
private final JRadioButton radCompleteStart = new FRadioButton("Unrestricted Starting Pool"); private final JRadioButton radCompleteStart = new FRadioButton("Unrestricted Starting Pool");
private final JRadioButton radRotatingStart = new FRadioButton("Format: "); private final JRadioButton radRotatingStart = new FRadioButton("Format: ");
@@ -113,6 +114,7 @@ public enum VSubmenuQuestData implements IVSubmenu {
public void actionPerformed(ActionEvent actionEvent) { public void actionPerformed(ActionEvent actionEvent) {
cbxPrecon.setEnabled(radPreconStart.isSelected()); cbxPrecon.setEnabled(radPreconStart.isSelected());
cbxFormat.setEnabled(radRotatingStart.isSelected()); cbxFormat.setEnabled(radRotatingStart.isSelected());
boxFormatPersist.setEnabled(radRotatingStart.isSelected());
} }
}; };
@@ -155,6 +157,8 @@ public enum VSubmenuQuestData implements IVSubmenu {
radRotatingStart.addActionListener(preconListener); radRotatingStart.addActionListener(preconListener);
group3.add(radPreconStart); group3.add(radPreconStart);
cbxFormat.setEnabled(false); cbxFormat.setEnabled(false);
boxFormatPersist.setSelected(true);
boxFormatPersist.setEnabled(false);
radPreconStart.addActionListener(preconListener); radPreconStart.addActionListener(preconListener);
radCompleteStart.setSelected(true); radCompleteStart.setSelected(true);
cbxPrecon.setEnabled(false); cbxPrecon.setEnabled(false);
@@ -177,9 +181,9 @@ public enum VSubmenuQuestData implements IVSubmenu {
pnlOptions.add(radRotatingStart, constraints + ", wrap"); pnlOptions.add(radRotatingStart, constraints + ", wrap");
pnlOptions.add(radExpert, constraints + ", gap 7.5% 2.5% 0 0 "); pnlOptions.add(radExpert, constraints + ", gap 7.5% 2.5% 0 0 ");
pnlOptions.add(cbxFormat, constraints + ", gap 20 0, w 30%!, wrap"); pnlOptions.add(cbxFormat, constraints + ", gap 20 0, w 30%!, wrap");
pnlOptions.add(boxFormatPersist, constraints + ", wrap, skip");
pnlOptions.add(radPreconStart, constraints + ", wrap, skip"); pnlOptions.add(radPreconStart, constraints + ", wrap, skip");
pnlOptions.add(cbxPrecon, "gap 20 0, w 30%!, h 35px!, wrap, skip"); pnlOptions.add(cbxPrecon, "gap 20 0, w 30%!, h 35px!, wrap, skip");
pnlOptions.add(btnEmbark, "w 40%!, h 30px!, gap 30% 0 20px 0, span 3 1"); pnlOptions.add(btnEmbark, "w 40%!, h 30px!, gap 30% 0 20px 0, span 3 1");
// Final layout // Final layout
@@ -197,7 +201,7 @@ public enum VSubmenuQuestData implements IVSubmenu {
pnlViewport.add(scr, "w 96%!, pushy, growy, gap 2% 0 0 30px"); pnlViewport.add(scr, "w 96%!, pushy, growy, gap 2% 0 0 30px");
pnlViewport.add(pnlTitleNew, "w 96%, h 36px!, gap 2% 0 0 10px"); pnlViewport.add(pnlTitleNew, "w 96%, h 36px!, gap 2% 0 0 10px");
pnlViewport.add(pnlOptions, "w 96%!, h 250px!, gap 2% 0 0 20px"); pnlViewport.add(pnlOptions, "w 96%!, h 280px!, gap 2% 0 0 20px");
scrContent.setBorder(null); scrContent.setBorder(null);
} }
@@ -277,6 +281,13 @@ public enum VSubmenuQuestData implements IVSubmenu {
return boxFantasy; return boxFantasy;
} }
/**
* @return {@link javax.swing.JCheckBox}
*/
public JCheckBox getBoxPersist() {
return boxFormatPersist;
}
/** /**
* @return {@link javax.swing.JRadioButton} * @return {@link javax.swing.JRadioButton}
*/ */

View File

@@ -553,21 +553,9 @@ public class QuestWinLoseHandler extends ControlWinLose {
*/ */
private void awardBooster() { private void awardBooster() {
// Do not enable booster selection in this way...
final boolean allowSetSelection = false;
final List<String> boosterTypes = new ArrayList<String>();
boosterTypes.add("Format");
boosterTypes.add("Set");
final String prompt = "Choose bonus booster type:";
Object o = null;
if (allowSetSelection) {
o = GuiChoose.one(prompt, boosterTypes);
}
List<CardPrinted> cardsWon = null; List<CardPrinted> cardsWon = null;
if (o == null || o.toString().equals(boosterTypes.get(0))) { if (qData.getFormat() == null) {
final List<GameFormat> formats = new ArrayList<GameFormat>(); final List<GameFormat> formats = new ArrayList<GameFormat>();
String prefferedFormat = Singletons.getModel().getQuestPreferences().getPreference(QPref.BOOSTER_FORMAT); String prefferedFormat = Singletons.getModel().getQuestPreferences().getPreference(QPref.BOOSTER_FORMAT);
@@ -595,14 +583,59 @@ public class QuestWinLoseHandler extends ControlWinLose {
final List<String> sets = new ArrayList<String>(); final List<String> sets = new ArrayList<String>();
for (BoosterData bd : Singletons.getModel().getBoosters()) { for (BoosterData bd : Singletons.getModel().getBoosters()) {
sets.add(bd.getEdition()); if (qData.getFormat().isSetLegal(bd.getEdition())) {
sets.add(bd.getEdition());
}
} }
List<String> chooseSets = new ArrayList<String>();
int maxChoices = 1;
if (this.wonMatch) {
maxChoices++;
final int wins = qData.getAchievements().getWin();
if (wins > 0 && wins % 5 == 0) { maxChoices++; }
if (wins > 0 && wins % 20 == 0) { maxChoices++; }
if (wins > 0 && wins % 50 == 0) { maxChoices++; }
}
if (sets.size() > maxChoices) {
if (maxChoices > 1) {
Boolean[] choices = new Boolean[sets.size()];
for (int i = 0; i < sets.size(); i++) {
choices[i] = false;
}
int toEnable = maxChoices;
while (toEnable > 0) {
int index = MyRandom.getRandom().nextInt(sets.size());
if (!choices[index]) {
choices[index] = true;
toEnable--;
}
}
for (int i = 0; i < sets.size(); i++) {
if (choices[i]) {
chooseSets.add(sets.get(i));
}
}
} else {
chooseSets.add(sets.get(MyRandom.getRandom().nextInt(sets.size())));
}
} else {
chooseSets.addAll(sets);
}
final String setPrompt = "Choose bonus booster set:"; final String setPrompt = "Choose bonus booster set:";
final String chSet = GuiChoose.one(setPrompt, sets); final String chSet = GuiChoose.one(setPrompt, chooseSets);
cardsWon = (new UnOpenedProduct(Singletons.getModel().getBoosters().get(chSet))).open(); cardsWon = (new UnOpenedProduct(Singletons.getModel().getBoosters().get(chSet))).open();
qData.getCards().addAllCards(cardsWon); qData.getCards().addAllCards(cardsWon);
this.lblTemp1 = new TitleLabel("Bonus booster pack from the \"" + chSet + "\" booster!"); this.lblTemp1 = new TitleLabel("Bonus \"" + chSet + "\" booster pack!");
} }
if (cardsWon != null) { if (cardsWon != null) {

View File

@@ -25,6 +25,7 @@ import com.google.common.base.Predicates;
import forge.Singletons; import forge.Singletons;
import forge.deck.Deck; import forge.deck.Deck;
import forge.game.GameFormatQuest;
import forge.item.CardPrinted; import forge.item.CardPrinted;
import forge.item.PreconDeck; import forge.item.PreconDeck;
import forge.properties.ForgeProps; import forge.properties.ForgeProps;
@@ -54,6 +55,8 @@ public class QuestController {
// complex // complex
private QuestUtilCards myCards; private QuestUtilCards myCards;
private GameFormatQuest questFormat;
private QuestEvent currentEvent; private QuestEvent currentEvent;
/** The decks. */ /** The decks. */
@@ -125,6 +128,15 @@ public class QuestController {
return this.decks; return this.decks;
} }
/**
* Gets the current format if any.
*
* @return GameFormatQuest, the game format (if persistent).
*/
public GameFormatQuest getFormat() {
return this.questFormat;
}
/** /**
* Gets the current event. * Gets the current event.
* *
@@ -162,8 +174,12 @@ public class QuestController {
// These are helper classes that hold no data. // These are helper classes that hold no data.
this.decks = this.model == null ? null : this.model.getAssets().getDeckStorage(); this.decks = this.model == null ? null : this.model.getAssets().getDeckStorage();
this.myCards = this.model == null ? null : new QuestUtilCards(this); this.myCards = this.model == null ? null : new QuestUtilCards(this);
this.questFormat = this.model == null ? null : this.model.getFormat();
this.currentEvent = null; this.currentEvent = null;
// if (questFormat == null) { System.out.println("No quest."); }
// else { System.out.println("Quest = " + questFormat.getName()); }
this.getChallengesManager().randomizeOpponents(); this.getChallengesManager().randomizeOpponents();
this.getDuelsManager().randomizeOpponents(); this.getDuelsManager().randomizeOpponents();
} }
@@ -195,11 +211,17 @@ public class QuestController {
* @param startPool the start type * @param startPool the start type
* @param startFormat the format of starting pool * @param startFormat the format of starting pool
* @param preconName the precon name * @param preconName the precon name
* @param persist
* enforce the format for the whole quest
*/ */
public void newGame(final String name, final int diff, final QuestMode mode, final QuestStartPool startPool, public void newGame(final String name, final int diff, final QuestMode mode, final QuestStartPool startPool,
final String startFormat, final String preconName) { final String startFormat, final String preconName, final boolean persist) {
this.load(new QuestData(name, diff, mode)); if (persist && startPool == QuestStartPool.Rotating) {
this.load(new QuestData(name, diff, mode, startFormat));
} else {
this.load(new QuestData(name, diff, mode, null));
}
final Predicate<CardPrinted> filter; final Predicate<CardPrinted> filter;
switch (startPool) { switch (startPool) {

View File

@@ -20,8 +20,11 @@ package forge.quest;
import forge.Singletons; import forge.Singletons;
import forge.card.BoosterGenerator; import forge.card.BoosterGenerator;
import forge.card.CardEdition; import forge.card.CardEdition;
import forge.card.CardRules;
import forge.card.CardRulesPredicates;
import forge.card.FormatCollection; import forge.card.FormatCollection;
import forge.deck.Deck; import forge.deck.Deck;
import forge.game.GameFormatQuest;
import forge.item.*; import forge.item.*;
import forge.quest.bazaar.QuestItemType; import forge.quest.bazaar.QuestItemType;
import forge.quest.data.QuestAssets; import forge.quest.data.QuestAssets;
@@ -145,7 +148,12 @@ public final class QuestUtilCards {
* @return the card printed * @return the card printed
*/ */
public CardPrinted addRandomRare() { public CardPrinted addRandomRare() {
final CardPrinted card = Aggregates.random(Iterables.filter(CardDb.instance().getAllCards(), QuestUtilCards.RARE_PREDICATE)); Predicate<CardPrinted> myFilter = QuestUtilCards.RARE_PREDICATE;
if (qc.getFormat() != null) {
myFilter = Predicates.and(QuestUtilCards.RARE_PREDICATE, qc.getFormat().getFilterPrinted());
}
final CardPrinted card = Aggregates.random(Iterables.filter(CardDb.instance().getAllCards(), myFilter));
this.addSingleCard(card); this.addSingleCard(card);
return card; return card;
} }
@@ -158,7 +166,13 @@ public final class QuestUtilCards {
* @return the list * @return the list
*/ */
public List<CardPrinted> addRandomRare(final int n) { public List<CardPrinted> addRandomRare(final int n) {
final List<CardPrinted> newCards = Aggregates.random(Iterables.filter(CardDb.instance().getAllCards(), QuestUtilCards.RARE_PREDICATE), n); Predicate<CardPrinted> myFilter = QuestUtilCards.RARE_PREDICATE;
if (qc.getFormat() != null) {
myFilter = Predicates.and(QuestUtilCards.RARE_PREDICATE, qc.getFormat().getFilterPrinted());
}
final List<CardPrinted> newCards = Aggregates.random(Iterables.filter(CardDb.instance().getAllCards(), myFilter), n);
this.addAllCards(newCards); this.addAllCards(newCards);
return newCards; return newCards;
} }
@@ -338,6 +352,17 @@ public final class QuestUtilCards {
private final Predicate<CardEdition> filterNotExt = Predicates.and(CardEdition.Predicates.CAN_MAKE_BOOSTER, private final Predicate<CardEdition> filterNotExt = Predicates.and(CardEdition.Predicates.CAN_MAKE_BOOSTER,
Predicates.not(this.filterExt)); Predicates.not(this.filterExt));
/**
* Helper predicate for shops: is legal in quest format.
*
* @param qFormat
* the quest format
* @return the predicate
*/
public static Predicate<CardEdition> isLegalInQuestFormat(final GameFormatQuest qFormat) {
return CardEdition.Predicates.isLegalInFormatQuest(qFormat);
}
/** /**
* Generate boosters in shop. * Generate boosters in shop.
* *
@@ -347,8 +372,11 @@ public final class QuestUtilCards {
public void generateBoostersInShop(final int count) { public void generateBoostersInShop(final int count) {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
final int rollD100 = MyRandom.getRandom().nextInt(100); final int rollD100 = MyRandom.getRandom().nextInt(100);
final Predicate<CardEdition> filter = rollD100 < 40 ? this.filterT2booster Predicate<CardEdition> filter = rollD100 < 40 ? this.filterT2booster
: (rollD100 < 75 ? this.filterExtButT2 : this.filterNotExt); : (rollD100 < 75 ? this.filterExtButT2 : this.filterNotExt);
if (qc.getFormat() != null) {
filter = isLegalInQuestFormat(qc.getFormat());
}
Iterable<CardEdition> rightEditions = Iterables.filter(Singletons.getModel().getEditions(), filter); Iterable<CardEdition> rightEditions = Iterables.filter(Singletons.getModel().getEditions(), filter);
this.qa.getShopList().add(BoosterPack.FN_FROM_SET.apply(Aggregates.random(rightEditions))); this.qa.getShopList().add(BoosterPack.FN_FROM_SET.apply(Aggregates.random(rightEditions)));
} }
@@ -361,12 +389,26 @@ public final class QuestUtilCards {
* the count * the count
*/ */
public void generateTournamentsInShop(final int count) { public void generateTournamentsInShop(final int count) {
Iterable<CardEdition> rightEditions = Iterables.filter(Singletons.getModel().getEditions(), CardEdition.Predicates.HAS_TOURNAMENT_PACK); Predicate<CardEdition> formatFilter = CardEdition.Predicates.HAS_TOURNAMENT_PACK;
if (qc.getFormat() != null) {
formatFilter = Predicates.and(formatFilter, isLegalInQuestFormat(qc.getFormat()));
}
Iterable<CardEdition> rightEditions = Iterables.filter(Singletons.getModel().getEditions(), formatFilter);
this.qa.getShopList().addAllFlat(Aggregates.random(Iterables.transform(rightEditions, TournamentPack.FN_FROM_SET), count)); this.qa.getShopList().addAllFlat(Aggregates.random(Iterables.transform(rightEditions, TournamentPack.FN_FROM_SET), count));
} }
/**
* Generate precons in shop.
*
* @param count
* the count
*/
public void generateFatPacksInShop(final int count) { public void generateFatPacksInShop(final int count) {
Iterable<CardEdition> rightEditions = Iterables.filter(Singletons.getModel().getEditions(), CardEdition.Predicates.HAS_FAT_PACK); Predicate<CardEdition> formatFilter = CardEdition.Predicates.HAS_FAT_PACK;
if (qc.getFormat() != null) {
formatFilter = Predicates.and(formatFilter, isLegalInQuestFormat(qc.getFormat()));
}
Iterable<CardEdition> rightEditions = Iterables.filter(Singletons.getModel().getEditions(), formatFilter);
this.qa.getShopList().addAllFlat(Aggregates.random(Iterables.transform(rightEditions, FatPack.FN_FROM_SET), count)); this.qa.getShopList().addAllFlat(Aggregates.random(Iterables.transform(rightEditions, FatPack.FN_FROM_SET), count));
} }
@@ -390,7 +432,15 @@ public final class QuestUtilCards {
* Generate cards in shop. * Generate cards in shop.
*/ */
public void generateCardsInShop() { public void generateCardsInShop() {
final BoosterGenerator pack = new BoosterGenerator(CardDb.instance().getAllCards());
Iterable<CardPrinted> cardList = null;
if (qc.getFormat() == null) {
cardList = CardDb.instance().getAllCards(); }
else {
cardList = Iterables.filter(CardDb.instance().getAllCards(), qc.getFormat().getFilterPrinted());
}
final BoosterGenerator pack = new BoosterGenerator(cardList);
int nLevel = this.qc.getAchievements().getLevel(); int nLevel = this.qc.getAchievements().getLevel();

View File

@@ -17,6 +17,8 @@
*/ */
package forge.quest.data; package forge.quest.data;
import forge.Singletons;
import forge.game.GameFormatQuest;
import forge.quest.QuestMode; import forge.quest.QuestMode;
import forge.quest.io.QuestDataIO; import forge.quest.io.QuestDataIO;
@@ -43,6 +45,7 @@ public final class QuestData {
/** The version number. */ /** The version number. */
private int versionNumber = QuestData.CURRENT_VERSION_NUMBER; private int versionNumber = QuestData.CURRENT_VERSION_NUMBER;
private GameFormatQuest format;
private final String name; private final String name;
// Quest mode - there should be an enum :( // Quest mode - there should be an enum :(
@@ -58,12 +61,22 @@ public final class QuestData {
/** /**
* Instantiates a new quest data. * Instantiates a new quest data.
* @param mode2 * @param mode2
* quest mode
* @param diff * @param diff
* achievement diff
* @param name2 * @param name2
* quest name
* @param formatString
* String, persistent format for the quest (null if none).
*/ */
public QuestData(String name2, int diff, QuestMode mode2) { public QuestData(String name2, int diff, QuestMode mode2, final String formatString) {
this.name = name2; this.name = name2;
if (formatString == null) {
format = null;
} else {
format = new GameFormatQuest(Singletons.getModel().getFormats().getFormat(formatString));
}
this.mode = mode2; this.mode = mode2;
this.achievements = new QuestAchievements(diff); this.achievements = new QuestAchievements(diff);
this.assets = new QuestAssets(); this.assets = new QuestAssets();
@@ -78,6 +91,15 @@ public final class QuestData {
return this.mode; return this.mode;
} }
/**
* Gets the persistent format, null if not assigned.
*
* @return GameFormatQuest, the persistent format
*/
public GameFormatQuest getFormat() {
return this.format;
}
// SERIALIZATION - related things // SERIALIZATION - related things
// This must be called by XML-serializer via reflection // This must be called by XML-serializer via reflection

View File

@@ -57,6 +57,7 @@ import forge.card.CardEdition;
import forge.deck.DeckSection; import forge.deck.DeckSection;
import forge.error.ErrorViewer; import forge.error.ErrorViewer;
import forge.game.GameType; import forge.game.GameType;
import forge.game.GameFormatQuest;
import forge.item.BoosterPack; import forge.item.BoosterPack;
import forge.item.CardDb; import forge.item.CardDb;
import forge.item.CardPrinted; import forge.item.CardPrinted;
@@ -98,6 +99,7 @@ public class QuestDataIO {
xStream.registerConverter(new ItemPoolToXml()); xStream.registerConverter(new ItemPoolToXml());
xStream.registerConverter(new DeckSectionToXml()); xStream.registerConverter(new DeckSectionToXml());
xStream.registerConverter(new GameTypeToXml()); xStream.registerConverter(new GameTypeToXml());
xStream.registerConverter(new GameFormatQuestToXml());
xStream.registerConverter(new QuestModeToXml()); xStream.registerConverter(new QuestModeToXml());
xStream.autodetectAnnotations(true); xStream.autodetectAnnotations(true);
xStream.alias("CardPool", ItemPool.class); xStream.alias("CardPool", ItemPool.class);
@@ -351,7 +353,7 @@ public class QuestDataIO {
final File f = new File(ForgeProps.getFile(NewConstants.Quest.DATA_DIR), qd.getName()); final File f = new File(ForgeProps.getFile(NewConstants.Quest.DATA_DIR), qd.getName());
QuestDataIO.savePacked(f + ".dat", xStream, qd); QuestDataIO.savePacked(f + ".dat", xStream, qd);
//QuestDataIO.saveUnpacked(f + ".xml", xStream, qd); // QuestDataIO.saveUnpacked(f + ".xml", xStream, qd);
} catch (final Exception ex) { } catch (final Exception ex) {
ErrorViewer.showError(ex, "Error saving Quest Data."); ErrorViewer.showError(ex, "Error saving Quest Data.");
@@ -375,6 +377,58 @@ public class QuestDataIO {
boutUnp.close(); boutUnp.close();
} }
private static class GameFormatQuestToXml implements Converter {
@SuppressWarnings("rawtypes")
@Override
public boolean canConvert(final Class clasz) {
return clasz.equals(GameFormatQuest.class);
}
@Override
public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) {
writer.startNode("format");
GameFormatQuest format = (GameFormatQuest) source;
writer.addAttribute("name", format.getName());
writer.endNode();
for (String set : format.getAllowedSetCodes()) {
writer.startNode("set");
writer.addAttribute("s", set);
writer.endNode();
}
for (String ban : format.getBannedCardNames()) {
writer.startNode("ban");
writer.addAttribute("s", ban);
writer.endNode();
}
}
@Override
public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) {
reader.moveDown();
GameFormatQuest format = new GameFormatQuest(reader.getAttribute("name"));
reader.moveUp();
while (reader.hasMoreChildren()) {
reader.moveDown();
final String nodename = reader.getNodeName();
if (nodename.equals("ban")) {
String toBan = reader.getAttribute("s");
format.addBannedCard(toBan);
// System.out.println("Added + " + toBan + " to banned cards");
}
else if (nodename.equals("set")) {
String toSets = reader.getAttribute("s");
format.addAllowedSet(toSets);
// System.out.println("Added + " + toSets + " to legal sets");
}
reader.moveUp();
}
format.updateFilters();
return format;
}
}
private static class GameTypeToXml implements Converter { private static class GameTypeToXml implements Converter {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override