matchStarter = new ArrayList<>();
private RegisteredPlayer humanPlayer = null;
private void setHumanPlayer(final RegisteredPlayer humanPlayer) {
this.matchStarter.add(humanPlayer);
diff --git a/forge-gui/src/main/java/forge/quest/QuestEventDraft.java b/forge-gui/src/main/java/forge/quest/QuestEventDraft.java
index 641f7b56410..1729a55db41 100644
--- a/forge-gui/src/main/java/forge/quest/QuestEventDraft.java
+++ b/forge-gui/src/main/java/forge/quest/QuestEventDraft.java
@@ -17,16 +17,6 @@
*/
package forge.quest;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
import forge.GuiBase;
import forge.card.CardEdition;
import forge.card.CardEdition.CardInSet;
@@ -44,9 +34,11 @@ import forge.player.GamePlayerUtil;
import forge.quest.data.QuestPreferences.QPref;
import forge.quest.io.ReadPriceList;
import forge.util.NameGenerator;
-import forge.util.TextUtil;
import forge.util.storage.IStorage;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
/**
*
* QuestEvent.
@@ -69,14 +61,14 @@ public class QuestEventDraft {
}
public boolean hasBoosterPacks() {
- return boosterPacks != null && boosterPacks.size() > 0;
+ return boosterPacks != null && !boosterPacks.isEmpty();
}
public boolean hasIndividualCards() {
- return individualCards != null && individualCards.size() > 0;
+ return individualCards != null && !individualCards.isEmpty();
}
- public boolean selectRareFromSets() { return selectRareCards != null && selectRareCards.size() > 0; }
+ public boolean selectRareFromSets() { return selectRareCards != null && !selectRareCards.isEmpty(); }
public void addSelectedCard(final PaperCard card) {
FModel.getQuest().getCards().addSingleCard(card, 1);
@@ -362,19 +354,8 @@ public class QuestEventDraft {
cards.add(getPromoCard());
- int creditsForPacks = (credits / 2); //Spend 50% of the credits on packs
-
- while (true) {
- final BoosterPack pack = getBoosterPack();
- final int price = getBoosterPrice(pack);
- if (price > creditsForPacks + creditsForPacks * 0.1f) { //Add a little room for near-same price packs.
- break;
- }
- creditsForPacks -= price;
- boosters.add(pack);
- }
-
- credits = (credits / 2) + creditsForPacks; //Add the leftover credits + 50%
+ int creditsLeftAfterPacks = generateBoosters((credits / 2), boosters); //Spend 75% of the credits on packs
+ credits = (credits / 2) + creditsLeftAfterPacks; //Add the leftover credits + 50%
final QuestDraftPrizes prizes = new QuestDraftPrizes();
prizes.credits = credits;
@@ -394,19 +375,9 @@ public class QuestEventDraft {
cards.add(getPromoCard());
- int creditsForPacks = (credits / 4) * 3; //Spend 75% of the credits on packs
+ int creditsLeftAfterPacks = generateBoosters((credits / 4) * 3, boosters); //Spend 75% of the credits on packs
- while (true) {
- final BoosterPack pack = getBoosterPack();
- final int price = getBoosterPrice(pack);
- if (price > creditsForPacks + creditsForPacks * 0.1f) { //Add a little room for near-same price packs.
- break;
- }
- creditsForPacks -= price;
- boosters.add(pack);
- }
-
- credits = (credits / 4) + creditsForPacks; //Add the leftover credits + 25%
+ credits = (credits / 4) + creditsLeftAfterPacks; //Add the leftover credits + 25%
final QuestDraftPrizes prizes = new QuestDraftPrizes();
prizes.credits = credits;
@@ -452,6 +423,20 @@ public class QuestEventDraft {
}
+ private int generateBoosters(final int creditsForPacks, final List boosters) {
+ int creditsAfterPacks = creditsForPacks;
+ while (true) {
+ final BoosterPack pack = getBoosterPack();
+ final int price = getBoosterPrice(pack);
+ if (price > creditsAfterPacks * 1.1f) { //Add a little room for near-same price packs.
+ break;
+ }
+ creditsAfterPacks -= price;
+ boosters.add(pack);
+ }
+ return creditsAfterPacks;
+ }
+
private void awardSelectedRare(final QuestDraftPrizes prizes) {
final List possibleCards = new ArrayList<>();
@@ -682,14 +667,60 @@ public class QuestEventDraft {
return title;
}
- public static List getAvailableBlocks(final QuestController quest) {
+ public static class QuestDraftFormat implements Comparable {
+
+ private CardEdition edition;
+ private CardBlock block;
+
+ public QuestDraftFormat(final CardEdition edition) {
+ this.edition = edition;
+ }
+
+ public QuestDraftFormat(final CardBlock block) {
+ this.block = block;
+ }
+
+ private boolean isSet() {
+ return edition != null;
+ }
+
+ @Override
+ public String toString() {
+ if (edition != null) {
+ return edition.getName() + " (" + edition.getCode() + ")";
+ }
+ String blockString = block.getName() + " (";
+ List sets = block.getSets();
+ for (int i = 0; i < sets.size(); i++) {
+ CardEdition cardEdition = sets.get(i);
+ blockString += cardEdition.getCode();
+ if (i < sets.size() - 1) {
+ blockString += ", ";
+ }
+ }
+ blockString += ")";
+ return blockString;
+ }
+
+ public String getName() {
+ if (edition != null) {
+ return edition.getName();
+ }
+ return block.getName();
+ }
+
+ @Override
+ public int compareTo(final QuestDraftFormat other) {
+ return toString().compareToIgnoreCase(other.toString());
+ }
+
+ }
+
+ private static List getAllowedSets(final QuestController quest) {
- final List possibleBlocks = new ArrayList<>();
final List allowedQuestSets = new ArrayList<>();
- final boolean questUsesLimitedCardPool = quest.getFormat() != null;
-
- if (questUsesLimitedCardPool) {
+ if (quest.getFormat() != null) {
final List allowedSetCodes = quest.getFormat().getAllowedSetCodes();
@@ -699,6 +730,12 @@ public class QuestEventDraft {
}
+ return allowedQuestSets;
+
+ }
+
+ private static List getBlocks() {
+
final List blocks = new ArrayList<>();
final IStorage storage = FModel.getBlocks();
@@ -708,29 +745,72 @@ public class QuestEventDraft {
}
}
- if (questUsesLimitedCardPool) {
+ return blocks;
+
+ }
+
+ public static List getAvailableFormats(final QuestController quest) {
+
+ final List allowedQuestSets = getAllowedSets(quest);
+ final List possibleFormats = new ArrayList<>();
+ final List blocks = getBlocks();
+
+ List singleSets = new ArrayList<>();
+ if (!allowedQuestSets.isEmpty()) {
for (final CardBlock block : blocks) {
- boolean blockAllowed = true;
+ boolean blockAllowed = false;
+ boolean largeSetUnlocked = false;
+ int unlockedSets = 0;
final boolean allBlocksSanctioned = quest.getFormat().getAllowedSetCodes().isEmpty();
for (final CardEdition set : block.getSets()) {
if (!allowedQuestSets.contains(set) && !allBlocksSanctioned) {
- blockAllowed = false;
- break;
+ continue;
+ }
+ unlockedSets++;
+ if (set.isLargeSet()) {
+ largeSetUnlocked = true;
}
}
+ //Allow partially unlocked blocks if they contain at least one large and one small unlocked set.
+ if (largeSetUnlocked && unlockedSets > 1) {
+ blockAllowed = true;
+ }
+
+ if (largeSetUnlocked && block.getSets().size() == 1) {
+ blockAllowed = true;
+ singleSets.add(block.getSets().get(0).getCode());
+ }
+
if (blockAllowed) {
- possibleBlocks.add(block);
+ possibleFormats.add(new QuestDraftFormat(block));
}
}
+
+ for (CardEdition allowedQuestSet : allowedQuestSets) {
+ if (allowedQuestSet.isLargeSet() && !singleSets.contains(allowedQuestSet.getCode())) {
+ possibleFormats.add(new QuestDraftFormat(allowedQuestSet));
+ }
+ }
+
} else {
- possibleBlocks.addAll(blocks);
+ for (CardBlock block : blocks) {
+ possibleFormats.add(new QuestDraftFormat(block));
+ if (block.getSets().size() > 1) {
+ for (CardEdition edition : block.getSets()) {
+ if (edition.isLargeSet()) {
+ possibleFormats.add(new QuestDraftFormat(edition));
+ }
+ }
+ }
+ }
}
- return possibleBlocks.isEmpty() ? null : possibleBlocks;
+ Collections.sort(possibleFormats);
+ return possibleFormats;
}
@@ -741,41 +821,42 @@ public class QuestEventDraft {
*/
public static QuestEventDraft getRandomDraftOrNull(final QuestController quest) {
- final List possibleBlocks = getAvailableBlocks(quest);
+ final List possibleFormats = getAvailableFormats(quest);
- if (possibleBlocks == null) {
+ if (possibleFormats.isEmpty()) {
return null;
}
- Collections.shuffle(possibleBlocks);
- return getDraftOrNull(quest, possibleBlocks.get(0));
+ Collections.shuffle(possibleFormats);
+ return getDraftOrNull(quest, possibleFormats.get(0));
}
/**
- * Generates a draft event based on the provided block.
+ * Generates a draft event based on the provided format.
* @return The created draft or null in the event no draft could be created.
*/
- public static QuestEventDraft getDraftOrNull(final QuestController quest, final CardBlock block) {
+ public static QuestEventDraft getDraftOrNull(final QuestController quest, final QuestDraftFormat format) {
- final QuestEventDraft event = new QuestEventDraft(block.getName());
+ final QuestEventDraft event = new QuestEventDraft(format.getName());
- if (block.getNumberSets() == 1) {
+ if (format.isSet()) {
+ CardEdition edition = format.edition;
String boosterConfiguration = "";
- for (int i = 0; i < block.getCntBoostersDraft(); i++) {
- boosterConfiguration += block.getSets().get(0).getCode();
- if (i != block.getCntBoostersDraft() - 1) {
+ for (int i = 0; i < 3; i++) {
+ boosterConfiguration += edition.getCode();
+ if (i != 2) {
boosterConfiguration += "/";
}
event.boosterConfiguration = boosterConfiguration;
}
} else {
- final List possibleSetCombinations = getSetCombos(block);
+ final List possibleSetCombinations = new ArrayList<>(getSetCombos(quest, format.block));
Collections.shuffle(possibleSetCombinations);
event.boosterConfiguration = possibleSetCombinations.get(0);
}
- event.block = block.getName();
+ event.block = format.getName();
event.entryFee = calculateEntryFee(event.boosterConfiguration.split("/"));
final List players = new ArrayList<>();
@@ -850,57 +931,76 @@ public class QuestEventDraft {
}
- private static List getSetCombos(final CardBlock block) {
- final List result = new ArrayList<>();
+ private static Set getSetCombos(final QuestController quest, final CardBlock block) {
+ final Set possibleCombinations = new LinkedHashSet<>();
final List sets = block.getSets();
+
final String s0c = sets.get(0).getCode();
if (sets.size() == 1) {
- result.add(String.format("%s/%s/%s", s0c, s0c, s0c));
- return result;
+ int numBoosters = block.getCntBoostersDraft();
+ String combination = "";
+ for (int i = 0; i < numBoosters; i++) {
+ combination += s0c;
+ if (i < numBoosters - 1) {
+ combination += "/";
+ }
+ }
+ possibleCombinations.add(combination);
+ return possibleCombinations;
}
- final String s1c = sets.get(1).getCode();
- final String s2c = sets.size() > 2 ? sets.get(2).getCode() : null;
-
- final boolean s0isLarge = sets.get(0).getCards().length > 200;
- final boolean s1isLarge = sets.get(1).getCards().length > 200;
-
- final String largerSet = s0isLarge == s1isLarge ? null : s0isLarge ? s0c : s1c;
-
- if (s2c == null) {
- if (largerSet != null ) {
- result.add(String.format("%s/%s/%s", s0c, largerSet, s1c));
- } else {
- result.add(String.format("%s/%s/%s", s1c, s1c, s1c));
- result.add(String.format("%s/%s/%s", s0c, s1c, s1c));
- result.add(String.format("%s/%s/%s", s0c, s0c, s1c));
- result.add(String.format("%s/%s/%s", s0c, s0c, s0c));
- }
+ List allowedSets;
+ if (quest.getFormat() == null) {
+ allowedSets = new ArrayList<>(sets);
} else {
- result.add(String.format("%s/%s/%s", s0c, s0c, s0c));
- result.add(String.format("%s/%s/%s", s0c, s1c, s2c));
+ allowedSets = getAllowedSets(quest);
+ allowedSets.retainAll(sets);
+ }
- // allow separate drafts with 3rd large set (ex: ROE, AVR)
- if( sets.get(2).getCards().length > 200) {
- result.add(String.format("%s/%s/%s", s2c, s2c, s2c));
+ final boolean oldSetsFirst = sets.get(0).getDate().before(FModel.getMagicDb().getEditions().get("SOM").getDate());
+ Collections.sort(allowedSets, new Comparator() {
+ @Override
+ public int compare(final CardEdition edition1, final CardEdition edition2) {
+ if (edition1.getDate().before(edition2.getDate())) {
+ return oldSetsFirst ? -1 : 1;
+ } else if (edition1.getDate().after(edition2.getDate())) {
+ return oldSetsFirst ? 1 : -1;
+ }
+ return 0;
+ }
+ });
+
+ boolean largeSetFound = false;
+ for (CardEdition allowedSet : allowedSets) {
+ if (allowedSet.isLargeSet()) {
+ largeSetFound = true;
+ break;
}
}
- // This is set to Scars of Mirrodin date to account for the fact that MBS is drafted as a part of the Scars of Mirrodin block.
- // Setting it to the date of Mirrodin Besieged makes it treat all drafts that feature Scars of Mirrodin incorrectly.
- final Date SOMDate = FModel.getMagicDb().getEditions().get("SOM").getDate();
- final boolean openOlderPacksFirst = sets.get(0).getDate().before(SOMDate); // before Mirrodin Besieged, sets were drafted in the opposite order (old->new instead of new->old)
+ if (!largeSetFound) {
+ throw new IllegalStateException(allowedSets + " does not contain a large set for quest draft generation.");
+ }
- if( !openOlderPacksFirst ){
- for(int i = result.size() - 1; i >= 0; i--) {
- final List parts = Arrays.asList(TextUtil.split(result.get(i), '/'));
- Collections.reverse(parts);
- result.set(i, TextUtil.join(parts, "/"));
+ if (allowedSets.containsAll(sets)) {
+ CardEdition set0 = allowedSets.get(0);
+ CardEdition set1 = allowedSets.get(1);
+ if (allowedSets.size() == 2) {
+ if (set0.isLargeSet()) {
+ possibleCombinations.add(String.format("%s/%s/%s", set0.getCode(), set0.getCode(), set1.getCode()));
+ } else {
+ possibleCombinations.add(String.format("%s/%s/%s", set0.getCode(), set1.getCode(), set1.getCode()));
+ }
+ }
+ if (allowedSets.size() == 3) {
+ CardEdition set2 = allowedSets.get(2);
+ possibleCombinations.add(String.format("%s/%s/%s", set0.getCode(), set1.getCode(), set2.getCode()));
}
}
- return result;
+ return possibleCombinations;
+
}
}
diff --git a/forge-gui/src/main/java/forge/quest/data/QuestAchievements.java b/forge-gui/src/main/java/forge/quest/data/QuestAchievements.java
index d6e741492eb..572a3c49880 100644
--- a/forge-gui/src/main/java/forge/quest/data/QuestAchievements.java
+++ b/forge-gui/src/main/java/forge/quest/data/QuestAchievements.java
@@ -1,8 +1,8 @@
package forge.quest.data;
-import forge.model.CardBlock;
import forge.model.FModel;
import forge.quest.QuestEventDraft;
+import forge.quest.QuestEventDraft.QuestDraftFormat;
import forge.quest.data.QuestPreferences.DifficultyPrefs;
import forge.quest.data.QuestPreferences.QPref;
@@ -11,7 +11,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
-/**
+/**
* TODO: Write javadoc for this type.
*
*/
@@ -23,7 +23,7 @@ public class QuestAchievements {
private List completedChallenges = new ArrayList<>();
private List currentChallenges = new ArrayList<>();
-
+
private QuestEventDraftContainer drafts = new QuestEventDraftContainer();
private int currentDraft = -1;
private int draftsToGenerate = 1;
@@ -33,17 +33,17 @@ public class QuestAchievements {
private int winstreakBest = 0;
private int winstreakCurrent = 0;
private int lost;
-
+
private int firstPlaceDraftFinishes = 0;
private int secondPlaceDraftFinishes = 0;
private int thirdPlaceDraftFinishes = 0;
private int fourthPlaceDraftFinishes = 0;
-
+
// Difficulty - will store only index from now.
private int difficulty;
-
- private transient CardBlock nextDraftBlock;
-
+
+ private transient QuestDraftFormat nextDraftFormat;
+
public QuestAchievements() { //needed for XML serialization
}
@@ -54,14 +54,14 @@ public class QuestAchievements {
public QuestAchievements(int diff) {
difficulty = diff;
}
-
+
public void deleteDraft(QuestEventDraft draft) {
if (currentDraft == drafts.indexOf(draft)) {
currentDraft = -1;
}
drafts.remove(draft);
}
-
+
public void endCurrentTournament(final int place) {
drafts.remove(drafts.get(currentDraft));
currentDraft = -1;
@@ -77,7 +77,7 @@ public class QuestAchievements {
* Adds the win.
*/
public void addWin() { // changes getRank()
-
+
win++;
winstreakCurrent++;
@@ -92,17 +92,17 @@ public class QuestAchievements {
if (win % FModel.getQuestPreferences().getPrefInt(QPref.WINS_NEW_DRAFT) == 0) {
draftsToGenerate++;
}
-
+
if (winstreakCurrent > winstreakBest) {
winstreakBest = winstreakCurrent;
}
-
+
}
// Challenge performance
/**
* Gets the challenges played.
- *
+ *
* @return the challenges played
*/
public int getChallengesPlayed() {
@@ -118,7 +118,7 @@ public class QuestAchievements {
/**
* Returns stored list of non-repeatable challenge IDs.
- *
+ *
* @return List
*/
public List getLockedChallenges() {
@@ -130,7 +130,7 @@ public class QuestAchievements {
* addCompletedChallenge.
*
* Add non-repeatable challenge ID to list.
- *
+ *
* @param i
* the i
*/
@@ -140,7 +140,7 @@ public class QuestAchievements {
/**
* Stores a list of current challenges.
- *
+ *
* @return List
*/
public List getCurrentChallenges() {
@@ -153,7 +153,7 @@ public class QuestAchievements {
/**
* Returns the stored list of current challenges.
- *
+ *
* @param lst0 List
*/
public void setCurrentChallenges(final List lst0) {
@@ -171,7 +171,7 @@ public class QuestAchievements {
// Level, read-only ( note: it increments in addWin() )
/**
* Gets the level.
- *
+ *
* @return the level
*/
public int getLevel() {
@@ -182,7 +182,7 @@ public class QuestAchievements {
// Wins & Losses
/**
* Gets the lost.
- *
+ *
* @return the lost
*/
public int getLost() {
@@ -191,7 +191,7 @@ public class QuestAchievements {
/**
* Gets the win.
- *
+ *
* @return the win
*/
public int getWin() {
@@ -218,7 +218,7 @@ public class QuestAchievements {
/**
* Gets the difficulty index.
- *
+ *
* @return the difficulty index
*/
public int getDifficulty() {
@@ -230,7 +230,7 @@ public class QuestAchievements {
}
public void generateDrafts() {
-
+
if (drafts == null) {
drafts = new QuestEventDraftContainer();
draftsToGenerate = 1;
@@ -251,9 +251,9 @@ public class QuestAchievements {
for (int i = 0; i < draftsToGenerate; i++) {
QuestEventDraft draft;
- if (nextDraftBlock != null) {
- draft = QuestEventDraft.getDraftOrNull(FModel.getQuest(), nextDraftBlock);
- nextDraftBlock = null;
+ if (nextDraftFormat != null) {
+ draft = QuestEventDraft.getDraftOrNull(FModel.getQuest(), nextDraftFormat);
+ nextDraftFormat = null;
} else {
draft = QuestEventDraft.getRandomDraftOrNull(FModel.getQuest());
}
@@ -264,7 +264,7 @@ public class QuestAchievements {
}
FModel.getQuest().save();
-
+
}
public void addDraftToken() {
@@ -276,7 +276,7 @@ public class QuestAchievements {
}
public QuestEventDraft getCurrentDraft() {
- if (drafts == null || drafts.size() == 0) {
+ if (drafts == null || drafts.isEmpty()) {
return null;
}
if (currentDraft > drafts.size() - 1) {
@@ -286,11 +286,11 @@ public class QuestAchievements {
}
return drafts.get(currentDraft);
}
-
+
public int getCurrentDraftIndex() {
return currentDraft;
}
-
+
public int getWinsForPlace(final int place) {
switch (place) {
case 1:
@@ -302,7 +302,7 @@ public class QuestAchievements {
case 4:
return fourthPlaceDraftFinishes;
}
-
+
return 0;
}
@@ -327,13 +327,13 @@ public class QuestAchievements {
return draftTokens;
}
- public void spendDraftToken(final CardBlock block) {
+ public void spendDraftToken(final QuestDraftFormat format) {
if (draftTokens > 0) {
draftTokens--;
draftsToGenerate++;
- nextDraftBlock = block;
+ nextDraftFormat = format;
generateDrafts();
}
}
-
+
}
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 5d798eec49e..4cb53d44120 100644
--- a/forge-gui/src/main/java/forge/quest/data/QuestPreferences.java
+++ b/forge-gui/src/main/java/forge/quest/data/QuestPreferences.java
@@ -275,12 +275,6 @@ public class QuestPreferences extends PreferencesStore i
}
break;
- case PLAYSET_BASIC_LAND_SIZE:
- if (val < 10) {
- return "Value too small (minimum 10).";
- }
- break;
-
case SHOP_MAX_PACKS:
case SHOP_MAX_SELLING_PRICE:
case SHOP_WINS_FOR_ADDITIONAL_PACK:
@@ -298,6 +292,7 @@ public class QuestPreferences extends PreferencesStore i
case BOOSTER_COMMONS:
case BOOSTER_UNCOMMONS:
case BOOSTER_RARES:
+ case PLAYSET_BASIC_LAND_SIZE:
case STARTING_CREDITS_EASY:
case STARTING_CREDITS_MEDIUM:
case STARTING_CREDITS_HARD: