diff --git a/forge-core/src/main/java/forge/card/CardDb.java b/forge-core/src/main/java/forge/card/CardDb.java index cdb48cfa730..e204dec3bc8 100644 --- a/forge-core/src/main/java/forge/card/CardDb.java +++ b/forge-core/src/main/java/forge/card/CardDb.java @@ -18,18 +18,12 @@ package forge.card; import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; -import com.google.common.collect.ListMultimap; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimaps; - +import com.google.common.collect.*; import forge.card.CardEdition.CardInSet; import forge.card.CardEdition.Type; import forge.deck.generation.IDeckGenPool; import forge.item.PaperCard; import forge.util.*; - import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; @@ -547,6 +541,15 @@ public final class CardDb implements ICardDatabase, IDeckGenPool { return roAllCards; } + public Collection getAllNonPromoCards() { + return Lists.newArrayList(Iterables.filter(this.roAllCards, new Predicate() { + @Override + public boolean apply(final PaperCard paperCard) { + return editions.getEditionByCodeOrThrow(paperCard.getEdition()).getType() != Type.PROMOS; + } + })); + } + public String getName(final String cardName) { if (alternateName.containsKey(cardName)) { return alternateName.get(cardName); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestPrefs.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestPrefs.java index caab3c441ac..fb9d77463e6 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestPrefs.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestPrefs.java @@ -221,6 +221,8 @@ public enum VSubmenuQuestPrefs implements IVSubmenu { pnlRewards.add(new PrefInput(QPref.REWARDS_TURN1, QuestPreferencesErrType.REWARDS), fieldConstraints); pnlRewards.add(new FLabel.Builder().text(localizer.getMessage("lblMaxLifeDiffBonus")).fontAlign(SwingConstants.RIGHT).build(), labelConstraints); pnlRewards.add(new PrefInput(QPref.REWARDS_HEALTH_DIFF_MAX, QuestPreferencesErrType.REWARDS), fieldConstraints); + pnlRewards.add(new FLabel.Builder().text(localizer.getMessage("lblExcludePromosFromRewardPool")).fontAlign(SwingConstants.RIGHT).build(), labelConstraints); + pnlRewards.add(new PrefInput(QPref.EXCLUDE_PROMOS_FROM_POOL, QuestPreferencesErrType.REWARDS), fieldConstraints); } private void populateDifficulty() { pnlDifficulty.setOpaque(false); diff --git a/forge-gui-mobile/src/forge/screens/quest/QuestPrefsScreen.java b/forge-gui-mobile/src/forge/screens/quest/QuestPrefsScreen.java index f267bf2fc80..4ad16f6f9af 100644 --- a/forge-gui-mobile/src/forge/screens/quest/QuestPrefsScreen.java +++ b/forge-gui-mobile/src/forge/screens/quest/QuestPrefsScreen.java @@ -70,6 +70,7 @@ public class QuestPrefsScreen extends FScreen { scroller.add(new PrefsOption(localizer.getMessage("lblWinbyTurn10"), QPref.REWARDS_TURN10, PrefsGroup.REWARDS)); scroller.add(new PrefsOption(localizer.getMessage("lblWinbyTurn5"), QPref.REWARDS_TURN5, PrefsGroup.REWARDS)); scroller.add(new PrefsOption(localizer.getMessage("lblFirstTurnWin"), QPref.REWARDS_TURN1, PrefsGroup.REWARDS)); + scroller.add(new PrefsOption(localizer.getMessage("lblExcludePromosFromRewardPool"), QPref.EXCLUDE_PROMOS_FROM_POOL, PrefsGroup.REWARDS)); //Booster Pack Ratios scroller.add(new PrefsHeader(localizer.getMessage("lblBoosterPackRatios"), FSkinImage.QUEST_BOOK, PrefsGroup.BOOSTER)); diff --git a/forge-gui/release-files/ANNOUNCEMENTS.txt b/forge-gui/release-files/ANNOUNCEMENTS.txt index 5a649afaa61..a81aa6230f0 100644 --- a/forge-gui/release-files/ANNOUNCEMENTS.txt +++ b/forge-gui/release-files/ANNOUNCEMENTS.txt @@ -2,4 +2,5 @@ Get in the discord if you aren't yet. Planar Conquest now has a new plane accessible - Ikoria. In Planar Conquest, it's now possible to collect C19 cards on Eldraine and ZNE/ZNC cards on Zendikar. -In Planar Conquest, the Eldraine plane now holds a little secret that's rather unhinged. It may be difficult to find though. \ No newline at end of file +In Planar Conquest, the Eldraine plane now holds a little secret that's rather unhinged. It may be difficult to find though. +Quest Mode now has a preference option to enable or disable promos in random reward pool. \ No newline at end of file diff --git a/forge-gui/res/languages/de-DE.properties b/forge-gui/res/languages/de-DE.properties index 3a2b59192e3..1f91f8971f8 100644 --- a/forge-gui/res/languages/de-DE.properties +++ b/forge-gui/res/languages/de-DE.properties @@ -701,6 +701,7 @@ lblWinbyTurn10=Sieg bis Zug 10 lblWinbyTurn5=Sieg bis Zug 5 lblFirstTurnWin=Sieg im ersten Zug lblMaxLifeDiffBonus=Max. Lebensdifferenzbonus +lblExcludePromosFromRewardPool=Exclude Promos lblEasy=Einfach lblMedium=Mittel lblHard=Hart diff --git a/forge-gui/res/languages/en-US.properties b/forge-gui/res/languages/en-US.properties index 5e5798bc1fe..af39603f29d 100644 --- a/forge-gui/res/languages/en-US.properties +++ b/forge-gui/res/languages/en-US.properties @@ -701,6 +701,7 @@ lblWinbyTurn10=Win by Turn 10 lblWinbyTurn5=Win by Turn 5 lblFirstTurnWin=First Turn Win lblMaxLifeDiffBonus=Max Life Diff. Bonus +lblExcludePromosFromRewardPool=Exclude Promos lblEasy=Easy lblMedium=Medium lblHard=Hard diff --git a/forge-gui/res/languages/es-ES.properties b/forge-gui/res/languages/es-ES.properties index 93bb5643c6a..f4de80612c1 100644 --- a/forge-gui/res/languages/es-ES.properties +++ b/forge-gui/res/languages/es-ES.properties @@ -701,6 +701,7 @@ lblWinbyTurn10=Victoria en el turno 10 lblWinbyTurn5=Victoria en el turno 5 lblFirstTurnWin=Victoria en el primer turno lblMaxLifeDiffBonus=Bonus por máxima diferencia en vidas +lblExcludePromosFromRewardPool=Exclude Promos lblEasy=Fácil lblMedium=Medio lblHard=Difícil diff --git a/forge-gui/res/languages/it-IT.properties b/forge-gui/res/languages/it-IT.properties index ef1e3094fa3..63c7184945c 100644 --- a/forge-gui/res/languages/it-IT.properties +++ b/forge-gui/res/languages/it-IT.properties @@ -701,6 +701,7 @@ lblWinbyTurn10=Vinci al turno 10 lblWinbyTurn5=Vinci al turno 5 lblFirstTurnWin=Primo turno Vinci lblMaxLifeDiffBonus=Max Life Diff. indennità +lblExcludePromosFromRewardPool=Exclude Promos lblEasy=Facile lblMedium=medio lblHard=Difficile diff --git a/forge-gui/res/languages/ja-JP.properties b/forge-gui/res/languages/ja-JP.properties index c3c0e34f5d5..6e04d1d8e51 100644 --- a/forge-gui/res/languages/ja-JP.properties +++ b/forge-gui/res/languages/ja-JP.properties @@ -701,6 +701,7 @@ lblWinbyTurn10=10ターン以内に勝利 lblWinbyTurn5=5ターン以内に勝利 lblFirstTurnWin=1ターン目に勝利 lblMaxLifeDiffBonus=ノーダメージ報酬 +lblExcludePromosFromRewardPool=Exclude Promos lblEasy=簡単 lblMedium=普通 lblHard=難しい diff --git a/forge-gui/res/languages/zh-CN.properties b/forge-gui/res/languages/zh-CN.properties index d425253b20d..5b8f82cdb5d 100644 --- a/forge-gui/res/languages/zh-CN.properties +++ b/forge-gui/res/languages/zh-CN.properties @@ -701,6 +701,7 @@ lblWinbyTurn10=10回合内胜利 lblWinbyTurn5=5回合内胜利 lblFirstTurnWin=第一回合胜利 lblMaxLifeDiffBonus=最大生命值差。奖金 +lblExcludePromosFromRewardPool=Exclude Promos lblEasy=简单 lblMedium=中等 lblHard=难 diff --git a/forge-gui/src/main/java/forge/quest/BoosterUtils.java b/forge-gui/src/main/java/forge/quest/BoosterUtils.java index 84d6cb768bd..cf23ad1eee4 100644 --- a/forge-gui/src/main/java/forge/quest/BoosterUtils.java +++ b/forge-gui/src/main/java/forge/quest/BoosterUtils.java @@ -115,7 +115,7 @@ public final class BoosterUtils { filter = formatStartingPool.getFilterPrinted(); } - final List cardPool = Lists.newArrayList(Iterables.filter(FModel.getMagicDb().getCommonCards().getAllCards(), filter)); + final List cardPool = Lists.newArrayList(Iterables.filter(FModel.getMagicDb().getCommonCards().getAllNonPromoCards(), filter)); if (userPrefs != null && userPrefs.grantCompleteSet()) { for (PaperCard card : cardPool) { @@ -478,7 +478,7 @@ public final class BoosterUtils { PrintSheet ps = new PrintSheet("Quest rewards"); Predicate predicate = preds.size() == 1 ? preds.get(0) : Predicates.and(preds); - ps.addAll(Iterables.filter(FModel.getMagicDb().getCommonCards().getAllCards(), predicate)); + ps.addAll(Iterables.filter(FModel.getMagicDb().getCommonCards().getAllNonPromoCards(), predicate)); rewards.addAll(ps.random(qty, true)); } else if (temp.length == 2 && temp[0].equalsIgnoreCase("duplicate") && temp[1].equalsIgnoreCase("card")) { // Type 2: a duplicate card of the players choice diff --git a/forge-gui/src/main/java/forge/quest/QuestUtilCards.java b/forge-gui/src/main/java/forge/quest/QuestUtilCards.java index ac51a6ba441..a0048b88292 100644 --- a/forge-gui/src/main/java/forge/quest/QuestUtilCards.java +++ b/forge-gui/src/main/java/forge/quest/QuestUtilCards.java @@ -23,7 +23,10 @@ import com.google.common.base.Predicates; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; -import forge.card.*; +import forge.card.CardEdition; +import forge.card.CardRarity; +import forge.card.ICardDatabase; +import forge.card.MagicColor; import forge.deck.Deck; import forge.deck.DeckSection; import forge.game.GameFormat; @@ -44,7 +47,10 @@ import forge.util.ItemPool; import forge.util.MyRandom; import org.apache.commons.lang3.tuple.Pair; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; import java.util.Map.Entry; /** @@ -215,10 +221,13 @@ public final class QuestUtilCards { * @return the card printed */ public PaperCard addRandomRare() { + final boolean usePromos = questPreferences.getPrefInt(QPref.EXCLUDE_PROMOS_FROM_POOL) == 0; + final Collection pool = usePromos ? FModel.getMagicDb().getCommonCards().getAllCards() + : FModel.getMagicDb().getCommonCards().getAllNonPromoCards(); final Predicate myFilter = applyFormatFilter(QuestUtilCards.RARE_PREDICATE); - final PaperCard card = Aggregates.random(Iterables.filter(FModel.getMagicDb().getCommonCards().getAllCards(), myFilter)); + final PaperCard card = Aggregates.random(Iterables.filter(pool, myFilter)); addSingleCard(card, 1); return card; } @@ -230,8 +239,12 @@ public final class QuestUtilCards { * @return the list of cards added */ public List addRandomCommon(final int n) { + final boolean usePromos = questPreferences.getPrefInt(QPref.EXCLUDE_PROMOS_FROM_POOL) == 0; + final Collection pool = usePromos ? FModel.getMagicDb().getCommonCards().getAllCards() + : FModel.getMagicDb().getCommonCards().getAllNonPromoCards(); + final Predicate myFilter = applyFormatFilter(QuestUtilCards.COMMON_PREDICATE); - final List newCards = Aggregates.random(Iterables.filter(FModel.getMagicDb().getCommonCards().getAllCards(), myFilter), n); + final List newCards = Aggregates.random(Iterables.filter(pool, myFilter), n); addAllCards(newCards); return newCards; } @@ -243,8 +256,12 @@ public final class QuestUtilCards { * @return the list of cards added */ public List addRandomUncommon(final int n) { + final boolean usePromos = questPreferences.getPrefInt(QPref.EXCLUDE_PROMOS_FROM_POOL) == 0; + final Collection pool = usePromos ? FModel.getMagicDb().getCommonCards().getAllCards() + : FModel.getMagicDb().getCommonCards().getAllNonPromoCards(); + final Predicate myFilter = applyFormatFilter(QuestUtilCards.UNCOMMON_PREDICATE); - final List newCards = Aggregates.random(Iterables.filter(FModel.getMagicDb().getCommonCards().getAllCards(), myFilter), n); + final List newCards = Aggregates.random(Iterables.filter(pool, myFilter), n); addAllCards(newCards); return newCards; } @@ -257,9 +274,13 @@ public final class QuestUtilCards { * @return the list */ public List addRandomRare(final int n) { + final boolean usePromos = questPreferences.getPrefInt(QPref.EXCLUDE_PROMOS_FROM_POOL) == 0; + final Collection pool = usePromos ? FModel.getMagicDb().getCommonCards().getAllCards() + : FModel.getMagicDb().getCommonCards().getAllNonPromoCards(); + final Predicate myFilter = applyFormatFilter(QuestUtilCards.RARE_PREDICATE); - final List newCards = Aggregates.random(Iterables.filter(FModel.getMagicDb().getCommonCards().getAllCards(), myFilter), n); + final List newCards = Aggregates.random(Iterables.filter(pool, myFilter), n); addAllCards(newCards); return newCards; } @@ -272,9 +293,13 @@ public final class QuestUtilCards { * @return the list */ public List addRandomRareNotMythic(final int n) { + final boolean usePromos = questPreferences.getPrefInt(QPref.EXCLUDE_PROMOS_FROM_POOL) == 0; + final Collection pool = usePromos ? FModel.getMagicDb().getCommonCards().getAllCards() + : FModel.getMagicDb().getCommonCards().getAllNonPromoCards(); + final Predicate myFilter = applyFormatFilter(QuestUtilCards.ONLY_RARE_PREDICATE); - final List newCards = Aggregates.random(Iterables.filter(FModel.getMagicDb().getCommonCards().getAllCards(), myFilter), n); + final List newCards = Aggregates.random(Iterables.filter(pool, myFilter), n); addAllCards(newCards); return newCards; } @@ -287,9 +312,13 @@ public final class QuestUtilCards { * @return the list */ public List addRandomMythicRare(final int n) { + final boolean usePromos = questPreferences.getPrefInt(QPref.EXCLUDE_PROMOS_FROM_POOL) == 0; + final Collection pool = usePromos ? FModel.getMagicDb().getCommonCards().getAllCards() + : FModel.getMagicDb().getCommonCards().getAllNonPromoCards(); + final Predicate myFilter = applyFormatFilter(QuestUtilCards.MYTHIC_PREDICATE); - final Iterable cardPool = Iterables.filter(FModel.getMagicDb().getCommonCards().getAllCards(), myFilter); + final Iterable cardPool = Iterables.filter(pool, myFilter); if (!cardPool.iterator().hasNext()) { return null; diff --git a/forge-gui/src/main/java/forge/quest/data/QuestPreferences.java b/forge-gui/src/main/java/forge/quest/data/QuestPreferences.java index a60d03fbf92..8611560a5de 100644 --- a/forge-gui/src/main/java/forge/quest/data/QuestPreferences.java +++ b/forge-gui/src/main/java/forge/quest/data/QuestPreferences.java @@ -177,7 +177,7 @@ public class QuestPreferences extends PreferencesStore i WILD_OPPONENTS_MULTIPLIER("2.0"), WILD_OPPONENTS_NUMBER("0"), - //The number of cards to keep before selling + // The number of cards to keep before selling PLAYSET_SIZE("4"), PLAYSET_ANY_NUMBER_SIZE("500"), PLAYSET_BASIC_LAND_SIZE("50"), @@ -187,7 +187,10 @@ public class QuestPreferences extends PreferencesStore i SIMULATE_AI_VS_AI_RESULTS("0"), DRAFT_ROTATION("0"), FOIL_FILTER_DEFAULT("0"), - RATING_FILTER_DEFAULT("1"); + RATING_FILTER_DEFAULT("1"), + + // Exclude promos from the random reward pool + EXCLUDE_PROMOS_FROM_POOL("1"); private final String strDefaultVal; @@ -295,6 +298,7 @@ public class QuestPreferences extends PreferencesStore i case FOIL_FILTER_DEFAULT: case RATING_FILTER_DEFAULT: case ITEM_LEVEL_RESTRICTION: + case EXCLUDE_PROMOS_FROM_POOL: if (val != 0 && val != 1) { return "Only values 0 or 1 are acceptable; 1 for enabled, 0 for disabled."; }