mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Fixed bugs and improved set selection for quest drafts.
This commit is contained in:
@@ -213,6 +213,10 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
|
||||
return whiteBorder;
|
||||
}
|
||||
|
||||
public boolean isLargeSet() {
|
||||
return cards.length > 200;
|
||||
}
|
||||
|
||||
public int getCntBoosterPictures() {
|
||||
return boosterArts;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,6 @@
|
||||
package forge.screens.home.quest;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JRadioButton;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.Singletons;
|
||||
import forge.UiCommand;
|
||||
@@ -32,11 +18,11 @@ import forge.item.BoosterPack;
|
||||
import forge.item.PaperCard;
|
||||
import forge.itemmanager.DeckManager;
|
||||
import forge.limited.BoosterDraft;
|
||||
import forge.model.CardBlock;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.quest.QuestDraftUtils;
|
||||
import forge.quest.QuestEventDraft;
|
||||
import forge.quest.QuestEventDraft.QuestDraftFormat;
|
||||
import forge.quest.QuestUtil;
|
||||
import forge.quest.data.QuestAchievements;
|
||||
import forge.screens.deckeditor.CDeckEditorUI;
|
||||
@@ -51,6 +37,12 @@ import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinImage;
|
||||
import forge.toolbox.JXButtonPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.*;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Controls the quest draft submenu in the home UI.
|
||||
*
|
||||
@@ -184,7 +176,7 @@ public enum CSubmenuQuestDraft implements ICDoc {
|
||||
final int totalPacks = prizes.boosterPacks.size();
|
||||
int currentPack = 0;
|
||||
|
||||
while (prizes.boosterPacks.size() > 0) {
|
||||
while (!prizes.boosterPacks.isEmpty()) {
|
||||
|
||||
final BoosterPack pack = prizes.boosterPacks.remove(0);
|
||||
currentPack++;
|
||||
@@ -211,7 +203,7 @@ public enum CSubmenuQuestDraft implements ICDoc {
|
||||
|
||||
final List<PaperCard> cards = new ArrayList<>();
|
||||
|
||||
while (prizes.boosterPacks.size() > 0) {
|
||||
while (!prizes.boosterPacks.isEmpty()) {
|
||||
final BoosterPack pack = prizes.boosterPacks.remove(0);
|
||||
cards.addAll(pack.getCards());
|
||||
}
|
||||
@@ -306,11 +298,21 @@ public enum CSubmenuQuestDraft implements ICDoc {
|
||||
|
||||
if (achievements != null) {
|
||||
|
||||
final CardBlock block = GuiChoose.oneOrNone("Choose Draft Format", QuestEventDraft.getAvailableBlocks(FModel.getQuest()));
|
||||
List<QuestDraftFormat> formats = QuestEventDraft.getAvailableFormats(FModel.getQuest());
|
||||
|
||||
if (block != null) {
|
||||
if (formats.isEmpty()) {
|
||||
FOptionPane.showErrorDialog(
|
||||
"You do not have any draft-able sets unlocked!\n" +
|
||||
"Come back later when you've unlocked more sets.",
|
||||
"No Available Drafts");
|
||||
return;
|
||||
}
|
||||
|
||||
achievements.spendDraftToken(block);
|
||||
final QuestDraftFormat format = GuiChoose.oneOrNone("Choose Draft Format", formats);
|
||||
|
||||
if (format != null) {
|
||||
|
||||
achievements.spendDraftToken(format);
|
||||
|
||||
update();
|
||||
VSubmenuQuestDraft.SINGLETON_INSTANCE.populate();
|
||||
@@ -516,6 +518,8 @@ public enum CSubmenuQuestDraft implements ICDoc {
|
||||
private void startDraft() {
|
||||
|
||||
if (drafting) {
|
||||
FOptionPane.showErrorDialog("You are currently in a draft.\n" +
|
||||
"You should leave or finish that draft before starting another.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -575,6 +579,12 @@ public enum CSubmenuQuestDraft implements ICDoc {
|
||||
return;
|
||||
}
|
||||
|
||||
if (QuestDraftUtils.matchInProgress) {
|
||||
FOptionPane.showErrorDialog("There is already a match in progress.\n" +
|
||||
"Please wait for the current round to end before attempting to continue.");
|
||||
return;
|
||||
}
|
||||
|
||||
gui = GuiBase.getInterface().getNewGuiGame();
|
||||
QuestDraftUtils.startNextMatch(gui);
|
||||
|
||||
|
||||
@@ -16,13 +16,10 @@
|
||||
*/
|
||||
package forge.screens.match;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.game.GameView;
|
||||
import forge.game.player.PlayerView;
|
||||
import forge.match.NextGameDecision;
|
||||
import forge.model.FModel;
|
||||
import forge.quest.QuestController;
|
||||
@@ -32,6 +29,9 @@ import forge.screens.home.quest.VSubmenuQuestDraft;
|
||||
import forge.toolbox.FOptionPane;
|
||||
import forge.toolbox.FSkin;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* QuestWinLose.
|
||||
@@ -46,9 +46,6 @@ public class QuestDraftWinLose extends ControlWinLose {
|
||||
|
||||
/**
|
||||
* Instantiates a new quest win lose handler.
|
||||
*
|
||||
* @param view0 ViewWinLose object
|
||||
* @param match2
|
||||
*/
|
||||
public QuestDraftWinLose(final ViewWinLose view0, final GameView game0, final CMatchUI matchUI) {
|
||||
super(view0, game0, matchUI);
|
||||
@@ -71,7 +68,6 @@ public class QuestDraftWinLose extends ControlWinLose {
|
||||
|
||||
if (lastGame.isMatchOver()) {
|
||||
final String winner = lastGame.getWinningPlayerName();
|
||||
|
||||
quest.getAchievements().getCurrentDraft().setWinner(winner);
|
||||
quest.save();
|
||||
}
|
||||
@@ -107,9 +103,29 @@ public class QuestDraftWinLose extends ControlWinLose {
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
if (warningString == null ||
|
||||
FOptionPane.showOptionDialog(warningString, warningCaption, FSkin.getImage(FSkinProp.ICO_WARNING).scale(2), ImmutableList.of("Yes", "No"), 1) == 0) {
|
||||
matchUI.getGameController().nextGameDecision(NextGameDecision.QUIT);
|
||||
QuestDraftUtils.matchInProgress = false;
|
||||
QuestDraftUtils.continueMatches(matchUI);
|
||||
if (warningString != null) {
|
||||
PlayerView humanPlayer = null;
|
||||
for (PlayerView playerView : matchUI.getLocalPlayers()) {
|
||||
humanPlayer = playerView;
|
||||
}
|
||||
for (PlayerView playerView : lastGame.getPlayers()) {
|
||||
if (humanPlayer == null) {
|
||||
throw new IllegalStateException("Forfeit tournament button was pressed in a match without human players.");
|
||||
}
|
||||
if (playerView != humanPlayer) {
|
||||
quest.getAchievements().getCurrentDraft().setWinner(playerView.getName());
|
||||
quest.save();
|
||||
CSubmenuQuestDraft.SINGLETON_INSTANCE.update();
|
||||
VSubmenuQuestDraft.SINGLETON_INSTANCE.populate();
|
||||
}
|
||||
}
|
||||
//The player is probably not interested in watching more AI matches.
|
||||
QuestDraftUtils.cancelFurtherMatches();
|
||||
} else {
|
||||
matchUI.getGameController().nextGameDecision(NextGameDecision.QUIT);
|
||||
QuestDraftUtils.matchInProgress = false;
|
||||
QuestDraftUtils.continueMatches(matchUI);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -37,7 +37,6 @@ public class QuestWinLose extends ControlWinLose {
|
||||
* Instantiates a new quest win lose handler.
|
||||
*
|
||||
* @param view0 ViewWinLose object
|
||||
* @param match2
|
||||
*/
|
||||
public QuestWinLose(final ViewWinLose view0, final GameView game0, final CMatchUI matchUI) {
|
||||
super(view0, game0, matchUI);
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package forge.quest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckGroup;
|
||||
@@ -17,14 +14,17 @@ import forge.player.GamePlayerUtil;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.util.storage.IStorage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class QuestDraftUtils {
|
||||
private static final List<DraftMatchup> matchups = new ArrayList<DraftMatchup>();
|
||||
private static final List<DraftMatchup> matchups = new ArrayList<>();
|
||||
|
||||
public static boolean matchInProgress = false;
|
||||
private static boolean waitForUserInput = false;
|
||||
|
||||
public static void completeDraft(final DeckGroup finishedDraft) {
|
||||
final List<Deck> aiDecks = new ArrayList<Deck>(finishedDraft.getAiDecks());
|
||||
final List<Deck> aiDecks = new ArrayList<>(finishedDraft.getAiDecks());
|
||||
finishedDraft.getAiDecks().clear();
|
||||
|
||||
for (int i = 0; i < aiDecks.size(); i++) {
|
||||
@@ -49,8 +49,40 @@ public class QuestDraftUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int getPreviousMatchup(final int position) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
case 1:
|
||||
return 0;
|
||||
case 2:
|
||||
case 3:
|
||||
return 2;
|
||||
case 4:
|
||||
case 5:
|
||||
return 4;
|
||||
case 6:
|
||||
case 7:
|
||||
return 6;
|
||||
case 8:
|
||||
return 0;
|
||||
case 9:
|
||||
return 2;
|
||||
case 10:
|
||||
return 4;
|
||||
case 11:
|
||||
return 6;
|
||||
case 12:
|
||||
return 8;
|
||||
case 13:
|
||||
return 10;
|
||||
case 14:
|
||||
return 12;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static void startNextMatch(final IGuiGame gui) {
|
||||
if (matchups.size() > 0) {
|
||||
if (!matchups.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -68,38 +100,69 @@ public class QuestDraftUtils {
|
||||
}
|
||||
}
|
||||
|
||||
switch (currentSet) {
|
||||
case 7:
|
||||
addMatchup(0, 1, draft);
|
||||
addMatchup(2, 3, draft);
|
||||
addMatchup(4, 5, draft);
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
case 8:
|
||||
addMatchup(2, 3, draft);
|
||||
addMatchup(4, 5, draft);
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
case 9:
|
||||
addMatchup(4, 5, draft);
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
case 10:
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
case 11:
|
||||
addMatchup(8, 9, draft);
|
||||
addMatchup(10, 11, draft);
|
||||
break;
|
||||
case 12:
|
||||
addMatchup(10, 11, draft);
|
||||
break;
|
||||
case 13:
|
||||
addMatchup(12, 13, draft);
|
||||
break;
|
||||
case 14:
|
||||
default:
|
||||
return;
|
||||
int latestSet = currentSet;
|
||||
//Choose the start of each matchup; it's always even (0v1 2v3 4v5)
|
||||
if (latestSet % 2 == 1) {
|
||||
latestSet--;
|
||||
}
|
||||
|
||||
//Fill in any missing spots in previous brackets
|
||||
boolean foundMatchups = false;
|
||||
for (int i = 0; i <= latestSet && i <= 14; i += 2) {
|
||||
if (currentStandings[i].equals(QuestEventDraft.UNDETERMINED) && !currentStandings[i + 1].equals(QuestEventDraft.UNDETERMINED)) {
|
||||
int previousMatchup = getPreviousMatchup(i);
|
||||
addMatchup(previousMatchup, previousMatchup + 1, draft);
|
||||
foundMatchups = true;
|
||||
} else if (!currentStandings[i].equals(QuestEventDraft.UNDETERMINED) && currentStandings[i + 1].equals(QuestEventDraft.UNDETERMINED)) {
|
||||
int previousMatchup = getPreviousMatchup(i + 1);
|
||||
addMatchup(previousMatchup, previousMatchup + 1, draft);
|
||||
foundMatchups = true;
|
||||
} else if (currentStandings[i].equals(QuestEventDraft.UNDETERMINED) && currentStandings[i + 1].equals(QuestEventDraft.UNDETERMINED)) {
|
||||
int previousMatchup = getPreviousMatchup(i);
|
||||
addMatchup(previousMatchup, previousMatchup + 1, draft);
|
||||
if (i >= 8) {
|
||||
previousMatchup = getPreviousMatchup(i + 1);
|
||||
addMatchup(previousMatchup, previousMatchup + 1, draft);
|
||||
}
|
||||
foundMatchups = true;
|
||||
}
|
||||
}
|
||||
|
||||
//If no previous matches need doing, start the next round as normal
|
||||
if (!foundMatchups) {
|
||||
switch (currentSet) {
|
||||
case 7:
|
||||
addMatchup(0, 1, draft);
|
||||
addMatchup(2, 3, draft);
|
||||
addMatchup(4, 5, draft);
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
case 8:
|
||||
addMatchup(2, 3, draft);
|
||||
addMatchup(4, 5, draft);
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
case 9:
|
||||
addMatchup(4, 5, draft);
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
case 10:
|
||||
addMatchup(6, 7, draft);
|
||||
break;
|
||||
case 11:
|
||||
addMatchup(8, 9, draft);
|
||||
addMatchup(10, 11, draft);
|
||||
break;
|
||||
case 12:
|
||||
addMatchup(10, 11, draft);
|
||||
break;
|
||||
case 13:
|
||||
addMatchup(12, 13, draft);
|
||||
break;
|
||||
case 14:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
update(gui);
|
||||
@@ -128,8 +191,7 @@ public class QuestDraftUtils {
|
||||
|
||||
final int aiDeckIndex = Integer.parseInt(draft.getStandings()[aiIndex]) - 1;
|
||||
matchup.matchStarter.add(new RegisteredPlayer(decks.getAiDecks().get(aiDeckIndex)).setPlayer(GamePlayerUtil.createAiPlayer(draft.getAINames()[aiName], draft.getAIIcons()[aiName])));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
final int aiName1 = Integer.parseInt(draft.getStandings()[player1]) - 1;
|
||||
final int aiName2 = Integer.parseInt(draft.getStandings()[player2]) - 1;
|
||||
|
||||
@@ -180,8 +242,14 @@ public class QuestDraftUtils {
|
||||
update(gui);
|
||||
}
|
||||
|
||||
public static void cancelFurtherMatches() {
|
||||
matchInProgress = false;
|
||||
waitForUserInput = false;
|
||||
matchups.clear();
|
||||
}
|
||||
|
||||
private static final class DraftMatchup {
|
||||
private final List<RegisteredPlayer> matchStarter = new ArrayList<RegisteredPlayer>();
|
||||
private final List<RegisteredPlayer> matchStarter = new ArrayList<>();
|
||||
private RegisteredPlayer humanPlayer = null;
|
||||
private void setHumanPlayer(final RegisteredPlayer humanPlayer) {
|
||||
this.matchStarter.add(humanPlayer);
|
||||
|
||||
@@ -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.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 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<BoosterPack> 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<PaperCard> possibleCards = new ArrayList<>();
|
||||
@@ -682,14 +667,60 @@ public class QuestEventDraft {
|
||||
return title;
|
||||
}
|
||||
|
||||
public static List<CardBlock> getAvailableBlocks(final QuestController quest) {
|
||||
public static class QuestDraftFormat implements Comparable<QuestDraftFormat> {
|
||||
|
||||
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<CardEdition> 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<CardEdition> getAllowedSets(final QuestController quest) {
|
||||
|
||||
final List<CardBlock> possibleBlocks = new ArrayList<>();
|
||||
final List<CardEdition> allowedQuestSets = new ArrayList<>();
|
||||
|
||||
final boolean questUsesLimitedCardPool = quest.getFormat() != null;
|
||||
|
||||
if (questUsesLimitedCardPool) {
|
||||
if (quest.getFormat() != null) {
|
||||
|
||||
final List<String> allowedSetCodes = quest.getFormat().getAllowedSetCodes();
|
||||
|
||||
@@ -699,6 +730,12 @@ public class QuestEventDraft {
|
||||
|
||||
}
|
||||
|
||||
return allowedQuestSets;
|
||||
|
||||
}
|
||||
|
||||
private static List<CardBlock> getBlocks() {
|
||||
|
||||
final List<CardBlock> blocks = new ArrayList<>();
|
||||
final IStorage<CardBlock> storage = FModel.getBlocks();
|
||||
|
||||
@@ -708,29 +745,72 @@ public class QuestEventDraft {
|
||||
}
|
||||
}
|
||||
|
||||
if (questUsesLimitedCardPool) {
|
||||
return blocks;
|
||||
|
||||
}
|
||||
|
||||
public static List<QuestDraftFormat> getAvailableFormats(final QuestController quest) {
|
||||
|
||||
final List<CardEdition> allowedQuestSets = getAllowedSets(quest);
|
||||
final List<QuestDraftFormat> possibleFormats = new ArrayList<>();
|
||||
final List<CardBlock> blocks = getBlocks();
|
||||
|
||||
List<String> 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<CardBlock> possibleBlocks = getAvailableBlocks(quest);
|
||||
final List<QuestDraftFormat> 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<String> possibleSetCombinations = getSetCombos(block);
|
||||
final List<String> 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<String> players = new ArrayList<>();
|
||||
@@ -850,57 +931,76 @@ public class QuestEventDraft {
|
||||
|
||||
}
|
||||
|
||||
private static List<String> getSetCombos(final CardBlock block) {
|
||||
final List<String> result = new ArrayList<>();
|
||||
private static Set<String> getSetCombos(final QuestController quest, final CardBlock block) {
|
||||
|
||||
final Set<String> possibleCombinations = new LinkedHashSet<>();
|
||||
final List<CardEdition> 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<CardEdition> 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<CardEdition>() {
|
||||
@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<String> 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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -42,7 +42,7 @@ public class QuestAchievements {
|
||||
// Difficulty - will store only index from now.
|
||||
private int difficulty;
|
||||
|
||||
private transient CardBlock nextDraftBlock;
|
||||
private transient QuestDraftFormat nextDraftFormat;
|
||||
|
||||
public QuestAchievements() { //needed for XML serialization
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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) {
|
||||
@@ -327,11 +327,11 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,12 +275,6 @@ public class QuestPreferences extends PreferencesStore<QuestPreferences.QPref> 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<QuestPreferences.QPref> 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:
|
||||
|
||||
Reference in New Issue
Block a user