mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
Refactor quest tournaments logic to make them easier to implement for Android
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -19626,6 +19626,7 @@ forge-gui/src/main/java/forge/properties/ForgePreferences.java svneol=native#tex
|
||||
forge-gui/src/main/java/forge/properties/package-info.java svneol=native#text/plain
|
||||
forge-gui/src/main/java/forge/quest/BoosterUtils.java svneol=native#text/plain
|
||||
forge-gui/src/main/java/forge/quest/IQuestRewardCard.java -text
|
||||
forge-gui/src/main/java/forge/quest/IQuestTournamentView.java -text
|
||||
forge-gui/src/main/java/forge/quest/IVQuestStats.java -text
|
||||
forge-gui/src/main/java/forge/quest/QuestController.java -text
|
||||
forge-gui/src/main/java/forge/quest/QuestDeckGroupMap.java -text
|
||||
@@ -19642,6 +19643,7 @@ forge-gui/src/main/java/forge/quest/QuestRewardCard.java -text
|
||||
forge-gui/src/main/java/forge/quest/QuestRewardCardDuplicate.java -text
|
||||
forge-gui/src/main/java/forge/quest/QuestRewardCardFiltered.java -text
|
||||
forge-gui/src/main/java/forge/quest/QuestSpellShop.java -text
|
||||
forge-gui/src/main/java/forge/quest/QuestTournamentController.java -text
|
||||
forge-gui/src/main/java/forge/quest/QuestUtil.java svneol=native#text/plain
|
||||
forge-gui/src/main/java/forge/quest/QuestUtilCards.java -text
|
||||
forge-gui/src/main/java/forge/quest/QuestUtilUnlockSets.java -text
|
||||
|
||||
@@ -27,6 +27,7 @@ import forge.download.GuiDownloadService;
|
||||
import forge.download.GuiDownloader;
|
||||
import forge.error.BugReportDialog;
|
||||
import forge.gui.BoxedProductCardListViewer;
|
||||
import forge.gui.CardListChooser;
|
||||
import forge.gui.CardListViewer;
|
||||
import forge.gui.GuiChoose;
|
||||
import forge.gui.framework.FScreen;
|
||||
@@ -182,6 +183,14 @@ public class GuiDesktop implements IGuiBase {
|
||||
return viewer.skipTheRest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaperCard chooseCard(String title, String message, List<PaperCard> list) {
|
||||
final CardListChooser cardListChooser = new CardListChooser(title, message, list);
|
||||
cardListChooser.setVisible(true);
|
||||
cardListChooser.dispose();
|
||||
return cardListChooser.getSelectedCard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvatarCount() {
|
||||
if (FSkin.isLoaded()) {
|
||||
|
||||
@@ -1,51 +1,11 @@
|
||||
package forge.screens.home.quest;
|
||||
|
||||
import com.beust.jcommander.internal.Lists;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import forge.GuiBase;
|
||||
import forge.Singletons;
|
||||
import forge.UiCommand;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.deck.DeckGroup;
|
||||
import forge.game.GameType;
|
||||
import forge.gui.BoxedProductCardListViewer;
|
||||
import forge.gui.CardListChooser;
|
||||
import forge.gui.CardListViewer;
|
||||
import forge.gui.GuiChoose;
|
||||
import forge.gui.framework.FScreen;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.interfaces.IGuiGame;
|
||||
import forge.item.BoosterPack;
|
||||
import forge.item.PaperCard;
|
||||
import forge.itemmanager.DeckManager;
|
||||
import forge.limited.BoosterDraft;
|
||||
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;
|
||||
import forge.screens.deckeditor.controllers.CEditorQuestDraftingProcess;
|
||||
import forge.screens.deckeditor.controllers.CEditorQuestLimited;
|
||||
import forge.screens.deckeditor.views.VCurrentDeck;
|
||||
import forge.screens.home.quest.VSubmenuQuestDraft.Mode;
|
||||
import forge.screens.home.sanctioned.CSubmenuDraft;
|
||||
import forge.screens.match.controllers.CDetailPicture;
|
||||
import forge.toolbox.FOptionPane;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinImage;
|
||||
import forge.toolbox.JXButtonPanel;
|
||||
import forge.tournament.system.TournamentBracket;
|
||||
import forge.tournament.system.TournamentPairing;
|
||||
import forge.tournament.system.TournamentPlayer;
|
||||
import forge.quest.QuestTournamentController;
|
||||
|
||||
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.
|
||||
@@ -56,10 +16,7 @@ import java.util.List;
|
||||
public enum CSubmenuQuestDraft implements ICDoc {
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
private static final DecimalFormat NUMBER_FORMATTER = new DecimalFormat("#,###");
|
||||
|
||||
private boolean drafting = false;
|
||||
private IGuiGame gui = null;
|
||||
private QuestTournamentController controller;
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
@@ -68,8 +25,8 @@ public enum CSubmenuQuestDraft implements ICDoc {
|
||||
@SuppressWarnings("serial")
|
||||
@Override
|
||||
public void initialize() {
|
||||
|
||||
final VSubmenuQuestDraft view = VSubmenuQuestDraft.SINGLETON_INSTANCE;
|
||||
controller = new QuestTournamentController(view);
|
||||
|
||||
view.getBtnStartDraft().addActionListener(selectTournamentStart);
|
||||
view.getBtnStartTournament().addActionListener(prepareDeckStart);
|
||||
@@ -77,600 +34,53 @@ public enum CSubmenuQuestDraft implements ICDoc {
|
||||
|
||||
view.getBtnStartMatchSmall().setCommand(new UiCommand() {
|
||||
@Override public void run() {
|
||||
CSubmenuQuestDraft.this.startNextMatch();
|
||||
controller.startNextMatch();
|
||||
}
|
||||
});
|
||||
view.getBtnSpendToken().setCommand(new UiCommand() {
|
||||
@Override public void run() {
|
||||
CSubmenuQuestDraft.this.spendToken();
|
||||
controller.spendToken();
|
||||
}
|
||||
});
|
||||
view.getBtnEditDeck().setCommand(new UiCommand() {
|
||||
@Override public void run() {
|
||||
CSubmenuQuestDraft.this.editDeck();
|
||||
controller.editDeck();
|
||||
}
|
||||
});
|
||||
view.getBtnLeaveTournament().setCommand(new UiCommand() {
|
||||
@Override public void run() {
|
||||
CSubmenuQuestDraft.this.endTournamentAndAwardPrizes();
|
||||
controller.endTournamentAndAwardPrizes();
|
||||
}
|
||||
});
|
||||
|
||||
final QuestAchievements achievements = FModel.getQuest().getAchievements();
|
||||
FModel.getQuest().getDraftDecks();
|
||||
|
||||
if (achievements == null) {
|
||||
|
||||
view.setMode(Mode.EMPTY);
|
||||
|
||||
} else if (achievements.getDraftEvents() == null || achievements.getDraftEvents().isEmpty()) {
|
||||
|
||||
achievements.generateDrafts();
|
||||
|
||||
if (achievements.getDraftEvents().isEmpty()) {
|
||||
view.setMode(Mode.EMPTY);
|
||||
} else {
|
||||
view.setMode(Mode.SELECT_TOURNAMENT);
|
||||
}
|
||||
|
||||
} else if (FModel.getQuest().getDraftDecks() == null || !FModel.getQuest().getDraftDecks().contains(QuestEventDraft.DECK_NAME)) {
|
||||
|
||||
achievements.generateDrafts();
|
||||
view.setMode(Mode.SELECT_TOURNAMENT);
|
||||
|
||||
} else if (!achievements.getCurrentDraft().isStarted()) {
|
||||
|
||||
view.setMode(Mode.PREPARE_DECK);
|
||||
|
||||
} else {
|
||||
|
||||
view.setMode(Mode.TOURNAMENT_ACTIVE);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void endTournamentAndAwardPrizes() {
|
||||
final QuestEventDraft draft = FModel.getQuest().getAchievements().getCurrentDraft();
|
||||
|
||||
if (!draft.isStarted()) {
|
||||
|
||||
final boolean shouldQuit = FOptionPane.showOptionDialog("If you leave now, this tournament will be forever gone."
|
||||
+ "\nYou will keep the cards you drafted, but will receive no other prizes."
|
||||
+ "\n\nWould you still like to quit the tournament?", "Really Quit?", FSkin.getImage(FSkinProp.ICO_WARNING).scale(2.0), ImmutableList.of("Yes", "No"), 1) == 0;
|
||||
if (!shouldQuit) {
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (draft.playerHasMatchesLeft()) {
|
||||
final boolean shouldQuit = FOptionPane.showOptionDialog("You have matches left to play!\nLeaving the tournament early will forfeit your potential future winnings."
|
||||
+ "\nYou will still receive winnings as if you conceded your next match and you will keep the cards you drafted."
|
||||
+ "\n\nWould you still like to quit the tournament?", "Really Quit?", FSkin.getImage(FSkinProp.ICO_WARNING).scale(2.0), ImmutableList.of("Yes", "No"), 1) == 0;
|
||||
if (!shouldQuit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final String placement = draft.getPlacementString();
|
||||
|
||||
final QuestEventDraft.QuestDraftPrizes prizes = draft.collectPrizes();
|
||||
|
||||
if (prizes.hasCredits()) {
|
||||
FOptionPane.showMessageDialog("For placing " + placement + ", you have been awarded " + prizes.credits + " credits!", "Credits Awarded", FSkin.getImage(FSkinProp.ICO_QUEST_GOLD));
|
||||
}
|
||||
|
||||
if (prizes.hasIndividualCards()) {
|
||||
final CardListViewer c = new CardListViewer("Tournament Reward", "For participating in the tournament, you have been awarded the following promotional card:", prizes.individualCards);
|
||||
c.setVisible(true);
|
||||
c.dispose();
|
||||
}
|
||||
|
||||
if (prizes.hasBoosterPacks()) {
|
||||
|
||||
final String packPlural = (prizes.boosterPacks.size() == 1) ? "" : "s";
|
||||
|
||||
FOptionPane.showMessageDialog("For placing " + placement + ", you have been awarded " + prizes.boosterPacks.size() + " booster pack" + packPlural + "!", "Booster Pack" + packPlural + " Awarded", FSkin.getImage(FSkinProp.ICO_QUEST_BOX));
|
||||
|
||||
if (FModel.getPreferences().getPrefBoolean(FPref.UI_OPEN_PACKS_INDIV) && prizes.boosterPacks.size() > 1) {
|
||||
|
||||
boolean skipTheRest = false;
|
||||
final List<PaperCard> remainingCards = new ArrayList<>();
|
||||
final int totalPacks = prizes.boosterPacks.size();
|
||||
int currentPack = 0;
|
||||
|
||||
while (!prizes.boosterPacks.isEmpty()) {
|
||||
|
||||
final BoosterPack pack = prizes.boosterPacks.remove(0);
|
||||
currentPack++;
|
||||
|
||||
if (skipTheRest) {
|
||||
remainingCards.addAll(pack.getCards());
|
||||
continue;
|
||||
}
|
||||
|
||||
final BoxedProductCardListViewer c = new BoxedProductCardListViewer(pack.getName(), "You have found the following cards inside (Booster Pack " + currentPack + " of " + totalPacks + "):", pack.getCards());
|
||||
c.setVisible(true);
|
||||
c.dispose();
|
||||
skipTheRest = c.skipTheRest();
|
||||
|
||||
}
|
||||
|
||||
if (skipTheRest && !remainingCards.isEmpty()) {
|
||||
final CardListViewer c = new CardListViewer("Tournament Reward", "You have found the following cards inside:", remainingCards);
|
||||
c.setVisible(true);
|
||||
c.dispose();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
final List<PaperCard> cards = new ArrayList<>();
|
||||
|
||||
while (!prizes.boosterPacks.isEmpty()) {
|
||||
final BoosterPack pack = prizes.boosterPacks.remove(0);
|
||||
cards.addAll(pack.getCards());
|
||||
}
|
||||
|
||||
final CardListViewer c = new CardListViewer("Tournament Reward", "You have found the following cards inside:", cards);
|
||||
c.setVisible(true);
|
||||
c.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (prizes.selectRareFromSets()) {
|
||||
|
||||
FOptionPane.showMessageDialog("For placing " + placement + ", you may select a rare or mythic rare card from the drafted block.", "Rare Awarded", FSkin.getImage(FSkinProp.ICO_QUEST_STAKES));
|
||||
|
||||
final CardListChooser cardListChooser = new CardListChooser("Select a Card", "Select a card to keep:", prizes.selectRareCards);
|
||||
cardListChooser.setVisible(true);
|
||||
cardListChooser.dispose();
|
||||
prizes.addSelectedCard(cardListChooser.getSelectedCard());
|
||||
|
||||
FOptionPane.showMessageDialog("'" + cardListChooser.getSelectedCard().getName() + "' has been added to your collection!", "Card Added", FSkin.getImage(FSkinProp.ICO_QUEST_STAKES));
|
||||
|
||||
}
|
||||
|
||||
if (draft.getPlayerPlacement() == 1) {
|
||||
FOptionPane.showMessageDialog("For placing " + placement + ", you have been awarded a token!\nUse tokens to create new drafts to play.", "Bonus Token", FSkin.getImage(FSkinProp.ICO_QUEST_NOTES));
|
||||
FModel.getQuest().getAchievements().addDraftToken();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
final boolean saveDraft = FOptionPane.showOptionDialog("Would you like to save this draft to the regular draft mode?", "Save Draft?", FSkin.getImage(FSkinProp.ICO_QUESTION).scale(2.0), ImmutableList.of("Yes", "No"), 0) == 0;
|
||||
|
||||
if (saveDraft) {
|
||||
draft.saveToRegularDraft();
|
||||
CSubmenuDraft.SINGLETON_INSTANCE.update();
|
||||
}
|
||||
|
||||
draft.addToQuestDecks();
|
||||
|
||||
final VSubmenuQuestDraft view = VSubmenuQuestDraft.SINGLETON_INSTANCE;
|
||||
CSubmenuQuestDraft.SINGLETON_INSTANCE.update();
|
||||
view.populate();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private final ActionListener selectTournamentStart = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
CSubmenuQuestDraft.this.startDraft();
|
||||
controller.startDraft();
|
||||
}
|
||||
};
|
||||
|
||||
private final ActionListener prepareDeckStart = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
CSubmenuQuestDraft.this.startTournament();
|
||||
controller.startTournament();
|
||||
}
|
||||
};
|
||||
|
||||
private final ActionListener nextMatchStart = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
CSubmenuQuestDraft.this.startNextMatch();
|
||||
controller.startNextMatch();
|
||||
}
|
||||
};
|
||||
|
||||
private final KeyAdapter startOnEnter = new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(final KeyEvent e) {
|
||||
if (KeyEvent.VK_ENTER == e.getKeyChar()) {
|
||||
VSubmenuQuestDraft.SINGLETON_INSTANCE.getBtnStartDraft().doClick();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final MouseAdapter startOnDblClick = new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(final MouseEvent e) {
|
||||
if (MouseEvent.BUTTON1 == e.getButton() && 2 == e.getClickCount()) {
|
||||
VSubmenuQuestDraft.SINGLETON_INSTANCE.getBtnStartDraft().doClick();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void spendToken() {
|
||||
|
||||
final QuestAchievements achievements = FModel.getQuest().getAchievements();
|
||||
|
||||
if (achievements != null) {
|
||||
|
||||
List<QuestDraftFormat> formats = QuestEventDraft.getAvailableFormats(FModel.getQuest());
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
final QuestDraftFormat format = GuiChoose.oneOrNone("Choose Draft Format", formats);
|
||||
|
||||
if (format != null) {
|
||||
|
||||
achievements.spendDraftToken(format);
|
||||
|
||||
update();
|
||||
VSubmenuQuestDraft.SINGLETON_INSTANCE.populate();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
|
||||
final VSubmenuQuestDraft view = VSubmenuQuestDraft.SINGLETON_INSTANCE;
|
||||
|
||||
if (FModel.getQuest().getAchievements() == null) {
|
||||
view.setMode(Mode.EMPTY);
|
||||
return;
|
||||
}
|
||||
|
||||
final QuestAchievements achievements = FModel.getQuest().getAchievements();
|
||||
achievements.generateDrafts();
|
||||
|
||||
if (FModel.getQuest().getAchievements().getDraftEvents().isEmpty()) {
|
||||
view.setMode(Mode.EMPTY);
|
||||
updatePlacementLabelsText();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((FModel.getQuest().getDraftDecks() == null
|
||||
|| !FModel.getQuest().getDraftDecks().contains(QuestEventDraft.DECK_NAME)
|
||||
|| FModel.getQuest().getAchievements().getCurrentDraftIndex() == -1)) {
|
||||
view.setMode(Mode.SELECT_TOURNAMENT);
|
||||
} else if (!FModel.getQuest().getAchievements().getCurrentDraft().isStarted()) {
|
||||
view.setMode(Mode.PREPARE_DECK);
|
||||
} else {
|
||||
view.setMode(Mode.TOURNAMENT_ACTIVE);
|
||||
}
|
||||
|
||||
QuestDraftUtils.update(gui);
|
||||
|
||||
switch (view.getMode()) {
|
||||
|
||||
case SELECT_TOURNAMENT:
|
||||
updateSelectTournament();
|
||||
break;
|
||||
|
||||
case PREPARE_DECK:
|
||||
updatePrepareDeck();
|
||||
break;
|
||||
|
||||
case TOURNAMENT_ACTIVE:
|
||||
updateTournamentActive();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateSelectTournament() {
|
||||
|
||||
final VSubmenuQuestDraft view = VSubmenuQuestDraft.SINGLETON_INSTANCE;
|
||||
|
||||
view.getLblCredits().setText("Available Credits: " + NUMBER_FORMATTER.format(FModel.getQuest().getAssets().getCredits()));
|
||||
|
||||
final QuestAchievements achievements = FModel.getQuest().getAchievements();
|
||||
achievements.generateDrafts();
|
||||
|
||||
view.getPnlTournaments().removeAll();
|
||||
final JXButtonPanel grpPanel = new JXButtonPanel();
|
||||
|
||||
boolean firstPanel = true;
|
||||
|
||||
for (final QuestEventDraft draft : FModel.getQuest().getAchievements().getDraftEvents()) {
|
||||
|
||||
final PnlDraftEvent draftPanel = new PnlDraftEvent(draft);
|
||||
final JRadioButton button = draftPanel.getRadioButton();
|
||||
|
||||
if (firstPanel) {
|
||||
button.setSelected(true);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override public void run() { button.requestFocusInWindow(); }
|
||||
});
|
||||
firstPanel = false;
|
||||
}
|
||||
|
||||
grpPanel.add(draftPanel, button, "w 100%!, h 135px!, gapy 15px");
|
||||
|
||||
button.addKeyListener(startOnEnter);
|
||||
button.addMouseListener(startOnDblClick);
|
||||
|
||||
}
|
||||
|
||||
view.getPnlTournaments().add(grpPanel, "w 100%!");
|
||||
|
||||
updatePlacementLabelsText();
|
||||
|
||||
}
|
||||
|
||||
private void updatePlacementLabelsText() {
|
||||
|
||||
final VSubmenuQuestDraft view = VSubmenuQuestDraft.SINGLETON_INSTANCE;
|
||||
final QuestAchievements achievements = FModel.getQuest().getAchievements();
|
||||
|
||||
if (view.getMode().equals(Mode.EMPTY)) {
|
||||
view.getPnlTournaments().removeAll();
|
||||
}
|
||||
|
||||
view.getLblFirst().setText("1st Place: " + achievements.getWinsForPlace(1) + " time" + (achievements.getWinsForPlace(1) == 1 ? "" : "s"));
|
||||
view.getLblSecond().setText("2nd Place: " + achievements.getWinsForPlace(2) + " time" + (achievements.getWinsForPlace(2) == 1 ? "" : "s"));
|
||||
view.getLblThird().setText("3rd Place: " + achievements.getWinsForPlace(3) + " time" + (achievements.getWinsForPlace(3) == 1 ? "" : "s"));
|
||||
view.getLblFourth().setText("4th Place: " + achievements.getWinsForPlace(4) + " time" + (achievements.getWinsForPlace(4) == 1 ? "" : "s"));
|
||||
|
||||
view.getLblTokens().setText("Tokens: " + achievements.getDraftTokens());
|
||||
view.getBtnSpendToken().setEnabled(achievements.getDraftTokens() > 0);
|
||||
|
||||
}
|
||||
|
||||
private void updatePrepareDeck() {
|
||||
}
|
||||
|
||||
private void updateTournamentActive() {
|
||||
if (FModel.getQuest().getAchievements().getCurrentDraft() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (QuestDraftUtils.TOURNAMENT_TOGGLE) {
|
||||
updateTournamentActiveForBracket();
|
||||
return;
|
||||
}
|
||||
|
||||
final VSubmenuQuestDraft view = VSubmenuQuestDraft.SINGLETON_INSTANCE;
|
||||
|
||||
for (int i = 0; i < 15; i++) {
|
||||
|
||||
String playerID = FModel.getQuest().getAchievements().getCurrentDraft().getStandings()[i];
|
||||
|
||||
int iconID = 0;
|
||||
|
||||
switch (playerID) {
|
||||
case QuestEventDraft.HUMAN:
|
||||
playerID = FModel.getPreferences().getPref(FPref.PLAYER_NAME);
|
||||
if (FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",").length > 0) {
|
||||
iconID = Integer.parseInt(FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",")[0]);
|
||||
}
|
||||
break;
|
||||
case QuestEventDraft.UNDETERMINED:
|
||||
playerID = "Undetermined";
|
||||
iconID = GuiBase.getInterface().getAvatarCount() - 1;
|
||||
break;
|
||||
default:
|
||||
iconID = FModel.getQuest().getAchievements().getCurrentDraft().getAIIcons()[Integer.parseInt(playerID) - 1];
|
||||
playerID = FModel.getQuest().getAchievements().getCurrentDraft().getAINames()[Integer.parseInt(playerID) - 1];
|
||||
break;
|
||||
}
|
||||
|
||||
final boolean first = i % 2 == 0;
|
||||
final int box = i / 2;
|
||||
|
||||
SkinImage icon = FSkin.getAvatars().get(iconID);
|
||||
|
||||
if (icon == null) {
|
||||
icon = FSkin.getAvatars().get(0);
|
||||
}
|
||||
|
||||
if (first) {
|
||||
view.getLblsMatchups()[box].setPlayerOne(playerID, icon);
|
||||
} else {
|
||||
view.getLblsMatchups()[box].setPlayerTwo(playerID, icon);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (FModel.getQuest().getAchievements().getCurrentDraft().playerHasMatchesLeft()) {
|
||||
view.getBtnLeaveTournament().setText("Leave Tournament");
|
||||
} else {
|
||||
view.getBtnLeaveTournament().setText("Collect Prizes");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateTournamentBoxLabel(String playerID, int iconID, int box, boolean first) {
|
||||
final VSubmenuQuestDraft view = VSubmenuQuestDraft.SINGLETON_INSTANCE;
|
||||
|
||||
SkinImage icon = FSkin.getAvatars().get(iconID);
|
||||
|
||||
if (icon == null) {
|
||||
icon = FSkin.getAvatars().get(0);
|
||||
}
|
||||
|
||||
if (first) {
|
||||
view.getLblsMatchups()[box].setPlayerOne(playerID, icon);
|
||||
} else {
|
||||
view.getLblsMatchups()[box].setPlayerTwo(playerID, icon);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTournamentActiveForBracket() {
|
||||
final VSubmenuQuestDraft view = VSubmenuQuestDraft.SINGLETON_INSTANCE;
|
||||
|
||||
QuestEventDraft draft = FModel.getQuest().getAchievements().getCurrentDraft();
|
||||
TournamentBracket bracket = draft.getBracket();
|
||||
|
||||
if (bracket == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Combine finished pairings with active round pairings
|
||||
List<TournamentPairing> allPairings = Lists.newArrayList();
|
||||
allPairings.addAll(bracket.getCompletedPairings());
|
||||
allPairings.addAll(bracket.getActivePairings());
|
||||
|
||||
int count = 0;
|
||||
int playerCount = 0;
|
||||
int lastWinner = 0;
|
||||
for(TournamentPairing tp : allPairings) {
|
||||
boolean first = true;
|
||||
String playerID = "Undetermined";
|
||||
int iconID = 0;
|
||||
for(TournamentPlayer player : tp.getPairedPlayers()) {
|
||||
if (player.getIndex() == -1) {
|
||||
playerID = FModel.getPreferences().getPref(FPref.PLAYER_NAME);
|
||||
if (FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",").length > 0) {
|
||||
iconID = Integer.parseInt(FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",")[0]);
|
||||
}
|
||||
}
|
||||
else{
|
||||
playerID = player.getPlayer().getName();
|
||||
iconID = player.getIndex();
|
||||
}
|
||||
updateTournamentBoxLabel(playerID, iconID, count, first);
|
||||
|
||||
if (tp.getWinner() != null && tp.getWinner().equals(player)) {
|
||||
// Temporarily fill in winner box
|
||||
lastWinner = playerCount;
|
||||
updateTournamentBoxLabel(player.getPlayer().getName(), player.getIndex(), playerCount/4 + 4, count%2 == 0);
|
||||
}
|
||||
first = false;
|
||||
playerCount++;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
if (!bracket.isTournamentOver()) {
|
||||
for (int i = lastWinner/2+9 ; i < 15; i++) {
|
||||
String playerID = "Undetermined";
|
||||
int iconID = GuiBase.getInterface().getAvatarCount() - 1;
|
||||
updateTournamentBoxLabel(playerID, iconID, i / 2, i%2 == 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (draft.playerHasMatchesLeft()) {
|
||||
view.getBtnLeaveTournament().setText("Leave Tournament");
|
||||
} else {
|
||||
view.getBtnLeaveTournament().setText("Collect Prizes");
|
||||
}
|
||||
controller.update();
|
||||
}
|
||||
|
||||
public void setCompletedDraft(final DeckGroup finishedDraft) {
|
||||
|
||||
QuestDraftUtils.completeDraft(finishedDraft);
|
||||
|
||||
Singletons.getControl().setCurrentScreen(FScreen.DECK_EDITOR_QUEST_TOURNAMENT);
|
||||
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(new CEditorQuestLimited(FModel.getQuest(), CDeckEditorUI.SINGLETON_INSTANCE.getCDetailPicture()));
|
||||
|
||||
drafting = false;
|
||||
|
||||
VSubmenuQuestDraft.SINGLETON_INSTANCE.setMode(Mode.PREPARE_DECK);
|
||||
VSubmenuQuestDraft.SINGLETON_INSTANCE.populate();
|
||||
|
||||
controller.setCompletedDraft(finishedDraft);
|
||||
}
|
||||
|
||||
private void editDeck() {
|
||||
final CDetailPicture cDetailPicture = CDeckEditorUI.SINGLETON_INSTANCE.getCDetailPicture();
|
||||
VCurrentDeck.SINGLETON_INSTANCE.setItemManager(new DeckManager(GameType.Draft, cDetailPicture));
|
||||
Singletons.getControl().setCurrentScreen(FScreen.DECK_EDITOR_QUEST_TOURNAMENT);
|
||||
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(new CEditorQuestLimited(FModel.getQuest(), cDetailPicture));
|
||||
FModel.getQuest().save();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
final QuestEventDraft draftEvent = QuestUtil.getDraftEvent();
|
||||
|
||||
final long creditsAvailable = FModel.getQuest().getAssets().getCredits();
|
||||
if (draftEvent.canEnter()) {
|
||||
FOptionPane.showMessageDialog("You need " + NUMBER_FORMATTER.format(draftEvent.getEntryFee() - creditsAvailable) + " more credits to enter this tournament.", "Not Enough Credits", FSkin.getImage(FSkinProp.ICO_WARNING).scale(2.0));
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean okayToEnter = FOptionPane.showOptionDialog("This tournament costs " + draftEvent.getEntryFee() + " credits to enter.\nAre you sure you wish to enter?", "Enter Draft Tournament?", FSkin.getImage(FSkinProp.ICO_QUEST_GOLD), ImmutableList.of("Yes", "No"), 1) == 0;
|
||||
|
||||
if (!okayToEnter) {
|
||||
return;
|
||||
}
|
||||
|
||||
drafting = true;
|
||||
|
||||
final BoosterDraft draft = draftEvent.enter();
|
||||
|
||||
final CEditorQuestDraftingProcess draftController = new CEditorQuestDraftingProcess(CDeckEditorUI.SINGLETON_INSTANCE.getCDetailPicture());
|
||||
draftController.showGui(draft);
|
||||
|
||||
draftController.setDraftQuest(CSubmenuQuestDraft.this);
|
||||
|
||||
Singletons.getControl().setCurrentScreen(FScreen.DRAFTING_PROCESS);
|
||||
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(draftController);
|
||||
|
||||
}
|
||||
|
||||
private void startTournament() {
|
||||
|
||||
FModel.getQuest().save();
|
||||
|
||||
final String message = GameType.QuestDraft.getDeckFormat().getDeckConformanceProblem(FModel.getQuest().getAssets().getDraftDeckStorage().get(QuestEventDraft.DECK_NAME).getHumanDeck());
|
||||
if (message != null && FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) {
|
||||
FOptionPane.showMessageDialog(message, "Deck Invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
FModel.getQuest().getAchievements().getCurrentDraft().start();
|
||||
|
||||
VSubmenuQuestDraft.SINGLETON_INSTANCE.setMode(Mode.TOURNAMENT_ACTIVE);
|
||||
VSubmenuQuestDraft.SINGLETON_INSTANCE.populate();
|
||||
|
||||
update();
|
||||
|
||||
}
|
||||
|
||||
private void startNextMatch() {
|
||||
|
||||
final String message = QuestDraftUtils.getDeckLegality();
|
||||
|
||||
if (message != null) {
|
||||
FOptionPane.showMessageDialog(message, "Deck Invalid");
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,22 +1,42 @@
|
||||
package forge.screens.home.quest;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.Singletons;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.game.GameType;
|
||||
import forge.gui.framework.DragCell;
|
||||
import forge.gui.framework.DragTab;
|
||||
import forge.gui.framework.EDocID;
|
||||
import forge.gui.framework.FScreen;
|
||||
import forge.itemmanager.DeckManager;
|
||||
import forge.limited.BoosterDraft;
|
||||
import forge.model.FModel;
|
||||
import forge.quest.IQuestTournamentView;
|
||||
import forge.quest.QuestEventDraft;
|
||||
import forge.quest.QuestDraftUtils.Mode;
|
||||
import forge.quest.data.QuestEventDraftContainer;
|
||||
import forge.screens.deckeditor.CDeckEditorUI;
|
||||
import forge.screens.deckeditor.controllers.CEditorQuestDraftingProcess;
|
||||
import forge.screens.deckeditor.controllers.CEditorQuestLimited;
|
||||
import forge.screens.deckeditor.views.VCurrentDeck;
|
||||
import forge.screens.home.*;
|
||||
import forge.screens.match.controllers.CDetailPicture;
|
||||
import forge.toolbox.FLabel;
|
||||
import forge.toolbox.FScrollPanel;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.Colors;
|
||||
import forge.toolbox.FSkin.SkinColor;
|
||||
import forge.toolbox.FSkin.SkinImage;
|
||||
import forge.toolbox.JXButtonPanel;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
/**
|
||||
@@ -24,17 +44,9 @@ import java.awt.geom.Rectangle2D;
|
||||
*
|
||||
* <br><br><i>(V at beginning of class name denotes a view class.)</i>
|
||||
*/
|
||||
public enum VSubmenuQuestDraft implements IVSubmenu<CSubmenuQuestDraft> {
|
||||
|
||||
public enum VSubmenuQuestDraft implements IVSubmenu<CSubmenuQuestDraft>, IQuestTournamentView {
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
protected enum Mode {
|
||||
EMPTY,
|
||||
SELECT_TOURNAMENT,
|
||||
PREPARE_DECK,
|
||||
TOURNAMENT_ACTIVE
|
||||
}
|
||||
|
||||
private final DragTab tab = new DragTab("Tournaments");
|
||||
|
||||
private final LblHeader lblTitle = new LblHeader("Quest Mode: Draft Tournament");
|
||||
@@ -180,23 +192,23 @@ public enum VSubmenuQuestDraft implements IVSubmenu<CSubmenuQuestDraft> {
|
||||
return matchups;
|
||||
}
|
||||
|
||||
public JLabel getLblFirst() {
|
||||
public FLabel getLblFirst() {
|
||||
return lblFirst;
|
||||
}
|
||||
|
||||
public JLabel getLblSecond() {
|
||||
public FLabel getLblSecond() {
|
||||
return lblSecond;
|
||||
}
|
||||
|
||||
public JLabel getLblThird() {
|
||||
public FLabel getLblThird() {
|
||||
return lblThird;
|
||||
}
|
||||
|
||||
public JLabel getLblFourth() {
|
||||
public FLabel getLblFourth() {
|
||||
return lblFourth;
|
||||
}
|
||||
|
||||
public JLabel getLblTokens() {
|
||||
public FLabel getLblTokens() {
|
||||
return lblTokens;
|
||||
}
|
||||
|
||||
@@ -281,7 +293,6 @@ public enum VSubmenuQuestDraft implements IVSubmenu<CSubmenuQuestDraft> {
|
||||
|
||||
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().repaintSelf();
|
||||
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().revalidate();
|
||||
|
||||
}
|
||||
|
||||
private void populateSelectTournament() {
|
||||
@@ -312,7 +323,6 @@ public enum VSubmenuQuestDraft implements IVSubmenu<CSubmenuQuestDraft> {
|
||||
}
|
||||
|
||||
private void populateTournamentActive() {
|
||||
|
||||
lblTitle.setText("Quest Mode: Draft Tournament - " + FModel.getQuest().getAchievements().getCurrentDraft().getTitle());
|
||||
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().setLayout(new MigLayout("insets 0, gap 0, ax center, wrap 1"));
|
||||
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(lblTitle, "w 80%!, h 40px!, gap 20% 0 15px 10px, ax right, span 2");
|
||||
@@ -340,28 +350,23 @@ public enum VSubmenuQuestDraft implements IVSubmenu<CSubmenuQuestDraft> {
|
||||
JPanel bottomButtons = new JPanel(new MigLayout("insets 0, gap 0, wrap 2, ax center"));
|
||||
|
||||
if (FModel.getQuest().getAchievements().getCurrentDraft().playerHasMatchesLeft()) {
|
||||
|
||||
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(btnStartMatch, "gap 0 0 0 20px, ax center");
|
||||
bottomButtons.add(btnEditDeck, "w 135px!, h 25px!, gap 0 25px 10px 10px, ax right");
|
||||
bottomButtons.add(btnLeaveTournament, "w 135px!, h 25px!, gap 25px 0 10px 10px, ax right");
|
||||
btnLeaveTournament.setFontSize(12);
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
else {
|
||||
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(btnLeaveTournament, "w 250px!, h 60px!, gap 0 0 20px 20px, ax center");
|
||||
bottomButtons.add(btnEditDeck, "w 135px!, h 25px!, gap 0 25px 10px 10px, ax right");
|
||||
bottomButtons.add(btnStartMatchSmall, "w 135px!, h 25px!, gap 25px 0 10px 10px, ax right");
|
||||
btnLeaveTournament.setFontSize(24);
|
||||
|
||||
}
|
||||
|
||||
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(bottomButtons, "w 100%!");
|
||||
bottomButtons.setOpaque(false);
|
||||
|
||||
}
|
||||
|
||||
private final class ProportionalPanel extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = 2098643413467094674L;
|
||||
|
||||
private final SkinImage image;
|
||||
@@ -381,7 +386,6 @@ public enum VSubmenuQuestDraft implements IVSubmenu<CSubmenuQuestDraft> {
|
||||
|
||||
@Override
|
||||
public void paintComponent(final Graphics g) {
|
||||
|
||||
Graphics2D g2d = (Graphics2D) g.create();
|
||||
|
||||
Dimension srcSize = image.getSizeForPaint(g2d);
|
||||
@@ -403,13 +407,10 @@ public enum VSubmenuQuestDraft implements IVSubmenu<CSubmenuQuestDraft> {
|
||||
0, 0, wSrc, hSrc); // Source
|
||||
|
||||
g2d.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class ProportionalDimension extends Dimension {
|
||||
|
||||
private static final long serialVersionUID = -428811386088062426L;
|
||||
|
||||
private ProportionalDimension(Dimension d, int w, int h) {
|
||||
@@ -581,9 +582,90 @@ public enum VSubmenuQuestDraft implements IVSubmenu<CSubmenuQuestDraft> {
|
||||
}
|
||||
|
||||
g2d.dispose();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateEventList(QuestEventDraftContainer events) {
|
||||
pnlTournaments.removeAll();
|
||||
if (events == null) { return; }
|
||||
|
||||
final JXButtonPanel grpPanel = new JXButtonPanel();
|
||||
|
||||
boolean firstPanel = true;
|
||||
|
||||
for (final QuestEventDraft draft : events) {
|
||||
final PnlDraftEvent draftPanel = new PnlDraftEvent(draft);
|
||||
final JRadioButton button = draftPanel.getRadioButton();
|
||||
|
||||
if (firstPanel) {
|
||||
button.setSelected(true);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override public void run() { button.requestFocusInWindow(); }
|
||||
});
|
||||
firstPanel = false;
|
||||
}
|
||||
|
||||
grpPanel.add(draftPanel, button, "w 100%!, h 135px!, gapy 15px");
|
||||
|
||||
button.addKeyListener(startOnEnter);
|
||||
button.addMouseListener(startOnDblClick);
|
||||
}
|
||||
|
||||
pnlTournaments.add(grpPanel, "w 100%!");
|
||||
}
|
||||
|
||||
private final KeyAdapter startOnEnter = new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(final KeyEvent e) {
|
||||
if (KeyEvent.VK_ENTER == e.getKeyChar()) {
|
||||
btnStartDraft.doClick();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final MouseAdapter startOnDblClick = new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(final MouseEvent e) {
|
||||
if (MouseEvent.BUTTON1 == e.getButton() && 2 == e.getClickCount()) {
|
||||
btnStartDraft.doClick();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void updateTournamentBoxLabel(String playerID, int iconID, int box, boolean first) {
|
||||
SkinImage icon = FSkin.getAvatars().get(iconID);
|
||||
if (icon == null) {
|
||||
icon = FSkin.getAvatars().get(0);
|
||||
}
|
||||
|
||||
if (first) {
|
||||
matchups[box].setPlayerOne(playerID, icon);
|
||||
}
|
||||
else {
|
||||
matchups[box].setPlayerTwo(playerID, icon);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startDraft(BoosterDraft draft) {
|
||||
final CEditorQuestDraftingProcess draftController = new CEditorQuestDraftingProcess(CDeckEditorUI.SINGLETON_INSTANCE.getCDetailPicture());
|
||||
draftController.showGui(draft);
|
||||
|
||||
draftController.setDraftQuest(CSubmenuQuestDraft.SINGLETON_INSTANCE);
|
||||
|
||||
Singletons.getControl().setCurrentScreen(FScreen.DRAFTING_PROCESS);
|
||||
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(draftController);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editDeck(boolean isExistingDeck) {
|
||||
final CDetailPicture cDetailPicture = CDeckEditorUI.SINGLETON_INSTANCE.getCDetailPicture();
|
||||
if (isExistingDeck) {
|
||||
VCurrentDeck.SINGLETON_INSTANCE.setItemManager(new DeckManager(GameType.Draft, cDetailPicture));
|
||||
}
|
||||
Singletons.getControl().setCurrentScreen(FScreen.DECK_EDITOR_QUEST_TOURNAMENT);
|
||||
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(new CEditorQuestLimited(FModel.getQuest(), cDetailPicture));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,6 +208,16 @@ public class GuiMobile implements IGuiBase {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaperCard chooseCard(final String title, final String message, final List<PaperCard> list) {
|
||||
return new WaitCallback<PaperCard>() {
|
||||
@Override
|
||||
public void run() {
|
||||
GuiChoose.one(title + " - " + message, list, this);
|
||||
}
|
||||
}.invokeAndWait();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvatarCount() {
|
||||
if (FSkin.isLoaded()) {
|
||||
|
||||
@@ -40,6 +40,7 @@ public interface IGuiBase {
|
||||
void download(GuiDownloadService service, Callback<Boolean> callback);
|
||||
void showCardList(String title, String message, List<PaperCard> list);
|
||||
boolean showBoxedProduct(String title, String message, List<PaperCard> list);
|
||||
PaperCard chooseCard(String title, String message, List<PaperCard> list);
|
||||
int getAvatarCount();
|
||||
void copyToClipboard(String text);
|
||||
void browseToUrl(String url) throws IOException, URISyntaxException;
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package forge.quest;
|
||||
|
||||
import forge.interfaces.IButton;
|
||||
import forge.limited.BoosterDraft;
|
||||
import forge.quest.QuestDraftUtils.Mode;
|
||||
import forge.quest.data.QuestEventDraftContainer;
|
||||
|
||||
public interface IQuestTournamentView {
|
||||
Mode getMode();
|
||||
void setMode(Mode mode0);
|
||||
void populate();
|
||||
void updateEventList(QuestEventDraftContainer events);
|
||||
void updateTournamentBoxLabel(String playerID, int iconID, int box, boolean first);
|
||||
void startDraft(BoosterDraft draft);
|
||||
void editDeck(boolean isNew);
|
||||
|
||||
IButton getLblCredits();
|
||||
IButton getLblFirst();
|
||||
IButton getLblSecond();
|
||||
IButton getLblThird();
|
||||
IButton getLblFourth();
|
||||
IButton getLblTokens();
|
||||
IButton getBtnSpendToken();
|
||||
IButton getBtnLeaveTournament();
|
||||
}
|
||||
@@ -25,12 +25,19 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class QuestDraftUtils {
|
||||
private static final List<DraftMatchup> matchups = new ArrayList<>();
|
||||
public static boolean TOURNAMENT_TOGGLE = false;
|
||||
public static boolean AI_BACKGROUND = false;
|
||||
|
||||
public static boolean matchInProgress = false;
|
||||
private static boolean waitForUserInput = false;
|
||||
private static final List<DraftMatchup> matchups = new ArrayList<>();
|
||||
|
||||
public enum Mode {
|
||||
EMPTY,
|
||||
SELECT_TOURNAMENT,
|
||||
PREPARE_DECK,
|
||||
TOURNAMENT_ACTIVE
|
||||
}
|
||||
|
||||
public static void completeDraft(final DeckGroup finishedDraft) {
|
||||
final List<Deck> aiDecks = new ArrayList<>(finishedDraft.getAiDecks());
|
||||
|
||||
@@ -0,0 +1,446 @@
|
||||
package forge.quest;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.deck.DeckGroup;
|
||||
import forge.game.GameType;
|
||||
import forge.interfaces.IGuiGame;
|
||||
import forge.item.BoosterPack;
|
||||
import forge.item.PaperCard;
|
||||
import forge.limited.BoosterDraft;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.quest.QuestDraftUtils.Mode;
|
||||
import forge.quest.QuestEventDraft.QuestDraftFormat;
|
||||
import forge.quest.data.QuestAchievements;
|
||||
import forge.tournament.system.TournamentBracket;
|
||||
import forge.tournament.system.TournamentPairing;
|
||||
import forge.tournament.system.TournamentPlayer;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
import forge.util.gui.SOptionPane;
|
||||
import forge.util.storage.IStorage;
|
||||
|
||||
public class QuestTournamentController {
|
||||
private static final DecimalFormat NUMBER_FORMATTER = new DecimalFormat("#,###");
|
||||
|
||||
private final IQuestTournamentView view;
|
||||
private boolean drafting = false;
|
||||
private IGuiGame gui = null;
|
||||
|
||||
public QuestTournamentController(IQuestTournamentView view0) {
|
||||
view = view0;
|
||||
|
||||
final QuestAchievements achievements = FModel.getQuest().getAchievements();
|
||||
final IStorage<DeckGroup> decks = FModel.getQuest().getDraftDecks();
|
||||
|
||||
if (achievements == null) {
|
||||
view.setMode(Mode.EMPTY);
|
||||
}
|
||||
else if (achievements.getDraftEvents() == null || achievements.getDraftEvents().isEmpty()) {
|
||||
achievements.generateDrafts();
|
||||
|
||||
if (achievements.getDraftEvents().isEmpty()) {
|
||||
view.setMode(Mode.EMPTY);
|
||||
}
|
||||
else {
|
||||
view.setMode(Mode.SELECT_TOURNAMENT);
|
||||
}
|
||||
}
|
||||
else if (decks == null || !decks.contains(QuestEventDraft.DECK_NAME)) {
|
||||
achievements.generateDrafts();
|
||||
view.setMode(Mode.SELECT_TOURNAMENT);
|
||||
}
|
||||
else if (!achievements.getCurrentDraft().isStarted()) {
|
||||
view.setMode(Mode.PREPARE_DECK);
|
||||
}
|
||||
else {
|
||||
view.setMode(Mode.TOURNAMENT_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
public void endTournamentAndAwardPrizes() {
|
||||
final QuestEventDraft draft = FModel.getQuest().getAchievements().getCurrentDraft();
|
||||
|
||||
if (!draft.isStarted()) {
|
||||
final boolean shouldQuit = SOptionPane.showOptionDialog("If you leave now, this tournament will be forever gone."
|
||||
+ "\nYou will keep the cards you drafted, but will receive no other prizes."
|
||||
+ "\n\nWould you still like to quit the tournament?", "Really Quit?", SOptionPane.WARNING_ICON, ImmutableList.of("Yes", "No"), 1) == 0;
|
||||
if (!shouldQuit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (draft.playerHasMatchesLeft()) {
|
||||
final boolean shouldQuit = SOptionPane.showOptionDialog("You have matches left to play!\nLeaving the tournament early will forfeit your potential future winnings."
|
||||
+ "\nYou will still receive winnings as if you conceded your next match and you will keep the cards you drafted."
|
||||
+ "\n\nWould you still like to quit the tournament?", "Really Quit?", SOptionPane.WARNING_ICON, ImmutableList.of("Yes", "No"), 1) == 0;
|
||||
if (!shouldQuit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final String placement = draft.getPlacementString();
|
||||
|
||||
final QuestEventDraft.QuestDraftPrizes prizes = draft.collectPrizes();
|
||||
|
||||
if (prizes.hasCredits()) {
|
||||
SOptionPane.showMessageDialog("For placing " + placement + ", you have been awarded " + prizes.credits + " credits!", "Credits Awarded", FSkinProp.ICO_QUEST_GOLD);
|
||||
}
|
||||
|
||||
if (prizes.hasIndividualCards()) {
|
||||
GuiBase.getInterface().showCardList("Tournament Reward", "For participating in the tournament, you have been awarded the following promotional card:", prizes.individualCards);
|
||||
}
|
||||
|
||||
if (prizes.hasBoosterPacks()) {
|
||||
final String packPlural = (prizes.boosterPacks.size() == 1) ? "" : "s";
|
||||
|
||||
SOptionPane.showMessageDialog("For placing " + placement + ", you have been awarded " + prizes.boosterPacks.size() + " booster pack" + packPlural + "!", "Booster Pack" + packPlural + " Awarded", FSkinProp.ICO_QUEST_BOX);
|
||||
|
||||
if (FModel.getPreferences().getPrefBoolean(FPref.UI_OPEN_PACKS_INDIV) && prizes.boosterPacks.size() > 1) {
|
||||
boolean skipTheRest = false;
|
||||
final List<PaperCard> remainingCards = new ArrayList<>();
|
||||
final int totalPacks = prizes.boosterPacks.size();
|
||||
int currentPack = 0;
|
||||
|
||||
while (!prizes.boosterPacks.isEmpty()) {
|
||||
|
||||
final BoosterPack pack = prizes.boosterPacks.remove(0);
|
||||
currentPack++;
|
||||
|
||||
if (skipTheRest) {
|
||||
remainingCards.addAll(pack.getCards());
|
||||
continue;
|
||||
}
|
||||
|
||||
skipTheRest = GuiBase.getInterface().showBoxedProduct(pack.getName(), "You have found the following cards inside (Booster Pack " + currentPack + " of " + totalPacks + "):", pack.getCards());
|
||||
}
|
||||
|
||||
if (skipTheRest && !remainingCards.isEmpty()) {
|
||||
GuiBase.getInterface().showCardList("Tournament Reward", "You have found the following cards inside:", remainingCards);
|
||||
}
|
||||
}
|
||||
else {
|
||||
final List<PaperCard> cards = new ArrayList<>();
|
||||
|
||||
while (!prizes.boosterPacks.isEmpty()) {
|
||||
final BoosterPack pack = prizes.boosterPacks.remove(0);
|
||||
cards.addAll(pack.getCards());
|
||||
}
|
||||
|
||||
GuiBase.getInterface().showCardList("Tournament Reward", "You have found the following cards inside:", cards);
|
||||
}
|
||||
}
|
||||
|
||||
if (prizes.selectRareFromSets()) {
|
||||
SOptionPane.showMessageDialog("For placing " + placement + ", you may select a rare or mythic rare card from the drafted block.", "Rare Awarded", FSkinProp.ICO_QUEST_STAKES);
|
||||
|
||||
final PaperCard card = GuiBase.getInterface().chooseCard("Select a Card", "Select a card to keep:", prizes.selectRareCards);
|
||||
prizes.addSelectedCard(card);
|
||||
|
||||
SOptionPane.showMessageDialog("'" + card.getName() + "' has been added to your collection!", "Card Added", FSkinProp.ICO_QUEST_STAKES);
|
||||
}
|
||||
|
||||
if (draft.getPlayerPlacement() == 1) {
|
||||
SOptionPane.showMessageDialog("For placing " + placement + ", you have been awarded a token!\nUse tokens to create new drafts to play.", "Bonus Token", FSkinProp.ICO_QUEST_NOTES);
|
||||
FModel.getQuest().getAchievements().addDraftToken();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
final boolean saveDraft = SOptionPane.showOptionDialog("Would you like to save this draft to the regular draft mode?", "Save Draft?", SOptionPane.QUESTION_ICON, ImmutableList.of("Yes", "No"), 0) == 0;
|
||||
if (saveDraft) {
|
||||
draft.saveToRegularDraft();
|
||||
}
|
||||
draft.addToQuestDecks();
|
||||
|
||||
update();
|
||||
view.populate();
|
||||
}
|
||||
|
||||
public void spendToken() {
|
||||
final QuestAchievements achievements = FModel.getQuest().getAchievements();
|
||||
if (achievements != null) {
|
||||
|
||||
List<QuestDraftFormat> formats = QuestEventDraft.getAvailableFormats(FModel.getQuest());
|
||||
|
||||
if (formats.isEmpty()) {
|
||||
SOptionPane.showErrorDialog(
|
||||
"You do not have any draft-able sets unlocked!\n" +
|
||||
"Come back later when you've unlocked more sets.",
|
||||
"No Available Drafts");
|
||||
return;
|
||||
}
|
||||
|
||||
final QuestDraftFormat format = SGuiChoose.oneOrNone("Choose Draft Format", formats);
|
||||
if (format != null) {
|
||||
achievements.spendDraftToken(format);
|
||||
|
||||
update();
|
||||
view.populate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (FModel.getQuest().getAchievements() == null) {
|
||||
view.setMode(Mode.EMPTY);
|
||||
return;
|
||||
}
|
||||
|
||||
final QuestAchievements achievements = FModel.getQuest().getAchievements();
|
||||
achievements.generateDrafts();
|
||||
|
||||
if (FModel.getQuest().getAchievements().getDraftEvents().isEmpty()) {
|
||||
view.setMode(Mode.EMPTY);
|
||||
updatePlacementLabelsText();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((FModel.getQuest().getDraftDecks() == null
|
||||
|| !FModel.getQuest().getDraftDecks().contains(QuestEventDraft.DECK_NAME)
|
||||
|| FModel.getQuest().getAchievements().getCurrentDraftIndex() == -1)) {
|
||||
view.setMode(Mode.SELECT_TOURNAMENT);
|
||||
}
|
||||
else if (!FModel.getQuest().getAchievements().getCurrentDraft().isStarted()) {
|
||||
view.setMode(Mode.PREPARE_DECK);
|
||||
}
|
||||
else {
|
||||
view.setMode(Mode.TOURNAMENT_ACTIVE);
|
||||
}
|
||||
|
||||
QuestDraftUtils.update(gui);
|
||||
|
||||
switch (view.getMode()) {
|
||||
case SELECT_TOURNAMENT:
|
||||
updateSelectTournament();
|
||||
break;
|
||||
case PREPARE_DECK:
|
||||
updatePrepareDeck();
|
||||
break;
|
||||
case TOURNAMENT_ACTIVE:
|
||||
updateTournamentActive();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSelectTournament() {
|
||||
view.getLblCredits().setText("Available Credits: " + NUMBER_FORMATTER.format(FModel.getQuest().getAssets().getCredits()));
|
||||
|
||||
final QuestAchievements achievements = FModel.getQuest().getAchievements();
|
||||
achievements.generateDrafts();
|
||||
|
||||
view.updateEventList(achievements.getDraftEvents());
|
||||
|
||||
updatePlacementLabelsText();
|
||||
}
|
||||
|
||||
private void updatePlacementLabelsText() {
|
||||
final QuestAchievements achievements = FModel.getQuest().getAchievements();
|
||||
|
||||
if (view.getMode() == Mode.EMPTY) {
|
||||
view.updateEventList(null);
|
||||
}
|
||||
|
||||
view.getLblFirst().setText("1st Place: " + achievements.getWinsForPlace(1) + " time" + (achievements.getWinsForPlace(1) == 1 ? "" : "s"));
|
||||
view.getLblSecond().setText("2nd Place: " + achievements.getWinsForPlace(2) + " time" + (achievements.getWinsForPlace(2) == 1 ? "" : "s"));
|
||||
view.getLblThird().setText("3rd Place: " + achievements.getWinsForPlace(3) + " time" + (achievements.getWinsForPlace(3) == 1 ? "" : "s"));
|
||||
view.getLblFourth().setText("4th Place: " + achievements.getWinsForPlace(4) + " time" + (achievements.getWinsForPlace(4) == 1 ? "" : "s"));
|
||||
|
||||
view.getLblTokens().setText("Tokens: " + achievements.getDraftTokens());
|
||||
view.getBtnSpendToken().setEnabled(achievements.getDraftTokens() > 0);
|
||||
}
|
||||
|
||||
private void updatePrepareDeck() {
|
||||
}
|
||||
|
||||
private void updateTournamentActive() {
|
||||
if (FModel.getQuest().getAchievements().getCurrentDraft() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (QuestDraftUtils.TOURNAMENT_TOGGLE) {
|
||||
updateTournamentActiveForBracket();
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 15; i++) {
|
||||
String playerID = FModel.getQuest().getAchievements().getCurrentDraft().getStandings()[i];
|
||||
|
||||
int iconID = 0;
|
||||
|
||||
switch (playerID) {
|
||||
case QuestEventDraft.HUMAN:
|
||||
playerID = FModel.getPreferences().getPref(FPref.PLAYER_NAME);
|
||||
if (FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",").length > 0) {
|
||||
iconID = Integer.parseInt(FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",")[0]);
|
||||
}
|
||||
break;
|
||||
case QuestEventDraft.UNDETERMINED:
|
||||
playerID = "Undetermined";
|
||||
iconID = GuiBase.getInterface().getAvatarCount() - 1;
|
||||
break;
|
||||
default:
|
||||
iconID = FModel.getQuest().getAchievements().getCurrentDraft().getAIIcons()[Integer.parseInt(playerID) - 1];
|
||||
playerID = FModel.getQuest().getAchievements().getCurrentDraft().getAINames()[Integer.parseInt(playerID) - 1];
|
||||
break;
|
||||
}
|
||||
|
||||
final boolean first = i % 2 == 0;
|
||||
final int box = i / 2;
|
||||
view.updateTournamentBoxLabel(playerID, iconID, box, first);
|
||||
}
|
||||
|
||||
if (FModel.getQuest().getAchievements().getCurrentDraft().playerHasMatchesLeft()) {
|
||||
view.getBtnLeaveTournament().setText("Leave Tournament");
|
||||
}
|
||||
else {
|
||||
view.getBtnLeaveTournament().setText("Collect Prizes");
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTournamentActiveForBracket() {
|
||||
QuestEventDraft draft = FModel.getQuest().getAchievements().getCurrentDraft();
|
||||
TournamentBracket bracket = draft.getBracket();
|
||||
|
||||
if (bracket == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Combine finished pairings with active round pairings
|
||||
List<TournamentPairing> allPairings = Lists.newArrayList();
|
||||
allPairings.addAll(bracket.getCompletedPairings());
|
||||
allPairings.addAll(bracket.getActivePairings());
|
||||
|
||||
int count = 0;
|
||||
int playerCount = 0;
|
||||
int lastWinner = 0;
|
||||
for (TournamentPairing tp : allPairings) {
|
||||
boolean first = true;
|
||||
String playerID = "Undetermined";
|
||||
int iconID = 0;
|
||||
for(TournamentPlayer player : tp.getPairedPlayers()) {
|
||||
if (player.getIndex() == -1) {
|
||||
playerID = FModel.getPreferences().getPref(FPref.PLAYER_NAME);
|
||||
if (FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",").length > 0) {
|
||||
iconID = Integer.parseInt(FModel.getPreferences().getPref(FPref.UI_AVATARS).split(",")[0]);
|
||||
}
|
||||
}
|
||||
else{
|
||||
playerID = player.getPlayer().getName();
|
||||
iconID = player.getIndex();
|
||||
}
|
||||
view.updateTournamentBoxLabel(playerID, iconID, count, first);
|
||||
|
||||
if (tp.getWinner() != null && tp.getWinner().equals(player)) {
|
||||
// Temporarily fill in winner box
|
||||
lastWinner = playerCount;
|
||||
view.updateTournamentBoxLabel(player.getPlayer().getName(), player.getIndex(), playerCount/4 + 4, count%2 == 0);
|
||||
}
|
||||
first = false;
|
||||
playerCount++;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
if (!bracket.isTournamentOver()) {
|
||||
for (int i = lastWinner/2+9 ; i < 15; i++) {
|
||||
String playerID = "Undetermined";
|
||||
int iconID = GuiBase.getInterface().getAvatarCount() - 1;
|
||||
view.updateTournamentBoxLabel(playerID, iconID, i / 2, i%2 == 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (draft.playerHasMatchesLeft()) {
|
||||
view.getBtnLeaveTournament().setText("Leave Tournament");
|
||||
}
|
||||
else {
|
||||
view.getBtnLeaveTournament().setText("Collect Prizes");
|
||||
}
|
||||
}
|
||||
|
||||
public void setCompletedDraft(final DeckGroup finishedDraft) {
|
||||
QuestDraftUtils.completeDraft(finishedDraft);
|
||||
|
||||
view.editDeck(false);
|
||||
|
||||
drafting = false;
|
||||
|
||||
view.setMode(Mode.PREPARE_DECK);
|
||||
view.populate();
|
||||
}
|
||||
|
||||
public void editDeck() {
|
||||
view.editDeck(true);
|
||||
FModel.getQuest().save();
|
||||
}
|
||||
|
||||
public void startDraft() {
|
||||
if (drafting) {
|
||||
SOptionPane.showErrorDialog("You are currently in a draft.\n" +
|
||||
"You should leave or finish that draft before starting another.");
|
||||
return;
|
||||
}
|
||||
|
||||
final QuestEventDraft draftEvent = QuestUtil.getDraftEvent();
|
||||
|
||||
final long creditsAvailable = FModel.getQuest().getAssets().getCredits();
|
||||
if (draftEvent.canEnter()) {
|
||||
SOptionPane.showMessageDialog("You need " + NUMBER_FORMATTER.format(draftEvent.getEntryFee() - creditsAvailable) + " more credits to enter this tournament.", "Not Enough Credits", SOptionPane.WARNING_ICON);
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean okayToEnter = SOptionPane.showOptionDialog("This tournament costs " + draftEvent.getEntryFee() + " credits to enter.\nAre you sure you wish to enter?", "Enter Draft Tournament?", FSkinProp.ICO_QUEST_GOLD, ImmutableList.of("Yes", "No"), 1) == 0;
|
||||
|
||||
if (!okayToEnter) {
|
||||
return;
|
||||
}
|
||||
|
||||
drafting = true;
|
||||
|
||||
final BoosterDraft draft = draftEvent.enter();
|
||||
view.startDraft(draft);
|
||||
}
|
||||
|
||||
public void startTournament() {
|
||||
FModel.getQuest().save();
|
||||
|
||||
final String message = GameType.QuestDraft.getDeckFormat().getDeckConformanceProblem(FModel.getQuest().getAssets().getDraftDeckStorage().get(QuestEventDraft.DECK_NAME).getHumanDeck());
|
||||
if (message != null && FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) {
|
||||
SOptionPane.showMessageDialog(message, "Deck Invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
FModel.getQuest().getAchievements().getCurrentDraft().start();
|
||||
|
||||
view.setMode(Mode.TOURNAMENT_ACTIVE);
|
||||
view.populate();
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
public void startNextMatch() {
|
||||
final String message = QuestDraftUtils.getDeckLegality();
|
||||
|
||||
if (message != null) {
|
||||
SOptionPane.showMessageDialog(message, "Deck Invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
if (QuestDraftUtils.matchInProgress) {
|
||||
SOptionPane.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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user