Initial commit of the Draft Tournament for Quests.

This commit is contained in:
Krazy
2014-05-31 21:04:29 +00:00
parent 24f4dd0e24
commit 289e1c35c5
27 changed files with 2560 additions and 31 deletions

10
.gitattributes vendored
View File

@@ -820,6 +820,8 @@ forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorDraf
forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorLimited.java -text forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorLimited.java -text
forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuest.java -text forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuest.java -text
forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuestCardShop.java -text forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuestCardShop.java -text
forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuestDraftingProcess.java -text
forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuestLimited.java -text
forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorVariant.java -text forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorVariant.java -text
forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CProbabilities.java -text forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CProbabilities.java -text
forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CStatistics.java -text forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CStatistics.java -text
@@ -858,10 +860,13 @@ forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuChallenges.java
forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuDuels.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuDuels.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestData.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestData.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDecks.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDecks.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDraft.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestPrefs.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestPrefs.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/DialogChooseSets.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/DialogChooseSets.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/IVQuestStats.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/IVQuestStats.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/PnlDraftEvent.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/PnlEvent.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/PnlEvent.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/QuestDraftUtils.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/QuestFileLister.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/QuestFileLister.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/QuestPreferencesHandler.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/QuestPreferencesHandler.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/SSubmenuQuestUtil.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/SSubmenuQuestUtil.java -text
@@ -869,6 +874,7 @@ forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuChallenges.java
forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuDuels.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuDuels.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestData.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestData.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestDecks.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestDecks.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestDraft.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestPrefs.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestPrefs.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/ViewItem.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/ViewItem.java -text
forge-gui-desktop/src/main/java/forge/screens/home/quest/ViewStall.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/ViewStall.java -text
@@ -896,6 +902,7 @@ forge-gui-desktop/src/main/java/forge/screens/match/ControlWinLose.java -text
forge-gui-desktop/src/main/java/forge/screens/match/GameLogPanel.java -text forge-gui-desktop/src/main/java/forge/screens/match/GameLogPanel.java -text
forge-gui-desktop/src/main/java/forge/screens/match/GauntletWinLose.java -text forge-gui-desktop/src/main/java/forge/screens/match/GauntletWinLose.java -text
forge-gui-desktop/src/main/java/forge/screens/match/LimitedWinLose.java -text forge-gui-desktop/src/main/java/forge/screens/match/LimitedWinLose.java -text
forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java -text
forge-gui-desktop/src/main/java/forge/screens/match/QuestWinLose.java -text forge-gui-desktop/src/main/java/forge/screens/match/QuestWinLose.java -text
forge-gui-desktop/src/main/java/forge/screens/match/QuestWinLoseCardViewer.java -text forge-gui-desktop/src/main/java/forge/screens/match/QuestWinLoseCardViewer.java -text
forge-gui-desktop/src/main/java/forge/screens/match/TargetingOverlay.java -text forge-gui-desktop/src/main/java/forge/screens/match/TargetingOverlay.java -text
@@ -16437,10 +16444,12 @@ forge-gui/src/main/java/forge/properties/package-info.java svneol=native#text/pl
forge-gui/src/main/java/forge/quest/BoosterUtils.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/IQuestRewardCard.java -text
forge-gui/src/main/java/forge/quest/QuestController.java -text forge-gui/src/main/java/forge/quest/QuestController.java -text
forge-gui/src/main/java/forge/quest/QuestDeckGroupMap.java -text
forge-gui/src/main/java/forge/quest/QuestDeckMap.java -text forge-gui/src/main/java/forge/quest/QuestDeckMap.java -text
forge-gui/src/main/java/forge/quest/QuestEvent.java -text forge-gui/src/main/java/forge/quest/QuestEvent.java -text
forge-gui/src/main/java/forge/quest/QuestEventChallenge.java svneol=native#text/plain forge-gui/src/main/java/forge/quest/QuestEventChallenge.java svneol=native#text/plain
forge-gui/src/main/java/forge/quest/QuestEventDifficulty.java -text forge-gui/src/main/java/forge/quest/QuestEventDifficulty.java -text
forge-gui/src/main/java/forge/quest/QuestEventDraft.java -text
forge-gui/src/main/java/forge/quest/QuestEventDuel.java svneol=native#text/plain forge-gui/src/main/java/forge/quest/QuestEventDuel.java svneol=native#text/plain
forge-gui/src/main/java/forge/quest/QuestEventDuelManager.java -text forge-gui/src/main/java/forge/quest/QuestEventDuelManager.java -text
forge-gui/src/main/java/forge/quest/QuestMode.java -text forge-gui/src/main/java/forge/quest/QuestMode.java -text
@@ -16473,6 +16482,7 @@ forge-gui/src/main/java/forge/quest/data/GameFormatQuest.java -text
forge-gui/src/main/java/forge/quest/data/QuestAchievements.java -text forge-gui/src/main/java/forge/quest/data/QuestAchievements.java -text
forge-gui/src/main/java/forge/quest/data/QuestAssets.java -text forge-gui/src/main/java/forge/quest/data/QuestAssets.java -text
forge-gui/src/main/java/forge/quest/data/QuestData.java svneol=native#text/plain forge-gui/src/main/java/forge/quest/data/QuestData.java svneol=native#text/plain
forge-gui/src/main/java/forge/quest/data/QuestEventDraftContainer.java -text
forge-gui/src/main/java/forge/quest/data/QuestItemCondition.java -text forge-gui/src/main/java/forge/quest/data/QuestItemCondition.java -text
forge-gui/src/main/java/forge/quest/data/QuestPreferences.java svneol=native#text/plain forge-gui/src/main/java/forge/quest/data/QuestPreferences.java svneol=native#text/plain
forge-gui/src/main/java/forge/quest/data/package-info.java svneol=native#text/plain forge-gui/src/main/java/forge/quest/data/package-info.java svneol=native#text/plain

View File

