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);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -28,16 +28,15 @@ import forge.screens.home.quest.CSubmenuDuels;
|
||||
* Processes win/lose presentation for Quest events. This presentation is
|
||||
* displayed by WinLoseFrame. Components to be added to pnlCustom in
|
||||
* WinLoseFrame should use MigLayout.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class QuestWinLose extends ControlWinLose {
|
||||
private final QuestWinLoseController controller;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
@@ -51,7 +50,7 @@ public class QuestWinLose extends ControlWinLose {
|
||||
* </p>
|
||||
* Checks conditions of win and fires various reward display methods
|
||||
* accordingly.
|
||||
*
|
||||
*
|
||||
* @return true, if successful
|
||||
*/
|
||||
@Override
|
||||
@@ -66,7 +65,7 @@ public class QuestWinLose extends ControlWinLose {
|
||||
* </p>
|
||||
* When "quit" button is pressed, this method adjusts quest data as
|
||||
* appropriate and saves.
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public final void actionOnQuit() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<String> completedChallenges = new ArrayList<>();
|
||||
private List<String> 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<Integer>
|
||||
*/
|
||||
public List<String> getLockedChallenges() {
|
||||
@@ -130,7 +130,7 @@ public class QuestAchievements {
|
||||
* addCompletedChallenge.
|
||||
* </p>
|
||||
* 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<Integer>
|
||||
*/
|
||||
public List<String> getCurrentChallenges() {
|
||||
@@ -153,7 +153,7 @@ public class QuestAchievements {
|
||||
|
||||
/**
|
||||
* Returns the stored list of current challenges.
|
||||
*
|
||||
*
|
||||
* @param lst0 List<Integer>
|
||||
*/
|
||||
public void setCurrentChallenges(final List<String> 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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