();
+ private boolean hasHumanPlayer = false;
+
+ }
+
+}
diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/SSubmenuQuestUtil.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/SSubmenuQuestUtil.java
index 23e563b7ce6..5add06eb023 100644
--- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/SSubmenuQuestUtil.java
+++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/SSubmenuQuestUtil.java
@@ -45,6 +45,7 @@ import java.util.List;
*/
public class SSubmenuQuestUtil {
private static QuestEvent event;
+ private static QuestEventDraft draftEvent;
/**
*
@@ -240,6 +241,14 @@ public class SSubmenuQuestUtil {
public static void setEvent(final QuestEvent event0) {
SSubmenuQuestUtil.event = event0;
}
+
+ public static void setDraftEvent(final QuestEventDraft event0) {
+ SSubmenuQuestUtil.draftEvent = event0;
+ }
+
+ public static QuestEventDraft getDraftEvent() {
+ return draftEvent;
+ }
public static boolean checkActiveQuest(String location) {
QuestController qc = FModel.getQuest();
diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestDraft.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestDraft.java
new file mode 100644
index 00000000000..ba33ef4a05b
--- /dev/null
+++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestDraft.java
@@ -0,0 +1,238 @@
+package forge.screens.home.quest;
+
+import java.awt.Font;
+
+import javax.swing.JLabel;
+import javax.swing.ScrollPaneConstants;
+import javax.swing.SwingConstants;
+
+import net.miginfocom.swing.MigLayout;
+import forge.assets.FSkinProp;
+import forge.gui.framework.DragCell;
+import forge.gui.framework.DragTab;
+import forge.gui.framework.EDocID;
+import forge.screens.home.EMenuGroup;
+import forge.screens.home.IVSubmenu;
+import forge.screens.home.LblHeader;
+import forge.screens.home.StartButton;
+import forge.screens.home.VHomeUI;
+import forge.toolbox.FLabel;
+import forge.toolbox.FScrollPanel;
+import forge.toolbox.FSkin;
+
+/**
+ * Assembles Swing components of quest draft submenu singleton.
+ *
+ *
(V at beginning of class name denotes a view class.)
+ */
+public enum VSubmenuQuestDraft implements IVSubmenu {
+
+ SINGLETON_INSTANCE;
+
+ protected static enum Mode {
+ SELECT_TOURNAMENT,
+ PREPARE_DECK,
+ TOURNAMENT_ACTIVE
+ }
+
+ private final DragTab tab = new DragTab("Tournaments");
+
+ private final LblHeader lblTitle = new LblHeader("Quest Mode: Draft Tournament");
+
+ private final FLabel lblCredits = new FLabel.Builder()
+ .icon(FSkin.getIcon(FSkinProp.ICO_QUEST_COINSTACK))
+ .iconScaleFactor(0.75)
+ .fontSize(13).build();
+
+ private final FScrollPanel pnlTournaments = new FScrollPanel(new MigLayout("insets 0, gap 0, wrap, ax center"), true,
+ ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
+
+ private final JLabel lblInfo = new FLabel.Builder().text("Select a tournament to join:")
+ .fontStyle(Font.BOLD).fontSize(16)
+ .fontAlign(SwingConstants.LEFT).build();
+
+ private final StartButton btnStartDraft = new StartButton();
+ private final StartButton btnStartTournament = new StartButton();
+ private final StartButton btnStartMatch = new StartButton();
+
+ private final FLabel btnEditDeck = new FLabel.ButtonBuilder().text("Edit Deck").fontSize(24).build();
+ private final FLabel btnLeaveTournament = new FLabel.ButtonBuilder().text("Leave Tournament").fontSize(14).build();
+
+ private final JLabel lblsStandings[] = new JLabel[15];
+
+ private Mode mode = Mode.SELECT_TOURNAMENT;
+
+ private DragCell parentCell;
+
+ private VSubmenuQuestDraft() {
+ for (int i = 0; i < 15; i++) {
+ lblsStandings[i] = new FLabel.Builder().text("Standing Slot: " + i)
+ .fontStyle(Font.BOLD).fontSize(14)
+ .fontAlign(SwingConstants.LEFT).build();
+ }
+ }
+
+ public LblHeader getLblTitle() {
+ return lblTitle;
+ }
+
+ public FLabel getLblCredits() {
+ return lblCredits;
+ }
+
+ public FScrollPanel getPnlTournaments() {
+ return pnlTournaments;
+ }
+
+ public StartButton getBtnStartDraft() {
+ return btnStartDraft;
+ }
+
+ public StartButton getBtnStartTournament() {
+ return btnStartTournament;
+ }
+
+ public StartButton getBtnStartMatch() {
+ return btnStartMatch;
+ }
+
+ public FLabel getBtnEditDeck() {
+ return btnEditDeck;
+ }
+
+ public FLabel getBtnLeaveTournament() {
+ return btnLeaveTournament;
+ }
+
+ public JLabel[] getLblsStandings() {
+ return lblsStandings;
+ }
+
+ public void setMode(Mode mode) {
+ this.mode = mode;
+ }
+
+ public Mode getMode() {
+ return mode;
+ }
+
+ @Override
+ public EDocID getDocumentID() {
+ return EDocID.HOME_QUESTDRAFTS;
+ }
+
+ @Override
+ public DragTab getTabLabel() {
+ return tab;
+ }
+
+ @Override
+ public CSubmenuQuestDraft getLayoutControl() {
+ return CSubmenuQuestDraft.SINGLETON_INSTANCE;
+ }
+
+ @Override
+ public void setParentCell(DragCell cell0) {
+ this.parentCell = cell0;
+ }
+
+ @Override
+ public DragCell getParentCell() {
+ return parentCell;
+ }
+
+ @Override
+ public EMenuGroup getGroupEnum() {
+ return EMenuGroup.QUEST;
+ }
+
+ @Override
+ public String getMenuTitle() {
+ return "Tournaments";
+ }
+
+ @Override
+ public EDocID getItemEnum() {
+ return EDocID.HOME_QUESTDRAFTS;
+ }
+
+ @Override
+ public void populate() {
+
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().removeAll();
+
+ switch (mode) {
+
+ case SELECT_TOURNAMENT:
+ populateSelectTournament();
+ break;
+ case PREPARE_DECK:
+ populatePrepareDeck();
+ break;
+ case TOURNAMENT_ACTIVE:
+ populateTournamentActive();
+ break;
+ default:
+ break;
+
+ }
+
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().repaintSelf();
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().revalidate();
+
+ }
+
+ private void populateSelectTournament() {
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().setLayout(new MigLayout("insets 0, gap 0, ax right, wrap"));
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(lblTitle, "w 80%!, h 40px!, gap 0 0 15px 35px, ax right");
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(lblCredits, "h 25px!, gap 0 0 30px");
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(lblInfo, "h 30px!, gap 0 0 5px");
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(pnlTournaments, "w 95%, pushy, growy");
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(btnStartDraft, "gap 0 6% 30px 30px, ax center");
+ }
+
+ private void populatePrepareDeck() {
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().setLayout(new MigLayout("insets 0, gap 0, ax center, wrap"));
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(lblTitle, "w 80%!, h 40px!, gap 20% 0 15px 35px, ax right");
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(btnEditDeck, "w 150px, h 50px, gap 0 0 35% 0, ax center");
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(btnStartTournament, "gap 0 0 30px 0, ax center");
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(btnLeaveTournament, "w 100px, h 35px, gap 0 0 100px 0, ax center");
+ }
+
+ private void populateTournamentActive() {
+
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().setLayout(new MigLayout("insets 0, gap 0, ax center, wrap"));
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(lblTitle, "w 80%!, h 40px!, gap 20% 0 15px 35px, ax right");
+
+ FScrollPanel panel = new FScrollPanel(new MigLayout("insets 0, gap 0, wrap 4, ax center"), true,
+ ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+
+ String constraints = "w 200px!, h 30px!, ay center";
+ String groupingGap = ", gap 0 0 0 50px";
+
+ panel.add(lblsStandings[0], constraints);
+ panel.add(lblsStandings[8], constraints + ", span 1 2");
+ panel.add(lblsStandings[12], constraints + ", span 1 4");
+ panel.add(lblsStandings[14], constraints + ", span 1 8");
+ panel.add(lblsStandings[1], constraints + groupingGap);
+ panel.add(lblsStandings[2], constraints);
+ panel.add(lblsStandings[9], constraints + ", span 1 2");
+ panel.add(lblsStandings[3], constraints + groupingGap);
+ panel.add(lblsStandings[4], constraints);
+ panel.add(lblsStandings[10], constraints + ", span 1 2");
+ panel.add(lblsStandings[13], constraints + ", span 1 4");
+ panel.add(lblsStandings[5], constraints + groupingGap);
+ panel.add(lblsStandings[6], constraints);
+ panel.add(lblsStandings[11], constraints + ", span 1 2");
+ panel.add(lblsStandings[7], constraints);
+
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(panel, "gap 0 0 30px 0, ax center");
+
+ /*for (JLabel label : lblsStandings) {
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(label, "h 30px!, gap 0 0 5px");
+ }*/
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(btnStartMatch, "gap 0 0 30px 0, ax center");
+ VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(btnLeaveTournament, "w 120px, h 35px, gap 0 0 100px 0, ax center");
+ }
+
+}
diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java b/forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java
new file mode 100644
index 00000000000..3d5b56d9ad3
--- /dev/null
+++ b/forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java
@@ -0,0 +1,151 @@
+/** Forge: Play Magic: the Gathering.
+ * Copyright (C) 2011 Forge Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * 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 .
+ */
+package forge.screens.match;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+
+import forge.GuiBase;
+import forge.LobbyPlayer;
+import forge.Singletons;
+import forge.game.Game;
+import forge.game.player.Player;
+import forge.gui.SOverlayUtils;
+import forge.gui.framework.FScreen;
+import forge.model.FModel;
+import forge.quest.QuestController;
+import forge.screens.home.quest.CSubmenuChallenges;
+import forge.screens.home.quest.CSubmenuDuels;
+import forge.screens.home.quest.CSubmenuQuestDraft;
+import forge.screens.home.quest.QuestDraftUtils;
+import forge.screens.home.quest.VSubmenuQuestDraft;
+
+/**
+ *
+ * QuestWinLose.
+ *
+ * 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 QuestDraftWinLose extends ControlWinLose {
+ private final transient ViewWinLose view;
+
+ private final transient QuestController qData;
+
+ /**
+ * Instantiates a new quest win lose handler.
+ *
+ * @param view0 ViewWinLose object
+ * @param match2
+ */
+ public QuestDraftWinLose(final ViewWinLose view0, Game lastGame) {
+ super(view0, lastGame);
+ this.view = view0;
+ qData = FModel.getQuest();
+ }
+
+ /**
+ *
+ * populateCustomPanel.
+ *
+ * Checks conditions of win and fires various reward display methods
+ * accordingly.
+ *
+ * @return true, if successful
+ */
+ @Override
+ public final boolean populateCustomPanel() {
+
+ QuestController quest = FModel.getQuest();
+
+ final LobbyPlayer questLobbyPlayer = GuiBase.getInterface().getQuestPlayer();
+ List players = lastGame.getRegisteredPlayers();
+ boolean gameHadHumanPlayer = false;
+ for (Player p : players) {
+ if (p.getLobbyPlayer().equals(questLobbyPlayer)) {
+ gameHadHumanPlayer = true;
+ break;
+ }
+ }
+
+ if (lastGame.getMatch().isMatchOver()) {
+
+ String winner = lastGame.getOutcome().getWinningPlayer().getName();
+
+ quest.getAchievements().getCurrentDraft().setWinner(winner);
+ quest.save();
+
+ }
+
+ if (!gameHadHumanPlayer) {
+
+ if (lastGame.getMatch().isMatchOver()) {
+ this.actionOnQuitMatch();
+ QuestDraftUtils.matchInProgress = false;
+ QuestDraftUtils.update();
+ } else {
+ this.actionOnContinue();
+ QuestDraftUtils.update();
+ }
+ return false;
+
+ }
+
+ view.getBtnRestart().setEnabled(false);
+
+ if (lastGame.getMatch().isMatchOver()) {
+ view.getBtnContinue().setEnabled(false);
+ //TODO Add match quit to quit button listeners before match is officially over
+ view.getBtnQuit().addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(final ActionEvent e) {
+ QuestDraftUtils.matchInProgress = false;
+ QuestDraftUtils.continueMatches();
+ }
+ });
+ } else {
+ view.getBtnQuit().setEnabled(false);
+ }
+
+ CSubmenuQuestDraft.SINGLETON_INSTANCE.update();
+ VSubmenuQuestDraft.SINGLETON_INSTANCE.populate();
+
+ return false; //We're not awarding anything, so never display the custom panel.
+
+ }
+
+ public final void actionOnQuitMatch() {
+
+ CSubmenuDuels.SINGLETON_INSTANCE.update();
+ CSubmenuChallenges.SINGLETON_INSTANCE.update();
+
+ qData.setCurrentEvent(null);
+ qData.save();
+ FModel.getQuestPreferences().save();
+ Singletons.getControl().writeMatchPreferences();
+
+ Singletons.getControl().endCurrentGame();
+ Singletons.getControl().setCurrentScreen(FScreen.HOME_SCREEN);
+
+ SOverlayUtils.hideOverlay();
+
+ }
+
+}
diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/ViewWinLose.java b/forge-gui-desktop/src/main/java/forge/screens/match/ViewWinLose.java
index 3e4f76bb15b..6a4a45e1a43 100644
--- a/forge-gui-desktop/src/main/java/forge/screens/match/ViewWinLose.java
+++ b/forge-gui-desktop/src/main/java/forge/screens/match/ViewWinLose.java
@@ -1,18 +1,32 @@
package forge.screens.match;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Point;
+import java.awt.Toolkit;
+import java.awt.datatransfer.StringSelection;
+
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+
+import net.miginfocom.swing.MigLayout;
import forge.UiCommand;
-import forge.game.*;
+import forge.game.Game;
+import forge.game.GameLog;
+import forge.game.GameLogEntry;
+import forge.game.GameLogEntryType;
+import forge.game.GameOutcome;
import forge.game.player.Player;
import forge.model.FModel;
-import forge.toolbox.*;
+import forge.toolbox.FButton;
+import forge.toolbox.FLabel;
+import forge.toolbox.FOverlay;
+import forge.toolbox.FScrollPane;
+import forge.toolbox.FSkin;
import forge.toolbox.FSkin.SkinnedLabel;
import forge.toolbox.FSkin.SkinnedPanel;
-import net.miginfocom.swing.MigLayout;
-
-import javax.swing.*;
-
-import java.awt.*;
-import java.awt.datatransfer.StringSelection;
+import forge.toolbox.FTextArea;
public class ViewWinLose {
@@ -24,7 +38,7 @@ public class ViewWinLose {
private final JPanel pnlOutcomes = new JPanel(new MigLayout("wrap, align center"));
private final Game game;
-
+
@SuppressWarnings("serial")
public ViewWinLose(final Game game0) {
@@ -48,6 +62,9 @@ public class ViewWinLose {
case Quest:
control = new QuestWinLose(this, game0);
break;
+ case QuestDraft:
+ control = new QuestDraftWinLose(this, game0);
+ break;
case Draft:
if (!FModel.getGauntletMini().isGauntletDraft()) {
break;
diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java b/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java
index 601816be3d7..2b6880ec2bb 100644
--- a/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java
+++ b/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java
@@ -19,8 +19,6 @@ package forge.view.arcane;
import forge.FThreads;
import forge.game.card.Card;
-import forge.model.FModel;
-import forge.properties.ForgePreferences.FPref;
import forge.screens.match.CMatchUI;
import forge.screens.match.controllers.CPrompt;
import forge.toolbox.FScrollPane;
@@ -58,7 +56,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
/** Constant STACK_SPACING_Y=0.07f. */
private static final float STACK_SPACING_Y = 0.07f;
- private final int creatureStackMax = 4;
+ //private final int creatureStackMax = 4;
private final int landStackMax = 5;
private final int tokenStackMax = 5;
private final int othersStackMax = 4;
@@ -186,7 +184,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
return allTokens;
}
- private final CardStackRow collectAllCreatures() {
+ /*private final CardStackRow collectAllCreatures() {
final CardStackRow allCreatures = new CardStackRow();
outerLoop:
//
@@ -236,7 +234,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
allCreatures.add(insertIndex == -1 ? allCreatures.size() : insertIndex, stack);
}
return allCreatures;
- }
+ }*/
@Override
public final CardPanel addCard(final Card card) {
diff --git a/forge-gui-mobile/src/forge/GuiMobile.java b/forge-gui-mobile/src/forge/GuiMobile.java
index b385edaa01c..d72afe10de8 100644
--- a/forge-gui-mobile/src/forge/GuiMobile.java
+++ b/forge-gui-mobile/src/forge/GuiMobile.java
@@ -53,7 +53,9 @@ import forge.util.WaitRunnable;
import forge.util.gui.SGuiChoose;
public class GuiMobile implements IGuiBase {
+
private final String assetsDir;
+
public GuiMobile(String assetsDir0) {
assetsDir = assetsDir0;
}
@@ -204,6 +206,14 @@ public class GuiMobile implements IGuiBase {
public void updatePlayerControl() {
//TODO
}
+
+ @Override
+ public void disableOverlay() {
+ }
+
+ @Override
+ public void enableOverlay() {
+ }
@Override
public void finishGame() {
diff --git a/forge-gui/src/main/java/forge/interfaces/IGuiBase.java b/forge-gui/src/main/java/forge/interfaces/IGuiBase.java
index cffaee449e9..b05fb989489 100644
--- a/forge-gui/src/main/java/forge/interfaces/IGuiBase.java
+++ b/forge-gui/src/main/java/forge/interfaces/IGuiBase.java
@@ -64,6 +64,8 @@ public interface IGuiBase {
void updatePhase();
void updateTurn(GameEventTurnBegan event, Game game);
void updatePlayerControl();
+ void enableOverlay();
+ void disableOverlay();
void finishGame();
void updateStack();
void updateZones(List> zonesToUpdate);
diff --git a/forge-gui/src/main/java/forge/limited/BoosterDraft.java b/forge-gui/src/main/java/forge/limited/BoosterDraft.java
index 2456cb27d4d..cd829617229 100644
--- a/forge-gui/src/main/java/forge/limited/BoosterDraft.java
+++ b/forge-gui/src/main/java/forge/limited/BoosterDraft.java
@@ -154,6 +154,23 @@ public final class BoosterDraft implements IBoosterDraft {
draft.pack = draft.get8BoosterPack();
return draft;
}
+
+ public static BoosterDraft createDraft(final LimitedPoolType draftType, final CardBlock block, final String[] boosters) {
+
+ BoosterDraft draft = new BoosterDraft(draftType);
+
+ final int nPacks = boosters.length;
+
+ for (int i = 0; i < nPacks; i++) {
+ draft.product.add(block.getBooster(boosters[i]));
+ }
+
+ IBoosterDraft.LAND_SET_CODE[0] = block.getLandSet();
+
+ draft.pack = draft.get8BoosterPack();
+ return draft;
+
+ }
/**
*
diff --git a/forge-gui/src/main/java/forge/quest/QuestController.java b/forge-gui/src/main/java/forge/quest/QuestController.java
index fe3280a50d8..6db9df700bf 100644
--- a/forge-gui/src/main/java/forge/quest/QuestController.java
+++ b/forge-gui/src/main/java/forge/quest/QuestController.java
@@ -17,12 +17,20 @@
*/
package forge.quest;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.eventbus.Subscribe;
import forge.GuiBase;
import forge.deck.Deck;
+import forge.deck.DeckGroup;
import forge.game.GameFormat;
import forge.game.event.GameEvent;
import forge.game.event.GameEventMulligan;
@@ -43,9 +51,6 @@ import forge.quest.io.QuestChallengeReader;
import forge.util.storage.IStorage;
import forge.util.storage.StorageBase;
-import java.io.File;
-import java.util.*;
-
/**
* TODO: Write javadoc for this type.
*
@@ -76,6 +81,9 @@ public class QuestController {
// This is used by shop. Had no idea where else to place this
private static transient IStorage preconManager = null;
+
+ private transient IStorage draftDecks;
+
/** The Constant RANK_TITLES. */
public static final String[] RANK_TITLES = new String[] { "Level 0 - Confused Wizard", "Level 1 - Mana Mage",
@@ -91,8 +99,7 @@ public class QuestController {
/** */
public static final int MAX_PET_SLOTS = 2;
-
-
+
/**
*
* TODO: Write javadoc for this method.
@@ -142,6 +149,10 @@ public class QuestController {
public IStorage getMyDecks() {
return this.decks;
}
+
+ public IStorage getDraftDecks() {
+ return draftDecks;
+ }
/**
* Gets the current format if any.
@@ -209,6 +220,8 @@ public class QuestController {
this.myCards = this.model == null ? null : new QuestUtilCards(this);
this.questFormat = this.model == null ? null : this.model.getFormat();
this.currentEvent = null;
+
+ this.draftDecks = this.model == null ? null : this.model.getAssets().getDraftDeckStorage();
this.resetDuelsManager();
this.resetChallengesManager();
diff --git a/forge-gui/src/main/java/forge/quest/QuestDeckGroupMap.java b/forge-gui/src/main/java/forge/quest/QuestDeckGroupMap.java
new file mode 100644
index 00000000000..ad1095fe4e6
--- /dev/null
+++ b/forge-gui/src/main/java/forge/quest/QuestDeckGroupMap.java
@@ -0,0 +1,60 @@
+/*
+ * Forge: Play Magic: the Gathering.
+ * Copyright (C) 2011 Forge Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * 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 .
+ */
+package forge.quest;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import forge.deck.DeckGroup;
+import forge.util.storage.StorageBase;
+
+/**
+ * TODO: Write javadoc for this type.
+ *
+ */
+public class QuestDeckGroupMap extends StorageBase {
+
+ /**
+ * Instantiates a new quest deck map.
+ */
+ public QuestDeckGroupMap(Map in) {
+ super("Quest draft decks", in == null ? new HashMap() : in);
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see forge.util.IFolderMap#add(forge.util.IHasName)
+ */
+ @Override
+ public void add(final DeckGroup deck) {
+ this.map.put(deck.getName(), deck);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see forge.util.IFolderMap#delete(java.lang.String)
+ */
+ @Override
+ public void delete(final String deckName) {
+ this.map.remove(deckName);
+ }
+
+}
diff --git a/forge-gui/src/main/java/forge/quest/QuestEventDraft.java b/forge-gui/src/main/java/forge/quest/QuestEventDraft.java
new file mode 100644
index 00000000000..8d7a8855b66
--- /dev/null
+++ b/forge-gui/src/main/java/forge/quest/QuestEventDraft.java
@@ -0,0 +1,459 @@
+/*
+ * Forge: Play Magic: the Gathering.
+ * Copyright (C) 2011 Forge Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * 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 .
+ */
+package forge.quest;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import org.apache.commons.lang3.ArrayUtils;
+
+import com.google.common.base.Function;
+
+import forge.GuiBase;
+import forge.card.CardEdition;
+import forge.limited.LimitedPoolType;
+import forge.model.CardBlock;
+import forge.model.FModel;
+import forge.quest.io.ReadPriceList;
+import forge.util.NameGenerator;
+import forge.util.storage.IStorage;
+
+/**
+ *
+ * QuestEvent.
+ *
+ *
+ * MODEL - A basic event instance in Quest mode. Can be extended for use in
+ * unique event types: battles, quests, and others.
+ */
+public class QuestEventDraft {
+
+ public static final String UNDETERMINED = "quest_draft_undetermined_place";
+ public static final String HUMAN = "quest_draft_human_place";
+ public static final String DECK_NAME = "Tournament Deck";
+
+ public static final Function FN_GET_NAME = new Function() {
+ @Override public final String apply(QuestEventDraft qe) { return qe.title; }
+ };
+
+ private static transient final ReadPriceList PRICE_LIST_READER = new ReadPriceList();
+ private static transient final Map MAP_PRICES = PRICE_LIST_READER.getPriceList();
+
+ private String title = "Mystery Draft";
+ private String boosterConfiguration = "";
+ private String block = "";
+
+ private int entryFee = 0;
+
+ private String[] standings = new String[15];
+ private String[] aiNames = new String[7];
+
+ private int[] aiIcons = new int[7];
+
+ public QuestEventDraft(final String title) {
+ this.title = title;
+ }
+
+ public final String getTitle() {
+ return this.title;
+ }
+
+ public final String[] getBoosterConfiguration() {
+ return boosterConfiguration.split("/");
+ }
+
+ public final void setBoosterConfiguration(final String boosterConfiguration) {
+ this.boosterConfiguration = boosterConfiguration;
+ }
+
+ public final void setEntryFee(final int entryFee) {
+ this.entryFee = entryFee;
+ }
+
+ public final int getEntryFee() {
+ return entryFee;
+ }
+
+ public final void setBlock(final String block) {
+ this.block = block;
+ }
+
+ public final String getBlock() {
+ return block;
+ }
+
+ public void setTitle(final String title0) {
+ this.title = title0;
+ }
+
+ public void setStanding(int position, String player) {
+ standings[position] = player;
+ }
+
+ public void setStandings(String[] standings) {
+ this.standings = standings;
+ }
+
+ public String[] getStandings() {
+ return standings;
+ }
+
+ public String[] getAINames() {
+ return aiNames;
+ }
+
+ public void setAINames(final String[] names) {
+ aiNames = names;
+ }
+
+ public int[] getAIIcons() {
+ return aiIcons;
+ }
+
+ public void setAIIcons(final int[] icons) {
+ aiIcons = icons;
+ }
+
+ public int getHumanLatestStanding() {
+ int humanIndex = 0;
+ for (int i = getStandings().length - 1; i >= 0; i--) {
+ if (getStandings()[i].equals(HUMAN)) {
+ humanIndex = i;
+ break;
+ }
+ }
+ return humanIndex;
+ }
+
+ public int getOpponentIndex(int playerIndex) {
+ int result = (playerIndex % 2 == 0) ? playerIndex + 1 : playerIndex - 1;
+ if (result == 15) {
+ result = -1;
+ }
+ return result;
+ }
+
+ public void setWinner(String playerName) {
+
+ boolean isHumanPlayer = true;
+
+ for (String name : aiNames) {
+ if (playerName.equals(name)) {
+ isHumanPlayer = false;
+ }
+ }
+
+ int playerIndex = -1;
+
+ if (isHumanPlayer) {
+ for (int i = standings.length - 1; i >= 0; i--) {
+ if (standings[i].equals(HUMAN)) {
+ playerIndex = i;
+ break;
+ }
+ }
+ } else {
+
+ String aiIndex = "";
+
+ for (int i = aiNames.length - 1; i >= 0; i--) {
+ if (aiNames[i].equals(playerName)) {
+ aiIndex = "" + (i + 1);
+ break;
+ }
+ }
+
+ for (int i = standings.length - 1; i >= 0; i--) {
+ if (standings[i].equals(aiIndex)) {
+ playerIndex = i;
+ break;
+ }
+ }
+
+ }
+
+ switch (playerIndex) {
+ case 0:
+ case 1:
+ standings[8] = standings[playerIndex];
+ break;
+ case 2:
+ case 3:
+ standings[9] = standings[playerIndex];
+ break;
+ case 4:
+ case 5:
+ standings[10] = standings[playerIndex];
+ break;
+ case 6:
+ case 7:
+ standings[11] = standings[playerIndex];
+ break;
+ case 8:
+ case 9:
+ standings[12] = standings[playerIndex];
+ break;
+ case 10:
+ case 11:
+ standings[13] = standings[playerIndex];
+ break;
+ case 12:
+ case 13:
+ standings[14] = standings[playerIndex];
+ break;
+ }
+
+ }
+
+ @Override
+ public String toString() {
+ return title;
+ }
+
+ /**
+ * Generates a random draft event based on the provided quest's limitations.
+ * Returns null in the event no draft could be created.
+ * @param quest
+ * @return
+ */
+ public static QuestEventDraft getRandomDraftOrNull(final QuestController quest) {
+
+ List possibleBlocks = new ArrayList();
+ List allowedQuestSets = new ArrayList();
+
+ boolean questUsesLimitedCardPool = quest.getFormat() != null;
+
+ if (questUsesLimitedCardPool) {
+
+ List allowedSetCodes = quest.getFormat().getAllowedSetCodes();
+
+ for (String setCode : allowedSetCodes) {
+ allowedQuestSets.add(FModel.getMagicDb().getEditions().get(setCode));
+ }
+
+ }
+
+ LimitedPoolType draftType = LimitedPoolType.Block;
+
+ List blocks = new ArrayList();
+ IStorage storage = draftType == LimitedPoolType.Block ? FModel.getBlocks() : FModel.getFantasyBlocks();
+
+ for (CardBlock b : storage) {
+ if (b.getCntBoostersDraft() > 0) {
+ blocks.add(b);
+ }
+ }
+
+ if (questUsesLimitedCardPool) {
+ for (CardBlock block : blocks) {
+
+ boolean blockAllowed = true;
+
+ for (CardEdition set : block.getSets()) {
+ if (!allowedQuestSets.contains(set)) {
+ blockAllowed = false;
+ break;
+ }
+ }
+
+ if (blockAllowed) {
+ possibleBlocks.add(block);
+ }
+
+ }
+ } else {
+ possibleBlocks.addAll(blocks);
+ }
+
+ if (possibleBlocks.isEmpty()) {
+ return null;
+ }
+
+ Collections.shuffle(possibleBlocks);
+ CardBlock selectedBlock = possibleBlocks.get(0);
+
+ final Stack sets = new Stack();
+ for (int k = selectedBlock.getSets().length - 1; k >= 0; k--) {
+ sets.add(selectedBlock.getSets()[k].getCode());
+ }
+
+ for (String setCode : selectedBlock.getMetaSetNames()) {
+ if (selectedBlock.getMetaSet(setCode).isDraftable()) {
+ sets.push(setCode);
+ }
+ }
+
+ QuestEventDraft event = new QuestEventDraft(selectedBlock.getName());
+
+ if (selectedBlock.getNumberSets() == 1) {
+ String boosterConfiguration = "";
+ for (int i = 0; i < selectedBlock.getCntBoostersDraft(); i++) {
+ boosterConfiguration += selectedBlock.getSets()[0].getCode();
+ if (i != selectedBlock.getCntBoostersDraft() - 1) {
+ boosterConfiguration += "/";
+ }
+ event.boosterConfiguration = boosterConfiguration;
+ }
+ } else {
+ List possibleSetCombinations = getSetCombos(sets);
+ Collections.shuffle(possibleSetCombinations);
+ event.boosterConfiguration = possibleSetCombinations.get(0);
+ }
+
+ event.block = selectedBlock.getName();
+ event.entryFee = calculateEntryFee(event.boosterConfiguration.split("/"));
+
+ List players = new ArrayList();
+ players.add(HUMAN);
+ players.add("1");
+ players.add("2");
+ players.add("3");
+ players.add("4");
+ players.add("5");
+ players.add("6");
+ players.add("7");
+
+ Collections.shuffle(players);
+
+ for (int i = 0; i < players.size(); i++) {
+ event.standings[i] = players.get(i);
+ }
+
+ for (int i = 8; i < event.standings.length; i++) {
+ event.standings[i] = UNDETERMINED;
+ }
+
+ List usedNames = new ArrayList();
+ usedNames.add(GuiBase.getInterface().getGuiPlayer().getName());
+
+ for (int i = 0; i < 7; i++) {
+ event.aiNames[i] = NameGenerator.getRandomName("Any", "Any", usedNames);
+ usedNames.add(event.aiNames[i]);
+ }
+
+ int numberOfIcons = GuiBase.getInterface().getAvatarCount();
+ List usedIcons = new ArrayList();
+
+ for (int i = 0; i < 7; i++) {
+
+ int icon = -1;
+ int attempts = 50;
+
+ do {
+ icon = (int) Math.floor(Math.random() * numberOfIcons);
+ } while ((icon < 0 || usedIcons.contains(icon)) && attempts-- > 0);
+
+ event.aiIcons[i] = icon;
+ usedNames.add(event.aiNames[i]);
+
+ }
+
+ return event;
+
+ }
+
+ private static int calculateEntryFee(String[] boosters) {
+
+ int entryFee = 0;
+
+ for (String boosterSet : boosters) {
+
+ int value = 0;
+ String boosterName = FModel.getMagicDb().getEditions().get(boosterSet).getName() + " Booster Pack";
+
+ if (MAP_PRICES.containsKey(boosterName)) {
+ value = MAP_PRICES.get(boosterName);
+ } else {
+ value = 395;
+ }
+
+ entryFee += value;
+
+ }
+
+ return (int) (entryFee * 1.5);
+
+ }
+
+ private static List getSetCombos(final List setz) {
+ String[] sets = setz.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
+ List setCombos = new ArrayList();
+ if (sets.length >= 2) {
+ setCombos.add(String.format("%s/%s/%s", sets[0], sets[0], sets[0]));
+ setCombos.add(String.format("%s/%s/%s", sets[0], sets[0], sets[1]));
+ setCombos.add(String.format("%s/%s/%s", sets[0], sets[1], sets[1]));
+ if (sets.length >= 3) {
+ setCombos.add(String.format("%s/%s/%s", sets[0], sets[1], sets[2]));
+ setCombos.add(String.format("%s/%s/%s", sets[0], sets[2], sets[2]));
+ }
+ setCombos.add(String.format("%s/%s/%s", sets[1], sets[0], sets[0]));
+ setCombos.add(String.format("%s/%s/%s", sets[1], sets[1], sets[0]));
+ setCombos.add(String.format("%s/%s/%s", sets[1], sets[1], sets[1]));
+ if (sets.length >= 3) {
+ setCombos.add(String.format("%s/%s/%s", sets[1], sets[1], sets[2]));
+ setCombos.add(String.format("%s/%s/%s", sets[1], sets[2], sets[2]));
+ }
+ }
+ if (sets.length >= 3) {
+ setCombos.add(String.format("%s/%s/%s", sets[2], sets[1], sets[0]));
+ setCombos.add(String.format("%s/%s/%s", sets[2], sets[2], sets[0]));
+ setCombos.add(String.format("%s/%s/%s", sets[2], sets[2], sets[1]));
+ setCombos.add(String.format("%s/%s/%s", sets[2], sets[2], sets[2]));
+ } // Beyond 3, skimp on the choice configurations, or the list will be enormous!
+ if (sets.length >= 4) {
+ setCombos.add(String.format("%s/%s/%s", sets[3], sets[1], sets[0]));
+ setCombos.add(String.format("%s/%s/%s", sets[3], sets[2], sets[1]));
+ }
+ if (sets.length >= 5) {
+ setCombos.add(String.format("%s/%s/%s", sets[4], sets[1], sets[0]));
+ setCombos.add(String.format("%s/%s/%s", sets[4], sets[3], sets[2]));
+ setCombos.add(String.format("%s/%s/%s", sets[4], sets[2], sets[0]));
+ }
+ if (sets.length >= 6) {
+ setCombos.add(String.format("%s/%s/%s", sets[5], sets[1], sets[0]));
+ setCombos.add(String.format("%s/%s/%s", sets[5], sets[3], sets[2]));
+ setCombos.add(String.format("%s/%s/%s", sets[5], sets[4], sets[3]));
+ setCombos.add(String.format("%s/%s/%s", sets[5], sets[2], sets[0]));
+ }
+ if (sets.length >= 7) {
+ setCombos.add(String.format("%s/%s/%s", sets[6], sets[1], sets[0]));
+ setCombos.add(String.format("%s/%s/%s", sets[6], sets[3], sets[2]));
+ setCombos.add(String.format("%s/%s/%s", sets[6], sets[5], sets[4]));
+ setCombos.add(String.format("%s/%s/%s", sets[6], sets[3], sets[0]));
+ }
+ if (sets.length >= 8) {
+ setCombos.add(String.format("%s/%s/%s", sets[7], sets[1], sets[0]));
+ setCombos.add(String.format("%s/%s/%s", sets[7], sets[3], sets[2]));
+ setCombos.add(String.format("%s/%s/%s", sets[7], sets[5], sets[4]));
+ setCombos.add(String.format("%s/%s/%s", sets[7], sets[6], sets[5]));
+ setCombos.add(String.format("%s/%s/%s", sets[7], sets[3], sets[0]));
+ }
+ if (sets.length >= 9) {
+ setCombos.add(String.format("%s/%s/%s", sets[8], sets[1], sets[0]));
+ setCombos.add(String.format("%s/%s/%s", sets[8], sets[3], sets[2]));
+ setCombos.add(String.format("%s/%s/%s", sets[8], sets[5], sets[4]));
+ setCombos.add(String.format("%s/%s/%s", sets[8], sets[7], sets[6]));
+ setCombos.add(String.format("%s/%s/%s", sets[8], sets[4], sets[0]));
+ }
+ return setCombos;
+ }
+
+}
diff --git a/forge-gui/src/main/java/forge/quest/data/QuestAchievements.java b/forge-gui/src/main/java/forge/quest/data/QuestAchievements.java
index e27dc406759..edf213c2c23 100644
--- a/forge-gui/src/main/java/forge/quest/data/QuestAchievements.java
+++ b/forge-gui/src/main/java/forge/quest/data/QuestAchievements.java
@@ -1,11 +1,12 @@
package forge.quest.data;
-import forge.model.FModel;
-import forge.quest.data.QuestPreferences.DifficultyPrefs;
-
import java.util.ArrayList;
import java.util.List;
+import forge.model.FModel;
+import forge.quest.QuestEventDraft;
+import forge.quest.data.QuestPreferences.DifficultyPrefs;
+
/**
* TODO: Write javadoc for this type.
*
@@ -18,6 +19,11 @@ public class QuestAchievements {
private List completedChallenges = new ArrayList();
private List currentChallenges = new ArrayList();
+
+ private QuestEventDraftContainer drafts = new QuestEventDraftContainer();
+ private int currentDraft = -1;
+ private int draftTokensAvailable = 3;
+ private int winCountAtEndOfDraft = 0;
private int win;
private int winstreakBest = 0;
@@ -34,6 +40,17 @@ public class QuestAchievements {
public QuestAchievements(int diff) {
difficulty = diff;
}
+
+ public void deleteDraft(QuestEventDraft draft) {
+ drafts.remove(draft);
+ }
+
+ public void endCurrentTournament() {
+ drafts.remove(drafts.get(currentDraft));
+ currentDraft = -1;
+ winCountAtEndOfDraft = win;
+ FModel.getQuest().save();
+ }
/**
* TODO: Write javadoc for Constructor.
@@ -45,6 +62,13 @@ public class QuestAchievements {
public void addWin() { // changes getRank()
this.win++;
this.winstreakCurrent++;
+
+ //Every 5 wins, allow a tournament to be generated.
+ if ((win - winCountAtEndOfDraft) % 5 == 0) {
+ if (draftTokensAvailable < 3) {
+ draftTokensAvailable++;
+ }
+ }
if (this.winstreakCurrent > this.winstreakBest) {
this.winstreakBest = this.winstreakCurrent;
@@ -176,4 +200,48 @@ public class QuestAchievements {
return this.difficulty;
}
+ public QuestEventDraftContainer getDraftEvents() {
+ return drafts;
+ }
+
+ public boolean isTournamentActive() {
+ return currentDraft >= 0;
+ }
+
+ public void generateNewTournaments() {
+
+ if (drafts == null) {
+ drafts = new QuestEventDraftContainer();
+ draftTokensAvailable = 3;
+ }
+
+ int draftsToGenerate = 3 - drafts.size();
+ if (draftsToGenerate > draftTokensAvailable) {
+ draftsToGenerate = draftTokensAvailable;
+ }
+
+ for (int i = 0; i < draftsToGenerate; i++) {
+ QuestEventDraft draft = QuestEventDraft.getRandomDraftOrNull(FModel.getQuest());
+ if (draft != null) {
+ drafts.add(draft);
+ draftTokensAvailable--;
+ }
+ }
+
+ FModel.getQuest().save();
+
+ }
+
+ public void addDraftToken() {
+ draftTokensAvailable++;
+ }
+
+ public void setCurrentDraft(final QuestEventDraft draft) {
+ currentDraft = drafts.indexOf(draft);
+ }
+
+ public QuestEventDraft getCurrentDraft() {
+ return drafts.get(currentDraft);
+ }
+
}
diff --git a/forge-gui/src/main/java/forge/quest/data/QuestAssets.java b/forge-gui/src/main/java/forge/quest/data/QuestAssets.java
index 88dad00a87c..91a3138d1d6 100644
--- a/forge-gui/src/main/java/forge/quest/data/QuestAssets.java
+++ b/forge-gui/src/main/java/forge/quest/data/QuestAssets.java
@@ -17,10 +17,16 @@
*/
package forge.quest.data;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Map;
+
import forge.deck.Deck;
+import forge.deck.DeckGroup;
import forge.item.InventoryItem;
import forge.item.PaperCard;
import forge.model.FModel;
+import forge.quest.QuestDeckGroupMap;
import forge.quest.QuestDeckMap;
import forge.quest.QuestMode;
import forge.quest.QuestUtilCards;
@@ -28,10 +34,6 @@ import forge.quest.bazaar.QuestItemType;
import forge.quest.data.QuestPreferences.QPref;
import forge.util.ItemPool;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.Map;
-
/** */
public class QuestAssets {
@@ -62,6 +64,8 @@ public class QuestAssets {
// Much the same like other map, but keyed by string (to support a lot of custom pets)
private final Map combatPets = new HashMap();
+
+ private final HashMap draftDecks = new HashMap();
/**
* Checks for item.
*
@@ -263,4 +267,11 @@ public class QuestAssets {
return new QuestDeckMap(this.myDecks);
}
+ /**
+ * @return the tournament deck storage
+ */
+ public QuestDeckGroupMap getDraftDeckStorage() {
+ return new QuestDeckGroupMap(this.draftDecks);
+ }
+
}
diff --git a/forge-gui/src/main/java/forge/quest/data/QuestData.java b/forge-gui/src/main/java/forge/quest/data/QuestData.java
index e0fd8674af4..b80725e12be 100644
--- a/forge-gui/src/main/java/forge/quest/data/QuestData.java
+++ b/forge-gui/src/main/java/forge/quest/data/QuestData.java
@@ -41,7 +41,7 @@ import java.util.Map;
*/
public final class QuestData {
/** Holds the latest version of the Quest Data. */
- public static final int CURRENT_VERSION_NUMBER = 8;
+ public static final int CURRENT_VERSION_NUMBER = 9;
// This field places the version number into QD instance,
// but only when the object is created through the constructor
diff --git a/forge-gui/src/main/java/forge/quest/data/QuestEventDraftContainer.java b/forge-gui/src/main/java/forge/quest/data/QuestEventDraftContainer.java
new file mode 100644
index 00000000000..725f43fa624
--- /dev/null
+++ b/forge-gui/src/main/java/forge/quest/data/QuestEventDraftContainer.java
@@ -0,0 +1,9 @@
+package forge.quest.data;
+
+import java.util.ArrayList;
+
+import forge.quest.QuestEventDraft;
+
+public class QuestEventDraftContainer extends ArrayList {
+ private static final long serialVersionUID = -417036762608756613L;
+}
diff --git a/forge-gui/src/main/java/forge/quest/io/QuestDataIO.java b/forge-gui/src/main/java/forge/quest/io/QuestDataIO.java
index 0abb09ce95b..0f9e0732e92 100644
--- a/forge-gui/src/main/java/forge/quest/io/QuestDataIO.java
+++ b/forge-gui/src/main/java/forge/quest/io/QuestDataIO.java
@@ -27,12 +27,14 @@ import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import forge.card.CardEdition;
import forge.deck.CardPool;
import forge.deck.Deck;
+import forge.deck.DeckGroup;
import forge.deck.DeckSection;
import forge.error.BugReporter;
import forge.item.*;
import forge.model.FModel;
import forge.properties.ForgeConstants;
import forge.quest.QuestController;
+import forge.quest.QuestEventDraft;
import forge.quest.QuestMode;
import forge.quest.bazaar.QuestItemType;
import forge.quest.data.*;
@@ -79,6 +81,7 @@ public class QuestDataIO {
final XStream xStream = isIgnoring ? new IgnoringXStream() : new XStream();
xStream.registerConverter(new ItemPoolToXml());
xStream.registerConverter(new DeckToXml());
+ xStream.registerConverter(new DraftTournamentToXml());
xStream.registerConverter(new GameFormatQuestToXml());
xStream.registerConverter(new QuestModeToXml());
xStream.autodetectAnnotations(true);
@@ -184,10 +187,10 @@ public class QuestDataIO {
QuestDataIO.setFinalField(QuestData.class, "petSlots", newData, new HashMap());
}
- if(saveVersion < 8) {
+ if (saveVersion < 8) {
QuestDataIO.setFinalField(QuestData.class, "isCharmActive", newData, false);
}
-
+
final QuestAssets qS = newData.getAssets();
final QuestAchievements qA = newData.getAchievements();
@@ -316,7 +319,10 @@ public class QuestDataIO {
if (!(lc instanceof String))
qA.getCurrentChallenges().set(i, lc.toString());
}
-
+
+ case 8:
+ QuestDataIO.setFinalField(QuestAssets.class, "draftDecks", qS, new HashMap());
+
default:
break;
}
@@ -469,6 +475,161 @@ public class QuestDataIO {
return QuestMode.smartValueOf(value, QuestMode.Classic);
}
}
+
+ private static class DraftTournamentToXml implements Converter {
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public boolean canConvert(Class type) {
+ return type.equals(QuestEventDraftContainer.class);
+ }
+
+ @Override
+ public void marshal(Object source, HierarchicalStreamWriter writer,
+ MarshallingContext context) {
+
+ QuestEventDraftContainer drafts = (QuestEventDraftContainer) source;
+
+ for (QuestEventDraft draft : drafts) {
+
+ writer.startNode("draft");
+
+ writer.startNode("title");
+ writer.setValue(draft.getTitle());
+ writer.endNode();
+
+ writer.startNode("packs");
+ String output = "";
+ for (int i = 0; i < draft.getBoosterConfiguration().length; i++) {
+ output += draft.getBoosterConfiguration()[i];
+ if (i != draft.getBoosterConfiguration().length - 1) {
+ output += "/";
+ }
+ }
+ writer.setValue(output);
+ writer.endNode();
+
+ writer.startNode("entryFee");
+ writer.setValue(String.valueOf(draft.getEntryFee()));
+ writer.endNode();
+
+ writer.startNode("block");
+ writer.setValue(draft.getBlock());
+ writer.endNode();
+
+ writer.startNode("standings");
+ int i = 0;
+ for (String standing : draft.getStandings()) {
+ writer.startNode("s" + i++);
+ writer.setValue(standing);
+ writer.endNode();
+ }
+ writer.endNode();
+
+ writer.startNode("aiNames");
+ i = 0;
+ for (String name : draft.getAINames()) {
+ writer.startNode("ain" + i++);
+ writer.setValue(name);
+ writer.endNode();
+ }
+ writer.endNode();
+
+ writer.startNode("aiIcons");
+ i = 0;
+ for (int icon : draft.getAIIcons()) {
+ writer.startNode("aii" + i++);
+ writer.setValue(icon + "");
+ writer.endNode();
+ }
+ writer.endNode();
+
+ writer.endNode();
+
+ }
+
+ }
+
+ @Override
+ public Object unmarshal(HierarchicalStreamReader reader,
+ UnmarshallingContext context) {
+
+ QuestEventDraftContainer output = new QuestEventDraftContainer();
+
+ while (reader.hasMoreChildren()) {
+
+ reader.moveDown();
+
+ //TODO Use switch and hasMoreChildren()
+
+ reader.moveDown();
+ String draftName = reader.getValue();
+ reader.moveUp();
+
+ reader.moveDown();
+ String boosterConfiguration = reader.getValue();
+ reader.moveUp();
+
+ reader.moveDown();
+ int entryFee = Integer.parseInt(reader.getValue());
+ reader.moveUp();
+
+ reader.moveDown();
+ String block = reader.getValue();
+ reader.moveUp();
+
+ String[] standings = new String[15];
+
+ reader.moveDown();
+ int i = 0;
+ while (reader.hasMoreChildren()) {
+ reader.moveDown();
+ standings[i++] = reader.getValue();
+ reader.moveUp();
+ }
+ reader.moveUp();
+
+ String[] aiNames = new String[7];
+
+ reader.moveDown();
+ i = 0;
+ while (reader.hasMoreChildren()) {
+ reader.moveDown();
+ aiNames[i++] = reader.getValue();
+ reader.moveUp();
+ }
+ reader.moveUp();
+
+ int[] aiIcons = new int[7];
+
+ reader.moveDown();
+ i = 0;
+ while (reader.hasMoreChildren()) {
+ reader.moveDown();
+ aiIcons[i++] = Integer.parseInt(reader.getValue());
+ reader.moveUp();
+ }
+ reader.moveUp();
+
+ QuestEventDraft draft = new QuestEventDraft(draftName);
+ draft.setBoosterConfiguration(boosterConfiguration);
+ draft.setEntryFee(entryFee);
+ draft.setBlock(block);
+ draft.setStandings(standings);
+ draft.setAINames(aiNames);
+ draft.setAIIcons(aiIcons);
+
+ output.add(draft);
+
+ reader.moveUp();
+
+ }
+
+ return output;
+
+ }
+
+ }
private static class DeckToXml extends ItemPoolToXml {