@@ -13,6 +13,7 @@ public enum GameType {
Draft (DeckFormat.Limited, true, true, true, "Draft"), Draft (DeckFormat.Limited, true, true, true, "Draft"),
Gauntlet (DeckFormat.Limited, true, true, true, "Gauntlet"), Gauntlet (DeckFormat.Limited, true, true, true, "Gauntlet"),
Quest (DeckFormat.QuestDeck, true, true, false, "Quest"), Quest (DeckFormat.QuestDeck, true, true, false, "Quest"),
QuestDraft (DeckFormat.Limited, true, true, true, "Quest Draft"),
Constructed (DeckFormat.Constructed, false, true, true, "Constructed"), Constructed (DeckFormat.Constructed, false, true, true, "Constructed"),
Vanguard (DeckFormat.Vanguard, true, true, true, "Vanguard"), Vanguard (DeckFormat.Vanguard, true, true, true, "Vanguard"),
Commander (DeckFormat.Commander, false, false, false, "Commander"), Commander (DeckFormat.Commander, false, false, false, "Commander"),

View File

@@ -75,6 +75,9 @@ import forge.util.BuildInfo;
import forge.util.ITriggerEvent; import forge.util.ITriggerEvent;
public class GuiDesktop implements IGuiBase { public class GuiDesktop implements IGuiBase {
private boolean showOverlay = true;
@Override @Override
public void invokeInEdtLater(Runnable proc) { public void invokeInEdtLater(Runnable proc) {
SwingUtilities.invokeLater(proc); SwingUtilities.invokeLater(proc);
@@ -213,10 +216,22 @@ public class GuiDesktop implements IGuiBase {
} }
} }
@Override
public void disableOverlay() {
showOverlay = false;
}
@Override
public void enableOverlay() {
showOverlay = true;
}
@Override @Override
public void finishGame() { public void finishGame() {
new ViewWinLose(Singletons.getControl().getObservedGame()); new ViewWinLose(Singletons.getControl().getObservedGame());
SOverlayUtils.showOverlay(); if (showOverlay) {
SOverlayUtils.showOverlay();
}
} }
@Override @Override

View File

@@ -43,6 +43,7 @@ public enum EDocID { /** */
WORKSHOP_CARDDESIGNER (VCardDesigner.SINGLETON_INSTANCE), /** */ WORKSHOP_CARDDESIGNER (VCardDesigner.SINGLETON_INSTANCE), /** */
WORKSHOP_CARDSCRIPT (VCardScript.SINGLETON_INSTANCE), /** */ WORKSHOP_CARDSCRIPT (VCardScript.SINGLETON_INSTANCE), /** */
HOME_QUESTDRAFTS (VSubmenuQuestDraft.SINGLETON_INSTANCE), /** */
HOME_QUESTCHALLENGES (VSubmenuChallenges.SINGLETON_INSTANCE), /** */ HOME_QUESTCHALLENGES (VSubmenuChallenges.SINGLETON_INSTANCE), /** */
HOME_QUESTDUELS (VSubmenuDuels.SINGLETON_INSTANCE), /** */ HOME_QUESTDUELS (VSubmenuDuels.SINGLETON_INSTANCE), /** */
HOME_QUESTDATA (VSubmenuQuestData.SINGLETON_INSTANCE), /** */ HOME_QUESTDATA (VSubmenuQuestData.SINGLETON_INSTANCE), /** */

View File

@@ -113,6 +113,14 @@ public enum FScreen {
true, true,
"Close Editor", "Close Editor",
ForgeConstants.EDITOR_LAYOUT_FILE), ForgeConstants.EDITOR_LAYOUT_FILE),
DECK_EDITOR_QUEST_TOURNAMENT(
VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE,
"Quest Tournament Deck Editor",
FSkin.getImage(FSkinProp.IMG_PACK),
true,
"Close Editor",
ForgeConstants.EDITOR_LAYOUT_FILE),
QUEST_CARD_SHOP( QUEST_CARD_SHOP(
VDeckEditorUI.SINGLETON_INSTANCE, VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE, CDeckEditorUI.SINGLETON_INSTANCE,

View File

@@ -0,0 +1,318 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package forge.screens.deckeditor.controllers;
import java.util.Map.Entry;
import forge.card.MagicColor;
import forge.deck.Deck;
import forge.deck.DeckGroup;
import forge.deck.DeckSection;
import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen;
import forge.item.PaperCard;
import forge.itemmanager.CardManager;
import forge.itemmanager.ItemManagerConfig;
import forge.limited.BoosterDraft;
import forge.limited.IBoosterDraft;
import forge.model.FModel;
import forge.properties.ForgePreferences.FPref;
import forge.screens.deckeditor.views.VAllDecks;
import forge.screens.deckeditor.views.VCurrentDeck;
import forge.screens.deckeditor.views.VDeckgen;
import forge.screens.home.quest.CSubmenuQuestDraft;
import forge.toolbox.FOptionPane;
import forge.util.ItemPool;
import forge.util.MyRandom;
/**
* Updates the deck editor UI as necessary draft selection mode.
*
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
*
* @author Forge
* @version $Id: CEditorDraftingProcess.java 24872 2014-02-17 07:35:47Z drdev $
*/
public class CEditorQuestDraftingProcess extends ACEditorBase<PaperCard, DeckGroup> {
private CSubmenuQuestDraft testDraftQuest;
public void setDraftQuest(CSubmenuQuestDraft testDraftQuest) {
this.testDraftQuest = testDraftQuest;
}
private IBoosterDraft boosterDraft;
private String ccAddLabel = "Add card";
private DragCell allDecksParent = null;
private DragCell deckGenParent = null;
private boolean saved = false;
//========== Constructor
/**
* Updates the deck editor UI as necessary draft selection mode.
*/
public CEditorQuestDraftingProcess() {
super(FScreen.DRAFTING_PROCESS);
final CardManager catalogManager = new CardManager(false);
final CardManager deckManager = new CardManager(false);
//hide filters and options panel so more of pack is visible by default
catalogManager.setHideViewOptions(1, true);
deckManager.setCaption("Draft Picks");
catalogManager.setAlwaysNonUnique(true);
deckManager.setAlwaysNonUnique(true);
this.setCatalogManager(catalogManager);
this.setDeckManager(deckManager);
}
/**
* Show gui.
*
* @param inBoosterDraft
* the in_booster draft
*/
public final void showGui(final IBoosterDraft inBoosterDraft) {
this.boosterDraft = inBoosterDraft;
}
/* (non-Javadoc)
* @see forge.gui.deckeditor.ACEditorBase#onAddItems()
*/
@Override
protected void onAddItems(Iterable<Entry<PaperCard, Integer>> items, boolean toAlternate) {
if (toAlternate) { return; }
// can only draft one at a time, regardless of the requested quantity
PaperCard card = items.iterator().next().getKey();
this.getDeckManager().addItem(card, 1);
// get next booster pack
this.boosterDraft.setChoice(card);
if (this.boosterDraft.hasNextChoice()) {
this.showChoices(this.boosterDraft.nextChoice());
}
else {
this.boosterDraft.finishedDrafting();
this.saveDraft();
}
}
/* (non-Javadoc)
* @see forge.gui.deckeditor.ACEditorBase#onRemoveItems()
*/
@Override
protected void onRemoveItems(Iterable<Entry<PaperCard, Integer>> items, boolean toAlternate) {
}
@Override
protected void buildAddContextMenu(EditorContextMenuBuilder cmb) {
cmb.addMoveItems("Draft", null);
}
@Override
protected void buildRemoveContextMenu(EditorContextMenuBuilder cmb) {
// no valid remove options
}
/**
* <p>
* showChoices.
* </p>
*
* @param list
* a {@link forge.CardList} object.
*/
private void showChoices(final ItemPool<PaperCard> list) {
int packNumber = ((BoosterDraft) boosterDraft).getCurrentBoosterIndex() + 1;
this.getCatalogManager().setCaption("Pack " + packNumber + " - Cards");
this.getCatalogManager().setPool(list);
} // showChoices()
/**
* <p>
* getPlayersDeck.
* </p>
*
* @return a {@link forge.deck.Deck} object.
*/
public Deck getPlayersDeck() {
final Deck deck = new Deck();
// add sideboard to deck
deck.getOrCreate(DeckSection.Sideboard).addAll(this.getDeckManager().getPool());
final String landSet = IBoosterDraft.LAND_SET_CODE[0].getCode();
final boolean isZendikarSet = landSet.equals("ZEN"); // we want to generate one kind of Zendikar lands at a time only
final boolean zendikarSetMode = MyRandom.getRandom().nextBoolean();
final int landsCount = 10;
for(String landName : MagicColor.Constant.BASIC_LANDS) {
int numArt = FModel.getMagicDb().getCommonCards().getArtCount(landName, landSet);
int minArtIndex = isZendikarSet ? (zendikarSetMode ? 1 : 5) : 1;
int maxArtIndex = isZendikarSet ? minArtIndex + 3 : numArt;
if (FModel.getPreferences().getPrefBoolean(FPref.UI_RANDOM_ART_IN_POOLS)) {
for (int i = minArtIndex; i <= maxArtIndex; i++) {
deck.get(DeckSection.Sideboard).add(landName, landSet, i, numArt > 1 ? landsCount : 30);
}
} else {
deck.get(DeckSection.Sideboard).add(landName, landSet, 30);
}
}
return deck;
} // getPlayersDeck()
/**
* <p>
* saveDraft.
* </p>
*/
private void saveDraft() {
String s = "Tournament Deck";
saved = true;
// Construct computer's decks and save draft
final Deck[] computer = this.boosterDraft.getDecks();
final DeckGroup finishedDraft = new DeckGroup(s);
finishedDraft.setHumanDeck((Deck) this.getPlayersDeck().copyTo(s));
finishedDraft.addAiDecks(computer);
CSubmenuQuestDraft.SINGLETON_INSTANCE.update();
FScreen.DRAFTING_PROCESS.close();
testDraftQuest.setCompletedDraft(finishedDraft, s);
}
//========== Overridden from ACEditorBase
@Override
protected CardLimit getCardLimit() {
return CardLimit.None;
}
/*
* (non-Javadoc)
*
* @see forge.gui.deckeditor.ACEditorBase#getController()
*/
@Override
public DeckController<DeckGroup> getDeckController() {
return null;
}
/*
* (non-Javadoc)
*
* @see forge.gui.deckeditor.ACEditorBase#updateView()
*/
@Override
public void resetTables() {
}
/*
* (non-Javadoc)
*
* @see forge.gui.deckeditor.ACEditorBase#show(forge.Command)
*/
@Override
public void update() {
this.getCatalogManager().setup(ItemManagerConfig.DRAFT_PACK);
this.getDeckManager().setup(ItemManagerConfig.DRAFT_POOL);
ccAddLabel = this.getBtnAdd().getText();
if (this.getDeckManager().getPool() == null) { //avoid showing next choice or resetting pool if just switching back to Draft screen
this.showChoices(this.boosterDraft.nextChoice());
this.getDeckManager().setPool((Iterable<PaperCard>) null);
}
else {
this.showChoices(this.getCatalogManager().getPool());
}
//Remove buttons
this.getBtnAdd().setVisible(false);
this.getBtnAdd4().setVisible(false);
this.getBtnRemove().setVisible(false);
this.getBtnRemove4().setVisible(false);
this.getBtnCycleSection().setVisible(false);
VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(false);
deckGenParent = removeTab(VDeckgen.SINGLETON_INSTANCE);
allDecksParent = removeTab(VAllDecks.SINGLETON_INSTANCE);
// set catalog table to single-selection only mode
getCatalogManager().setAllowMultipleSelections(false);
}
/* (non-Javadoc)
* @see forge.gui.deckeditor.controllers.ACEditorBase#canSwitchAway()
*/
@Override
public boolean canSwitchAway(boolean isClosing) {
if (isClosing && !saved) {
String userPrompt =
"This will end the current draft and you will not be able to resume.\n\n" +
"Leave anyway?";
return FOptionPane.showConfirmDialog(userPrompt, "Leave Draft?", "Leave", "Cancel", false);
}
return true;
}
/* (non-Javadoc)
* @see forge.gui.deckeditor.controllers.ACEditorBase#resetUIChanges()
*/
@Override
public void resetUIChanges() {
//Re-rename buttons
this.getBtnAdd().setText(ccAddLabel);
//Re-add buttons
this.getBtnAdd4().setVisible(true);
this.getBtnRemove().setVisible(true);
this.getBtnRemove4().setVisible(true);
VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(true);
//Re-add tabs
if (deckGenParent != null) {
deckGenParent.addDoc(VDeckgen.SINGLETON_INSTANCE);
}
if (allDecksParent != null) {
allDecksParent.addDoc(VAllDecks.SINGLETON_INSTANCE);
}
// set catalog table back to free-selection mode
getCatalogManager().setAllowMultipleSelections(true);
}
}

View File

@@ -0,0 +1,299 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package forge.screens.deckeditor.controllers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import forge.deck.Deck;
import forge.deck.DeckGroup;
import forge.deck.DeckSection;
import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen;
import forge.item.InventoryItem;
import forge.item.PaperCard;
import forge.itemmanager.CardManager;
import forge.itemmanager.ColumnDef;
import forge.itemmanager.ItemManagerConfig;
import forge.itemmanager.views.ItemTableColumn;
import forge.model.FModel;
import forge.properties.ForgePreferences.FPref;
import forge.quest.QuestController;
import forge.quest.QuestEventDraft;
import forge.screens.deckeditor.SEditorIO;
import forge.screens.deckeditor.views.VAllDecks;
import forge.screens.deckeditor.views.VCurrentDeck;
import forge.screens.deckeditor.views.VDeckgen;
import forge.screens.home.quest.CSubmenuQuestDecks;
//import forge.quest.data.QuestBoosterPack;
/**
* Child controller for quest deck editor UI.
* <br><br>
* Card catalog and decks are drawn from a QuestController object.
*
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
*
* @author Forge
* @version $Id: CEditorQuest.java 24868 2014-02-17 05:08:05Z drdev $
*/
public final class CEditorQuestLimited extends ACEditorBase<PaperCard, DeckGroup> {
private final QuestController questData;
private final DeckController<DeckGroup> controller;
private final List<DeckSection> allSections = new ArrayList<DeckSection>();
private DragCell allDecksParent = null;
private DragCell deckGenParent = null;
private Map<PaperCard, Integer> decksUsingMyCards;
private final Function<Entry<InventoryItem, Integer>, Comparable<?>> fnDeckCompare = new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
@Override
public Comparable<?> apply(final Entry<InventoryItem, Integer> from) {
final Integer iValue = decksUsingMyCards.get(from.getKey());
return iValue == null ? Integer.valueOf(0) : iValue;
}
};
private final Function<Entry<? extends InventoryItem, Integer>, Object> fnDeckGet = new Function<Entry<? extends InventoryItem, Integer>, Object>() {
@Override
public Object apply(final Entry<? extends InventoryItem, Integer> from) {
final Integer iValue = decksUsingMyCards.get(from.getKey());
return iValue == null ? "" : iValue.toString();
}
};
/**
* Child controller for quest deck editor UI.
* <br><br>
* Card catalog and decks are drawn from a QuestController object.
*
* @param questData0 &emsp; {@link forge.quest.QuestController}
*/
public CEditorQuestLimited(final QuestController questData0) {
super(FScreen.DECK_EDITOR_QUEST_TOURNAMENT);
allSections.add(DeckSection.Main);
allSections.add(DeckSection.Sideboard);
this.questData = questData0;
final CardManager catalogManager = new CardManager(false);
final CardManager deckManager = new CardManager(false);
catalogManager.setCaption("Sideboard");
catalogManager.setAlwaysNonUnique(true);
deckManager.setAlwaysNonUnique(true);
this.setCatalogManager(catalogManager);
this.setDeckManager(deckManager);
final Supplier<DeckGroup> newCreator = new Supplier<DeckGroup>() {
@Override
public DeckGroup get() {
return new DeckGroup("");
}
};
this.controller = new DeckController<DeckGroup>(questData0.getDraftDecks(), this, newCreator);
controller.getView().getDeckManager().setup(ItemManagerConfig.DRAFT_POOL);
controller.setModel(questData0.getDraftDecks().get(QuestEventDraft.DECK_NAME));
}
/**
* Adds any card to the catalog and data pool.
*
* @param card {@link forge.item.PaperCard}
*/
public void addCheatCard(final PaperCard card, int qty) {
this.getCatalogManager().addItem(card, qty);
this.questData.getCards().getCardpool().add(card, qty);
}
// fills number of decks using each card
private Map<PaperCard, Integer> countDecksForEachCard() {
final Map<PaperCard, Integer> result = new HashMap<PaperCard, Integer>();
for (final Deck deck : this.questData.getMyDecks()) {
for (final Entry<PaperCard, Integer> e : deck.getMain()) {
final PaperCard card = e.getKey();
final Integer amount = result.get(card);
result.put(card, Integer.valueOf(amount == null ? 1 : 1 + amount.intValue()));
}
}
return result;
}
//=========== Overridden from ACEditorBase
@Override
protected CardLimit getCardLimit() {
if (FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) {
return CardLimit.Default;
}
return CardLimit.None; //if not enforcing deck legality, don't enforce default limit
}
/* (non-Javadoc)
* @see forge.gui.deckeditor.ACEditorBase#onAddItems()
*/
@Override
protected void onAddItems(Iterable<Entry<PaperCard, Integer>> items, boolean toAlternate) {
if (toAlternate) { return; }
// update view
this.getDeckManager().addItems(items);
this.getCatalogManager().removeItems(items);
this.getDeckController().notifyModelChanged();
}
/* (non-Javadoc)
* @see forge.gui.deckeditor.ACEditorBase#onRemoveItems()
*/
@Override
protected void onRemoveItems(Iterable<Entry<PaperCard, Integer>> items, boolean toAlternate) {
if (toAlternate) { return; }
// update view
this.getCatalogManager().addItems(items);
this.getDeckManager().removeItems(items);
this.getDeckController().notifyModelChanged();
}
/* (non-Javadoc)
* @see forge.gui.deckeditor.ACEditorBase#buildAddContextMenu()
*/
@Override
protected void buildAddContextMenu(EditorContextMenuBuilder cmb) {
cmb.addMoveItems("Move", "to deck");
}
/* (non-Javadoc)
* @see forge.gui.deckeditor.ACEditorBase#buildRemoveContextMenu()
*/
@Override
protected void buildRemoveContextMenu(EditorContextMenuBuilder cmb) {
cmb.addMoveItems("Move", "to sideboard");
}
private Deck getSelectedDeck(final DeckGroup model) {
return model.getHumanDeck();
}
/*
* (non-Javadoc)
*
* @see forge.gui.deckeditor.ACEditorBase#updateView()
*/
@Override
public void resetTables() {
final Deck toEdit = this.getSelectedDeck(this.controller.getModel());
this.getCatalogManager().setPool(toEdit.getOrCreate(DeckSection.Sideboard));
this.getDeckManager().setPool(toEdit.getMain());
}
//=========== Overridden from ACEditorBase
/*
* (non-Javadoc)
*
* @see forge.gui.deckeditor.ACEditorBase#getController()
*/
@Override
public DeckController<DeckGroup> getDeckController() {
return this.controller;
}
@Override
public void update() {
this.getCatalogManager().setup(getScreen() == FScreen.DECK_EDITOR_DRAFT ? ItemManagerConfig.DRAFT_POOL : ItemManagerConfig.SEALED_POOL);
this.getDeckManager().setup(ItemManagerConfig.DECK_EDITOR);
this.decksUsingMyCards = this.countDecksForEachCard();
final Map<ColumnDef, ItemTableColumn> colOverridesCatalog = new HashMap<ColumnDef, ItemTableColumn>();
final Map<ColumnDef, ItemTableColumn> colOverridesDeck = new HashMap<ColumnDef, ItemTableColumn>();
ItemTableColumn.addColOverride(ItemManagerConfig.QUEST_EDITOR_POOL, colOverridesCatalog, ColumnDef.NEW, this.questData.getCards().getFnNewCompare(), this.questData.getCards().getFnNewGet());
ItemTableColumn.addColOverride(ItemManagerConfig.QUEST_DECK_EDITOR, colOverridesDeck, ColumnDef.NEW, this.questData.getCards().getFnNewCompare(), this.questData.getCards().getFnNewGet());
ItemTableColumn.addColOverride(ItemManagerConfig.QUEST_DECK_EDITOR, colOverridesDeck, ColumnDef.DECKS, this.fnDeckCompare, this.fnDeckGet);
this.getCatalogManager().setup(ItemManagerConfig.QUEST_EDITOR_POOL, colOverridesCatalog);
this.getDeckManager().setup(ItemManagerConfig.QUEST_DECK_EDITOR, colOverridesDeck);
resetUI();
VCurrentDeck.SINGLETON_INSTANCE.getBtnSave().setVisible(true);
VCurrentDeck.SINGLETON_INSTANCE.getBtnImport().setVisible(false);
VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setEnabled(false);
deckGenParent = removeTab(VDeckgen.SINGLETON_INSTANCE);
allDecksParent = removeTab(VAllDecks.SINGLETON_INSTANCE);
if (this.controller.getModel() == null) {
throw new RuntimeException("Expected deck group but found none!");
}
else {
this.controller.refreshModel();
}
}
/* (non-Javadoc)
* @see forge.gui.deckeditor.controllers.ACEditorBase#canSwitchAway()
*/
@Override
public boolean canSwitchAway(boolean isClosing) {
if (SEditorIO.confirmSaveChanges(FScreen.DECK_EDITOR_QUEST_TOURNAMENT, isClosing)) {
FModel.getQuest().save();
return true;
}
return false;
}
/* (non-Javadoc)
* @see forge.gui.deckeditor.controllers.ACEditorBase#resetUIChanges()
*/
@Override
public void resetUIChanges() {
CSubmenuQuestDecks.SINGLETON_INSTANCE.update();
//Re-add tabs
if (deckGenParent != null) {
deckGenParent.addDoc(VDeckgen.SINGLETON_INSTANCE);
}
if (allDecksParent != null) {
allDecksParent.addDoc(VAllDecks.SINGLETON_INSTANCE);
}
}
/**
* TODO: Write javadoc for this method.
* @param d0
*/
/*public void load(Deck deck) {
controller.setModel(deck);
}*/
}

View File

@@ -118,6 +118,7 @@ public enum VHomeUI implements IVTopLevelUI {
allSubmenus.add(VSubmenuDuels.SINGLETON_INSTANCE); allSubmenus.add(VSubmenuDuels.SINGLETON_INSTANCE);
allSubmenus.add(VSubmenuChallenges.SINGLETON_INSTANCE); allSubmenus.add(VSubmenuChallenges.SINGLETON_INSTANCE);
allSubmenus.add(VSubmenuQuestDraft.SINGLETON_INSTANCE);
allSubmenus.add(VSubmenuQuestDecks.SINGLETON_INSTANCE); allSubmenus.add(VSubmenuQuestDecks.SINGLETON_INSTANCE);
allSubmenus.add(VSubmenuQuestData.SINGLETON_INSTANCE); allSubmenus.add(VSubmenuQuestData.SINGLETON_INSTANCE);
allSubmenus.add(VSubmenuQuestPrefs.SINGLETON_INSTANCE); allSubmenus.add(VSubmenuQuestPrefs.SINGLETON_INSTANCE);

View File

@@ -0,0 +1,384 @@
package forge.screens.home.quest;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;
import forge.Singletons;
import forge.UiCommand;
import forge.assets.FSkinProp;
import forge.deck.CardPool;
import forge.deck.Deck;
import forge.deck.DeckGroup;
import forge.deck.DeckSection;
import forge.game.GameType;
import forge.gui.framework.EDocID;
import forge.gui.framework.FScreen;
import forge.gui.framework.ICDoc;
import forge.itemmanager.DeckManager;
import forge.limited.BoosterDraft;
import forge.limited.LimitedPoolType;
import forge.model.FModel;
import forge.properties.ForgePreferences.FPref;
import forge.quest.QuestController;
import forge.quest.QuestEventDraft;
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.CHomeUI;
import forge.screens.home.quest.VSubmenuQuestDraft.Mode;
import forge.screens.home.sanctioned.CSubmenuDraft;
import forge.toolbox.FOptionPane;
import forge.toolbox.FSkin;
import forge.toolbox.JXButtonPanel;
import forge.util.storage.IStorage;
/**
* Controls the quest draft submenu in the home UI.
*
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
*
*/
public enum CSubmenuQuestDraft implements ICDoc {
SINGLETON_INSTANCE;
private static final DecimalFormat NUMBER_FORMATTER = new DecimalFormat("#,###");
@SuppressWarnings("serial")
@Override
public void initialize() {
final VSubmenuQuestDraft view = VSubmenuQuestDraft.SINGLETON_INSTANCE;
if (FModel.getQuest().getDraftDecks() == null || !FModel.getQuest().getDraftDecks().contains(QuestEventDraft.DECK_NAME)) {
view.setMode(Mode.SELECT_TOURNAMENT);
} else if (!FModel.getQuest().getAchievements().isTournamentActive()) {
view.setMode(Mode.PREPARE_DECK);
} else {
view.setMode(Mode.TOURNAMENT_ACTIVE);
}
view.getBtnStartDraft().addActionListener(selectTournamentStart);
view.getBtnStartTournament().addActionListener(prepareDeckStart);
view.getBtnStartMatch().addActionListener(nextMatchStart);
view.getBtnEditDeck().setCommand(
new UiCommand() { @Override
public void run() { CSubmenuQuestDraft.this.editDeck(); } });
view.getBtnLeaveTournament().setCommand(
new UiCommand() { @Override
public void run() { CSubmenuQuestDraft.this.TEMP_END_TOURNAMENT(); } });
}
private void TEMP_END_TOURNAMENT() {
// TODO Integrate better
Deck deck = FModel.getQuest().getDraftDecks().get(QuestEventDraft.DECK_NAME).getHumanDeck();
FModel.getQuest().getCards().addAllCards(deck.getAllCardsInASinglePool().toFlatList());
if (FOptionPane.showOptionDialog("Add this draft to normal mode?", "Add Draft?", FSkin.getImage(FSkinProp.ICO_QUESTION), new String[] { "Yes", "No" }) == 0) {
String tournamentName = FModel.getQuest().getName() + " Tournament Deck " + new SimpleDateFormat("EEE d MMM yyyy HH-mm-ss").format(new Date());
DeckGroup original = FModel.getQuest().getDraftDecks().get(QuestEventDraft.DECK_NAME);
DeckGroup output = new DeckGroup(tournamentName);
for (Deck aiDeck : original.getAiDecks()) {
output.addAiDeck(copyDeck(aiDeck));
}
output.setHumanDeck(copyDeck(original.getHumanDeck(), tournamentName));
FModel.getDecks().getDraft().add(output);
CSubmenuDraft.SINGLETON_INSTANCE.update();
}
if (deck.get(DeckSection.Main).countAll() > 0) {
FModel.getQuest().getMyDecks().add(FModel.getQuest().getDraftDecks().get(QuestEventDraft.DECK_NAME).getHumanDeck());
FModel.getQuest().getMyDecks().get(QuestEventDraft.DECK_NAME).get(DeckSection.Sideboard).clear();
}
FModel.getQuest().getDraftDecks().delete(QuestEventDraft.DECK_NAME);
FModel.getQuest().getAchievements().endCurrentTournament();
FModel.getQuest().save();
VSubmenuQuestDraft view = VSubmenuQuestDraft.SINGLETON_INSTANCE;
view.setMode(Mode.SELECT_TOURNAMENT);
view.populate();
CSubmenuQuestDraft.SINGLETON_INSTANCE.update();
}
private final ActionListener selectTournamentStart = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
CSubmenuQuestDraft.this.startDraft();
}
};
private final ActionListener prepareDeckStart = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
//TODO Refactor the deck getting to a single method
String message = GameType.QuestDraft.getDecksFormat().getDeckConformanceProblem(FModel.getQuest().getAssets().getDraftDeckStorage().get(QuestEventDraft.DECK_NAME).getHumanDeck());
if (message != null) {
//TODO Pref for allowing non-conformant decks
FOptionPane.showMessageDialog(message, "Deck Invalid");
return;
}
CSubmenuQuestDraft.this.startTournament();
}
};
private final ActionListener nextMatchStart = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
QuestDraftUtils.startNextMatch();
}
};
private final KeyAdapter startOnEnter = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (KeyEvent.VK_ENTER == e.getKeyChar()) {
VSubmenuQuestDraft.SINGLETON_INSTANCE.getBtnStartDraft().doClick();
}
}
};
private final MouseAdapter startOnDblClick = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (MouseEvent.BUTTON1 == e.getButton() && 2 == e.getClickCount()) {
VSubmenuQuestDraft.SINGLETON_INSTANCE.getBtnStartDraft().doClick();
}
}
};
@Override
public void update() {
VSubmenuQuestDraft view = VSubmenuQuestDraft.SINGLETON_INSTANCE;
if (FModel.getQuest().getAchievements() == null) {
return;
}
QuestDraftUtils.update();
QuestAchievements achievements = FModel.getQuest().getAchievements();
achievements.generateNewTournaments();
switch (view.getMode()) {
case SELECT_TOURNAMENT:
updateSelectTournament();
break;
case PREPARE_DECK:
updatePrepareDeck();
break;
case TOURNAMENT_ACTIVE:
updateTournamentActive();
break;
default:
break;
}
}
private void updateSelectTournament() {
VSubmenuQuestDraft view = VSubmenuQuestDraft.SINGLETON_INSTANCE;
view.getLblCredits().setText("Available Credits: " + NUMBER_FORMATTER.format(FModel.getQuest().getAssets().getCredits()));
FModel.getQuest().getAchievements().generateNewTournaments();
view.getPnlTournaments().removeAll();
JXButtonPanel grpPanel = new JXButtonPanel();
boolean firstPanel = true;
for (QuestEventDraft draft : FModel.getQuest().getAchievements().getDraftEvents()) {
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%!");
}
private void updatePrepareDeck() {
}
private void updateTournamentActive() {
VSubmenuQuestDraft view = VSubmenuQuestDraft.SINGLETON_INSTANCE;
if (FModel.getQuest().getAchievements().getCurrentDraft() == null) {
return;
}
for (int i = 0; i < 15; i++) {
String playerID = FModel.getQuest().getAchievements().getCurrentDraft().getStandings()[i];
if (playerID.equals(QuestEventDraft.HUMAN)) {
playerID = FModel.getPreferences().getPref(FPref.PLAYER_NAME);
} else if (playerID.equals(QuestEventDraft.UNDETERMINED)) {
playerID = "Undetermined";
} else {
playerID = FModel.getQuest().getAchievements().getCurrentDraft().getAINames()[Integer.parseInt(playerID) - 1];
}
view.getLblsStandings()[i].setText(playerID);
}
}
public void setCompletedDraft(DeckGroup finishedDraft, String s) {
List<Deck> aiDecks = new ArrayList<Deck>(finishedDraft.getAiDecks());
finishedDraft.getAiDecks().clear();
for (int i = 0; i < aiDecks.size(); i++) {
Deck oldDeck = aiDecks.get(i);
Deck namedDeck = new Deck("AI Deck " + i);
namedDeck.putSection(DeckSection.Main, oldDeck.get(DeckSection.Main));
namedDeck.putSection(DeckSection.Sideboard, oldDeck.get(DeckSection.Sideboard));
finishedDraft.getAiDecks().add(namedDeck);
}
IStorage<DeckGroup> draft = FModel.getQuest().getDraftDecks();
draft.add(finishedDraft);
Singletons.getControl().setCurrentScreen(FScreen.DECK_EDITOR_QUEST_TOURNAMENT);
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(new CEditorQuestLimited(FModel.getQuest()));
FModel.getQuest().save();
VSubmenuQuestDraft.SINGLETON_INSTANCE.setMode(Mode.PREPARE_DECK);
VSubmenuQuestDraft.SINGLETON_INSTANCE.populate();
}
private void editDeck() {
VCurrentDeck.SINGLETON_INSTANCE.setItemManager(new DeckManager(GameType.Draft));
Singletons.getControl().setCurrentScreen(FScreen.DECK_EDITOR_QUEST_TOURNAMENT);
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(new CEditorQuestLimited(FModel.getQuest()));
FModel.getQuest().save();
}
private void startDraft() {
QuestEventDraft draftEvent = SSubmenuQuestUtil.getDraftEvent();
/*long creditsAvailable = FModel.getQuest().getAssets().getCredits();
if (creditsAvailable < draftEvent.getEntryFee()) {
FOptionPane.showMessageDialog("You need " + NUMBER_FORMATTER.format(draftEvent.getEntryFee() - creditsAvailable) + " more credits to enter this tournament.", "Not Enough Credits");
return;
}*/
boolean okayToEnter = FOptionPane.showConfirmDialog("This tournament costs " + draftEvent.getEntryFee() + " credits to enter.\nAre you sure you wish to enter?", "Enter Draft Tournament?");
if (!okayToEnter) {
return;
}
FModel.getQuest().getAchievements().setCurrentDraft(draftEvent);
//TODO What happens when the draft is quit early
FModel.getQuest().getAssets().subtractCredits(draftEvent.getEntryFee());
BoosterDraft draft = BoosterDraft.createDraft(LimitedPoolType.Block, FModel.getBlocks().get(draftEvent.getBlock()), draftEvent.getBoosterConfiguration());
final CEditorQuestDraftingProcess draftController = new CEditorQuestDraftingProcess();
draftController.showGui(draft);
draftController.setDraftQuest(CSubmenuQuestDraft.this);
Singletons.getControl().setCurrentScreen(FScreen.DRAFTING_PROCESS);
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(draftController);
}
private void startTournament() {
VSubmenuQuestDraft.SINGLETON_INSTANCE.setMode(Mode.TOURNAMENT_ACTIVE);
VSubmenuQuestDraft.SINGLETON_INSTANCE.populate();
update();
// TODO All the stuff needed for the tournament itself
}
private Deck copyDeck(final Deck deck) {
Deck outputDeck = new Deck(deck.getName());
outputDeck.putSection(DeckSection.Main, new CardPool(deck.get(DeckSection.Main)));
outputDeck.putSection(DeckSection.Sideboard, new CardPool(deck.get(DeckSection.Sideboard)));
return outputDeck;
}
private Deck copyDeck(final Deck deck, final String deckName) {
Deck outputDeck = new Deck(deckName);
outputDeck.putSection(DeckSection.Main, new CardPool(deck.get(DeckSection.Main)));
outputDeck.putSection(DeckSection.Sideboard, new CardPool(deck.get(DeckSection.Sideboard)));
return outputDeck;
}
@Override
public UiCommand getCommandOnSelect() {
final QuestController qc = FModel.getQuest();
return new UiCommand() {
private static final long serialVersionUID = 6153589785507038445L;
@Override
public void run() {
if (qc.getAchievements() == null) {
CHomeUI.SINGLETON_INSTANCE.itemClick(EDocID.HOME_QUESTDATA);
}
}
};
}
}

View File

@@ -0,0 +1,88 @@
package forge.screens.home.quest;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.text.DecimalFormat;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.miginfocom.swing.MigLayout;
import forge.model.FModel;
import forge.quest.QuestEventDraft;
import forge.toolbox.FRadioButton;
import forge.toolbox.FSkin;
import forge.toolbox.FSkin.SkinColor;
import forge.toolbox.FTextArea;
public class PnlDraftEvent extends JPanel {
private static final long serialVersionUID = 7348489421342846451L;
private static final DecimalFormat NUMBER_FORMATTER = new DecimalFormat("#,###");
private final Color clr2 = new Color(255, 255, 0, 0);
private final SkinColor clr3 = FSkin.getColor(FSkin.Colors.CLR_THEME2).alphaColor(200);
private final FRadioButton radButton;
public PnlDraftEvent(final QuestEventDraft event) {
super();
radButton = new FRadioButton(event.getTitle());
radButton.setFont(FSkin.getBoldFont(20));
radButton.setIconTextGap(10);
final FTextArea eventBoosters = new FTextArea();
final FTextArea eventFee = new FTextArea();
String boosterList = "";
for (int i = 0; i < event.getBoosterConfiguration().length; i++) {
boosterList += FModel.getMagicDb().getEditions().get(event.getBoosterConfiguration()[i]).getName();
if (i != event.getBoosterConfiguration().length - 1) {
boosterList += " | ";
}
}
eventBoosters.setText(boosterList);
eventBoosters.setFont(FSkin.getFont(12));
eventFee.setText(NUMBER_FORMATTER.format(event.getEntryFee()) + " Credit Entry Fee");
eventFee.setFont(FSkin.getFont(12));
radButton.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent arg0) {
if (radButton.isSelected()) {
SSubmenuQuestUtil.setDraftEvent(event);
}
}
});
this.setOpaque(false);
this.setLayout(new MigLayout("insets 0, gap 0, wrap"));
this.add(radButton, "gap 25px 0 20px 0");
this.add(eventBoosters, "w 100% - 25px!, gap 25px 0 15px 0");
this.add(eventFee, "w 100% - 25px!, gap 25px 0 10px 0");
}
public FRadioButton getRadioButton() {
return radButton;
}
@Override
public void paintComponent(final Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
FSkin.setGraphicsGradientPaint(g2d, 0, 0, clr3, (int) (getWidth() * 0.75), 0, clr2);
g2d.fillRect(0, 0, (int) (getWidth() * 0.75), getHeight());
g2d.dispose();
}
}

View File

@@ -0,0 +1,181 @@
package forge.screens.home.quest;
import java.util.ArrayList;
import java.util.List;
import javax.swing.SwingUtilities;
import forge.GuiBase;
import forge.Singletons;
import forge.deck.DeckGroup;
import forge.game.Game;
import forge.game.GameType;
import forge.game.player.RegisteredPlayer;
import forge.gui.SOverlayUtils;
import forge.gui.framework.FScreen;
import forge.model.FModel;
import forge.quest.QuestEventDraft;
public class QuestDraftUtils {
private static List<DraftMatchup> matchups = new ArrayList<DraftMatchup>();
public static boolean matchInProgress = false;
private static boolean waitForUserInput = false;
public static void continueMatch(Game lastGame) {
if (lastGame.getMatch().isMatchOver()) {
matchInProgress = false;
}
if (!matchInProgress) {
// Reset other stuff
Singletons.getControl().endCurrentGame();
Singletons.getControl().setCurrentScreen(FScreen.HOME_SCREEN);
} else {
Singletons.getControl().endCurrentGame();
Singletons.getControl().startGameWithUi(lastGame.getMatch());
}
}
public static void startNextMatch() {
matchups.clear();
QuestEventDraft draft = FModel.getQuest().getAchievements().getCurrentDraft();
String[] currentStandings = draft.getStandings();
int currentSet = -1;
for (int i = currentStandings.length - 1; i >= 0; i--) {
if (!currentStandings[i].equals(QuestEventDraft.UNDETERMINED)) {
currentSet = i;
break;
}
}
switch (currentSet) {
case 7:
addMatchup(0, 1, draft);
addMatchup(2, 3, draft);
addMatchup(4, 5, draft);
addMatchup(6, 7, draft);
break;
case 11:
addMatchup(8, 9, draft);
addMatchup(10, 11, draft);
break;
case 13:
addMatchup(12, 13, draft);
break;
case 14:
default:
return;
}
update();
}
private static void addMatchup(final int player1, final int player2, final QuestEventDraft draft) {
DraftMatchup matchup = new DraftMatchup();
DeckGroup decks = FModel.getQuest().getAssets().getDraftDeckStorage().get(QuestEventDraft.DECK_NAME);
int humanIndex = -1;
int aiIndex = -1;
if (draft.getStandings()[player1].equals(QuestEventDraft.HUMAN)) {
humanIndex = player1;
aiIndex = player2;
} else if (draft.getStandings()[player2].equals(QuestEventDraft.HUMAN)) {
humanIndex = player2;
aiIndex = player1;
}
if (humanIndex > -1) {
matchup.hasHumanPlayer = true;
matchup.matchStarter.add(new RegisteredPlayer(decks.getHumanDeck()).setPlayer(GuiBase.getInterface().getGuiPlayer()));
int aiName = Integer.parseInt(draft.getStandings()[aiIndex]) - 1;
int aiDeckIndex = Integer.parseInt(draft.getStandings()[aiIndex]) - 1;
matchup.matchStarter.add(new RegisteredPlayer(decks.getAiDecks().get(aiDeckIndex)).setPlayer(GuiBase.getInterface().createAiPlayer(draft.getAINames()[aiName], draft.getAIIcons()[aiName])));
} else {
int aiName1 = Integer.parseInt(draft.getStandings()[player1]) - 1;
int aiName2 = Integer.parseInt(draft.getStandings()[player2]) - 1;
int aiDeckIndex = Integer.parseInt(draft.getStandings()[player1]) - 1;
matchup.matchStarter.add(new RegisteredPlayer(decks.getAiDecks().get(aiDeckIndex)).setPlayer(GuiBase.getInterface().createAiPlayer(draft.getAINames()[aiName1], draft.getAIIcons()[aiName1])));
aiDeckIndex = Integer.parseInt(draft.getStandings()[player2]) - 1;
matchup.matchStarter.add(new RegisteredPlayer(decks.getAiDecks().get(aiDeckIndex)).setPlayer(GuiBase.getInterface().createAiPlayer(draft.getAINames()[aiName2], draft.getAIIcons()[aiName2])));
}
matchups.add(matchup);
}
public static void update() {
if (matchups.isEmpty()) {
return;
}
if (waitForUserInput) {
return;
}
if (matchInProgress) {
return;
}
GuiBase.getInterface().enableOverlay();
DraftMatchup nextMatch = matchups.remove(0);
matchInProgress = true;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SOverlayUtils.startGameOverlay();
SOverlayUtils.showOverlay();
}
});
if (!nextMatch.hasHumanPlayer) {
GuiBase.getInterface().disableOverlay();
waitForUserInput = false;
} else {
waitForUserInput = true;
}
GuiBase.getInterface().startMatch(GameType.QuestDraft, nextMatch.matchStarter);
}
public static void continueMatches() {
waitForUserInput = false;
update();
}
private static class DraftMatchup {
private List<RegisteredPlayer> matchStarter = new ArrayList<RegisteredPlayer>();
private boolean hasHumanPlayer = false;
}
}

View File

@@ -45,6 +45,7 @@ import java.util.List;
*/ */
public class SSubmenuQuestUtil { public class SSubmenuQuestUtil {
private static QuestEvent event; private static QuestEvent event;
private static QuestEventDraft draftEvent;
/** /**
* <p> * <p>
@@ -241,6 +242,14 @@ public class SSubmenuQuestUtil {
SSubmenuQuestUtil.event = 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) { public static boolean checkActiveQuest(String location) {
QuestController qc = FModel.getQuest(); QuestController qc = FModel.getQuest();
if (qc == null || qc.getAssets() == null) { if (qc == null || qc.getAssets() == null) {

View File

@@ -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.
*
* <br><br><i>(V at beginning of class name denotes a view class.)</i>
*/
public enum VSubmenuQuestDraft implements IVSubmenu<CSubmenuQuestDraft> {
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");
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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;
/**
* <p>
* QuestWinLose.
* </p>
* 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();
}
/**
* <p>
* populateCustomPanel.
* </p>
* 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<Player> 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();
}
}

View File

@@ -1,18 +1,32 @@
package forge.screens.match; 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.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.game.player.Player;
import forge.model.FModel; 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.SkinnedLabel;
import forge.toolbox.FSkin.SkinnedPanel; import forge.toolbox.FSkin.SkinnedPanel;
import net.miginfocom.swing.MigLayout; import forge.toolbox.FTextArea;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.StringSelection;
public class ViewWinLose { public class ViewWinLose {
@@ -48,6 +62,9 @@ public class ViewWinLose {
case Quest: case Quest:
control = new QuestWinLose(this, game0); control = new QuestWinLose(this, game0);
break; break;
case QuestDraft:
control = new QuestDraftWinLose(this, game0);
break;
case Draft: case Draft:
if (!FModel.getGauntletMini().isGauntletDraft()) { if (!FModel.getGauntletMini().isGauntletDraft()) {
break; break;

View File

@@ -19,8 +19,6 @@ package forge.view.arcane;
import forge.FThreads; import forge.FThreads;
import forge.game.card.Card; import forge.game.card.Card;
import forge.model.FModel;
import forge.properties.ForgePreferences.FPref;
import forge.screens.match.CMatchUI; import forge.screens.match.CMatchUI;
import forge.screens.match.controllers.CPrompt; import forge.screens.match.controllers.CPrompt;
import forge.toolbox.FScrollPane; import forge.toolbox.FScrollPane;
@@ -58,7 +56,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
/** Constant <code>STACK_SPACING_Y=0.07f</code>. */ /** Constant <code>STACK_SPACING_Y=0.07f</code>. */
private static final float 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 landStackMax = 5;
private final int tokenStackMax = 5; private final int tokenStackMax = 5;
private final int othersStackMax = 4; private final int othersStackMax = 4;
@@ -186,7 +184,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
return allTokens; return allTokens;
} }
private final CardStackRow collectAllCreatures() { /*private final CardStackRow collectAllCreatures() {
final CardStackRow allCreatures = new CardStackRow(); final CardStackRow allCreatures = new CardStackRow();
outerLoop: outerLoop:
// //
@@ -236,7 +234,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
allCreatures.add(insertIndex == -1 ? allCreatures.size() : insertIndex, stack); allCreatures.add(insertIndex == -1 ? allCreatures.size() : insertIndex, stack);
} }
return allCreatures; return allCreatures;
} }*/
@Override @Override
public final CardPanel addCard(final Card card) { public final CardPanel addCard(final Card card) {

View File

@@ -53,7 +53,9 @@ import forge.util.WaitRunnable;
import forge.util.gui.SGuiChoose; import forge.util.gui.SGuiChoose;
public class GuiMobile implements IGuiBase { public class GuiMobile implements IGuiBase {
private final String assetsDir; private final String assetsDir;
public GuiMobile(String assetsDir0) { public GuiMobile(String assetsDir0) {
assetsDir = assetsDir0; assetsDir = assetsDir0;
} }
@@ -205,6 +207,14 @@ public class GuiMobile implements IGuiBase {
//TODO //TODO
} }
@Override
public void disableOverlay() {
}
@Override
public void enableOverlay() {
}
@Override @Override
public void finishGame() { public void finishGame() {
new ViewWinLose(FControl.getGame()).setVisible(true); new ViewWinLose(FControl.getGame()).setVisible(true);

View File

@@ -64,6 +64,8 @@ public interface IGuiBase {
void updatePhase(); void updatePhase();
void updateTurn(GameEventTurnBegan event, Game game); void updateTurn(GameEventTurnBegan event, Game game);
void updatePlayerControl(); void updatePlayerControl();
void enableOverlay();
void disableOverlay();
void finishGame(); void finishGame();
void updateStack(); void updateStack();
void updateZones(List<Pair<Player, ZoneType>> zonesToUpdate); void updateZones(List<Pair<Player, ZoneType>> zonesToUpdate);

View File

@@ -155,6 +155,23 @@ public final class BoosterDraft implements IBoosterDraft {
return draft; 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;
}
/** /**
* <p> * <p>
* Constructor for BoosterDraft_1. * Constructor for BoosterDraft_1.

View File

@@ -17,12 +17,20 @@
*/ */
package forge.quest; 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.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.eventbus.Subscribe; import com.google.common.eventbus.Subscribe;
import forge.GuiBase; import forge.GuiBase;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckGroup;
import forge.game.GameFormat; import forge.game.GameFormat;
import forge.game.event.GameEvent; import forge.game.event.GameEvent;
import forge.game.event.GameEventMulligan; import forge.game.event.GameEventMulligan;
@@ -43,9 +51,6 @@ import forge.quest.io.QuestChallengeReader;
import forge.util.storage.IStorage; import forge.util.storage.IStorage;
import forge.util.storage.StorageBase; import forge.util.storage.StorageBase;
import java.io.File;
import java.util.*;
/** /**
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
* *
@@ -77,6 +82,9 @@ public class QuestController {
// This is used by shop. Had no idea where else to place this // This is used by shop. Had no idea where else to place this
private static transient IStorage<PreconDeck> preconManager = null; private static transient IStorage<PreconDeck> preconManager = null;
private transient IStorage<DeckGroup> draftDecks;
/** The Constant RANK_TITLES. */ /** The Constant RANK_TITLES. */
public static final String[] RANK_TITLES = new String[] { "Level 0 - Confused Wizard", "Level 1 - Mana Mage", public static final String[] RANK_TITLES = new String[] { "Level 0 - Confused Wizard", "Level 1 - Mana Mage",
"Level 2 - Death by Megrim", "Level 3 - Shattered the Competition", "Level 4 - Black Knighted", "Level 2 - Death by Megrim", "Level 3 - Shattered the Competition", "Level 4 - Black Knighted",
@@ -92,7 +100,6 @@ public class QuestController {
/** */ /** */
public static final int MAX_PET_SLOTS = 2; public static final int MAX_PET_SLOTS = 2;
/** /**
* *
* TODO: Write javadoc for this method. * TODO: Write javadoc for this method.
@@ -143,6 +150,10 @@ public class QuestController {
return this.decks; return this.decks;
} }
public IStorage<DeckGroup> getDraftDecks() {
return draftDecks;
}
/** /**
* Gets the current format if any. * Gets the current format if any.
* *
@@ -210,6 +221,8 @@ public class QuestController {
this.questFormat = this.model == null ? null : this.model.getFormat(); this.questFormat = this.model == null ? null : this.model.getFormat();
this.currentEvent = null; this.currentEvent = null;
this.draftDecks = this.model == null ? null : this.model.getAssets().getDraftDeckStorage();
this.resetDuelsManager(); this.resetDuelsManager();
this.resetChallengesManager(); this.resetChallengesManager();
this.getDuelsManager().randomizeOpponents(); this.getDuelsManager().randomizeOpponents();

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<DeckGroup> {
/**
* Instantiates a new quest deck map.
*/
public QuestDeckGroupMap(Map<String, DeckGroup> in) {
super("Quest draft decks", in == null ? new HashMap<String, DeckGroup>() : 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);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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;
/**
* <p>
* QuestEvent.
* </p>
*
* 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<QuestEventDraft, String> FN_GET_NAME = new Function<QuestEventDraft, String>() {
@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<String, Integer> 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<CardBlock> possibleBlocks = new ArrayList<CardBlock>();
List<CardEdition> allowedQuestSets = new ArrayList<CardEdition>();
boolean questUsesLimitedCardPool = quest.getFormat() != null;
if (questUsesLimitedCardPool) {
List<String> allowedSetCodes = quest.getFormat().getAllowedSetCodes();
for (String setCode : allowedSetCodes) {
allowedQuestSets.add(FModel.getMagicDb().getEditions().get(setCode));
}
}
LimitedPoolType draftType = LimitedPoolType.Block;
List<CardBlock> blocks = new ArrayList<CardBlock>();
IStorage<CardBlock> 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<String> sets = new Stack<String>();
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<String> possibleSetCombinations = getSetCombos(sets);
Collections.shuffle(possibleSetCombinations);
event.boosterConfiguration = possibleSetCombinations.get(0);
}
event.block = selectedBlock.getName();
event.entryFee = calculateEntryFee(event.boosterConfiguration.split("/"));
List<String> players = new ArrayList<String>();
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<String> usedNames = new ArrayList<String>();
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<Integer> usedIcons = new ArrayList<Integer>();
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<String> getSetCombos(final List<String> setz) {
String[] sets = setz.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
List<String> setCombos = new ArrayList<String>();
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;
}
}

View File

@@ -1,11 +1,12 @@
package forge.quest.data; package forge.quest.data;
import forge.model.FModel;
import forge.quest.data.QuestPreferences.DifficultyPrefs;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import forge.model.FModel;
import forge.quest.QuestEventDraft;
import forge.quest.data.QuestPreferences.DifficultyPrefs;
/** /**
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
* *
@@ -19,6 +20,11 @@ public class QuestAchievements {
private List<String> completedChallenges = new ArrayList<String>(); private List<String> completedChallenges = new ArrayList<String>();
private List<String> currentChallenges = new ArrayList<String>(); private List<String> currentChallenges = new ArrayList<String>();
private QuestEventDraftContainer drafts = new QuestEventDraftContainer();
private int currentDraft = -1;
private int draftTokensAvailable = 3;
private int winCountAtEndOfDraft = 0;
private int win; private int win;
private int winstreakBest = 0; private int winstreakBest = 0;
private int winstreakCurrent = 0; private int winstreakCurrent = 0;
@@ -35,6 +41,17 @@ public class QuestAchievements {
difficulty = 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. * TODO: Write javadoc for Constructor.
* @param mode * @param mode
@@ -46,6 +63,13 @@ public class QuestAchievements {
this.win++; this.win++;
this.winstreakCurrent++; 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) { if (this.winstreakCurrent > this.winstreakBest) {
this.winstreakBest = this.winstreakCurrent; this.winstreakBest = this.winstreakCurrent;
} }
@@ -176,4 +200,48 @@ public class QuestAchievements {
return this.difficulty; 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);
}
} }

View File

@@ -17,10 +17,16 @@
*/ */
package forge.quest.data; package forge.quest.data;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckGroup;
import forge.item.InventoryItem; import forge.item.InventoryItem;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.model.FModel; import forge.model.FModel;
import forge.quest.QuestDeckGroupMap;
import forge.quest.QuestDeckMap; import forge.quest.QuestDeckMap;
import forge.quest.QuestMode; import forge.quest.QuestMode;
import forge.quest.QuestUtilCards; import forge.quest.QuestUtilCards;
@@ -28,10 +34,6 @@ import forge.quest.bazaar.QuestItemType;
import forge.quest.data.QuestPreferences.QPref; import forge.quest.data.QuestPreferences.QPref;
import forge.util.ItemPool; import forge.util.ItemPool;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
/** */ /** */
public class QuestAssets { 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) // Much the same like other map, but keyed by string (to support a lot of custom pets)
private final Map<String, QuestItemCondition> combatPets = new HashMap<String, QuestItemCondition>(); private final Map<String, QuestItemCondition> combatPets = new HashMap<String, QuestItemCondition>();
private final HashMap<String, DeckGroup> draftDecks = new HashMap<String, DeckGroup>();
/** /**
* Checks for item. * Checks for item.
* *
@@ -263,4 +267,11 @@ public class QuestAssets {
return new QuestDeckMap(this.myDecks); return new QuestDeckMap(this.myDecks);
} }
/**
* @return the tournament deck storage
*/
public QuestDeckGroupMap getDraftDeckStorage() {
return new QuestDeckGroupMap(this.draftDecks);
}
} }

View File

@@ -41,7 +41,7 @@ import java.util.Map;
*/ */
public final class QuestData { public final class QuestData {
/** Holds the latest version of the Quest Data. */ /** 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, // This field places the version number into QD instance,
// but only when the object is created through the constructor // but only when the object is created through the constructor

View File

@@ -0,0 +1,9 @@
package forge.quest.data;
import java.util.ArrayList;
import forge.quest.QuestEventDraft;
public class QuestEventDraftContainer extends ArrayList<QuestEventDraft> {
private static final long serialVersionUID = -417036762608756613L;
}

View File

@@ -27,12 +27,14 @@ import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import forge.card.CardEdition; import forge.card.CardEdition;
import forge.deck.CardPool; import forge.deck.CardPool;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckGroup;
import forge.deck.DeckSection; import forge.deck.DeckSection;
import forge.error.BugReporter; import forge.error.BugReporter;
import forge.item.*; import forge.item.*;
import forge.model.FModel; import forge.model.FModel;
import forge.properties.ForgeConstants; import forge.properties.ForgeConstants;
import forge.quest.QuestController; import forge.quest.QuestController;
import forge.quest.QuestEventDraft;
import forge.quest.QuestMode; import forge.quest.QuestMode;
import forge.quest.bazaar.QuestItemType; import forge.quest.bazaar.QuestItemType;
import forge.quest.data.*; import forge.quest.data.*;
@@ -79,6 +81,7 @@ public class QuestDataIO {
final XStream xStream = isIgnoring ? new IgnoringXStream() : new XStream(); final XStream xStream = isIgnoring ? new IgnoringXStream() : new XStream();
xStream.registerConverter(new ItemPoolToXml()); xStream.registerConverter(new ItemPoolToXml());
xStream.registerConverter(new DeckToXml()); xStream.registerConverter(new DeckToXml());
xStream.registerConverter(new DraftTournamentToXml());
xStream.registerConverter(new GameFormatQuestToXml()); xStream.registerConverter(new GameFormatQuestToXml());
xStream.registerConverter(new QuestModeToXml()); xStream.registerConverter(new QuestModeToXml());
xStream.autodetectAnnotations(true); xStream.autodetectAnnotations(true);
@@ -184,7 +187,7 @@ public class QuestDataIO {
QuestDataIO.setFinalField(QuestData.class, "petSlots", newData, new HashMap<Integer, String>()); QuestDataIO.setFinalField(QuestData.class, "petSlots", newData, new HashMap<Integer, String>());
} }
if(saveVersion < 8) { if (saveVersion < 8) {
QuestDataIO.setFinalField(QuestData.class, "isCharmActive", newData, false); QuestDataIO.setFinalField(QuestData.class, "isCharmActive", newData, false);
} }
@@ -317,6 +320,9 @@ public class QuestDataIO {
qA.getCurrentChallenges().set(i, lc.toString()); qA.getCurrentChallenges().set(i, lc.toString());
} }
case 8:
QuestDataIO.setFinalField(QuestAssets.class, "draftDecks", qS, new HashMap<String, DeckGroup>());
default: default:
break; break;
} }
@@ -470,6 +476,161 @@ public class QuestDataIO {
} }
} }
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 { private static class DeckToXml extends ItemPoolToXml {
/* (non-Javadoc) /* (non-Javadoc)