From 0190ccbedff1f2ca8ebcf6f9846cfd1a367f56bc Mon Sep 17 00:00:00 2001 From: drdev Date: Sat, 12 Jul 2014 21:10:39 +0000 Subject: [PATCH] Support editing quest decks --- .gitattributes | 1 + .../home/quest/VSubmenuQuestDecks.java | 2 +- .../src/forge/deck/FDeckEditor.java | 45 +++++- .../forge/screens/quest/QuestDeckEditor.java | 89 +++++++++++ .../forge/screens/quest/QuestDecksScreen.java | 141 +++++++++++++++++- .../src/forge/screens/quest/QuestMenu.java | 13 +- .../java/forge/itemmanager/ItemColumn.java | 11 ++ 7 files changed, 290 insertions(+), 12 deletions(-) create mode 100644 forge-gui-mobile/src/forge/screens/quest/QuestDeckEditor.java diff --git a/.gitattributes b/.gitattributes index 0ce154bd015..c2cb9114f46 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1202,6 +1202,7 @@ forge-gui-mobile/src/forge/screens/quest/LoadQuestScreen.java -text forge-gui-mobile/src/forge/screens/quest/NewQuestScreen.java -text forge-gui-mobile/src/forge/screens/quest/QuestBazaarScreen.java -text forge-gui-mobile/src/forge/screens/quest/QuestChallengesScreen.java -text +forge-gui-mobile/src/forge/screens/quest/QuestDeckEditor.java -text forge-gui-mobile/src/forge/screens/quest/QuestDecksScreen.java -text forge-gui-mobile/src/forge/screens/quest/QuestDuelsScreen.java -text forge-gui-mobile/src/forge/screens/quest/QuestEventPanel.java -text diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestDecks.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestDecks.java index cb86c7c0181..f574c89c2c3 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestDecks.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestDecks.java @@ -38,7 +38,7 @@ public enum VSubmenuQuestDecks implements IVSubmenu { private final DeckManager lstDecks = new DeckManager(GameType.Quest); - private final JLabel lblInfo = new FLabel.Builder() + private final FLabel lblInfo = new FLabel.Builder() .fontAlign(SwingConstants.LEFT).fontSize(16).fontStyle(Font.BOLD) .text("Build or select a deck").build(); diff --git a/forge-gui-mobile/src/forge/deck/FDeckEditor.java b/forge-gui-mobile/src/forge/deck/FDeckEditor.java index 0697e4d04b2..9dee44df820 100644 --- a/forge-gui-mobile/src/forge/deck/FDeckEditor.java +++ b/forge-gui-mobile/src/forge/deck/FDeckEditor.java @@ -2,6 +2,7 @@ package forge.deck; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import org.apache.commons.lang3.StringUtils; @@ -25,6 +26,8 @@ import forge.card.CardZoom; import forge.deck.io.DeckPreferences; import forge.item.PaperCard; import forge.itemmanager.CardManager; +import forge.itemmanager.ColumnDef; +import forge.itemmanager.ItemColumn; import forge.itemmanager.ItemManager.ContextMenuBuilder; import forge.itemmanager.ItemManagerConfig; import forge.limited.BoosterDraft; @@ -33,6 +36,7 @@ import forge.menu.FMenuItem; import forge.menu.FPopupMenu; import forge.model.FModel; import forge.properties.ForgePreferences.FPref; +import forge.quest.data.QuestPreferences.QPref; import forge.screens.TabPageScreen; import forge.toolbox.FContainer; import forge.toolbox.FEvent; @@ -91,6 +95,12 @@ public class FDeckEditor extends TabPageScreen { public Deck get() { return new Deck(); } + })), + Quest(new DeckController(FModel.getQuest().getMyDecks(), new Supplier() { + @Override + public Deck get() { + return new Deck(); + } })); private final DeckController controller; @@ -141,6 +151,12 @@ public class FDeckEditor extends TabPageScreen { new CatalogPage(ItemManagerConfig.PLANAR_POOL), new DeckSectionPage(DeckSection.Planes, ItemManagerConfig.PLANAR_DECK_EDITOR) }; + case Quest: + return new DeckEditorPage[] { + new CatalogPage(ItemManagerConfig.QUEST_EDITOR_POOL, "Inventory", FSkinImage.QUEST_BOX), + new DeckSectionPage(DeckSection.Main, ItemManagerConfig.QUEST_DECK_EDITOR), + new DeckSectionPage(DeckSection.Sideboard, ItemManagerConfig.QUEST_DECK_EDITOR) + }; } } @@ -364,6 +380,7 @@ public class FDeckEditor extends TabPageScreen { case Constructed: case Planechase: case Archenemy: + case Quest: default: if (FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) { return CardLimit.Default; @@ -439,6 +456,10 @@ public class FDeckEditor extends TabPageScreen { } } + protected Map getColOverrides(ItemManagerConfig config) { + return null; + } + protected class DeckHeader extends FContainer { private DeckHeader() { setHeight(HEADER_HEIGHT); @@ -475,11 +496,12 @@ public class FDeckEditor extends TabPageScreen { } protected static abstract class CardManagerPage extends DeckEditorPage { + private final ItemManagerConfig config; protected final CardManager cardManager = add(new CardManager(false)); - protected CardManagerPage(ItemManagerConfig config, String caption0, FImage icon0) { + protected CardManagerPage(ItemManagerConfig config0, String caption0, FImage icon0) { super(caption0, icon0); - cardManager.setup(config); + config = config0; cardManager.setItemActivateHandler(new FEventHandler() { @Override public void handleEvent(FEvent e) { @@ -500,6 +522,10 @@ public class FDeckEditor extends TabPageScreen { }); } + protected void initialize() { + cardManager.setup(config, parentScreen.getColOverrides(config)); + } + protected boolean canAddCards() { return true; } @@ -667,6 +693,7 @@ public class FDeckEditor extends TabPageScreen { if (initialized) { return; } //prevent initializing more than once if deck changes initialized = true; + super.initialize(); cardManager.setCaption(getItemManagerCaption()); refresh(); } @@ -710,6 +737,15 @@ public class FDeckEditor extends TabPageScreen { case Planechase: cardManager.setPool(ItemPool.createFrom(FModel.getMagicDb().getVariantCards().getAllCards(Predicates.compose(CardRulesPredicates.Presets.IS_PLANE_OR_PHENOMENON, PaperCard.FN_GET_RULES)), PaperCard.class), true); break; + case Quest: + final ItemPool cardpool = new ItemPool(PaperCard.class); + cardpool.addAll(FModel.getQuest().getCards().getCardpool()); + // remove bottom cards that are in the deck from the card pool + cardpool.removeAll(parentScreen.getDeck().getMain()); + // remove sideboard cards from the catalog + cardpool.removeAll(parentScreen.getDeck().getOrCreate(DeckSection.Sideboard)); + cardManager.setPool(cardpool); + break; default: cardManager.setPool(ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(), PaperCard.class), true); break; @@ -811,6 +847,7 @@ public class FDeckEditor extends TabPageScreen { @Override protected void initialize() { + super.initialize(); cardManager.setPool(parentScreen.getDeck().getOrCreate(deckSection)); updateCaption(); } @@ -1227,6 +1264,10 @@ public class FDeckEditor extends TabPageScreen { case Sealed: DeckPreferences.setSealedDeck(deckStr); break; + case Quest: + FModel.getQuestPreferences().setPref(QPref.CURRENT_DECK, model.toString()); + FModel.getQuest().save(); + break; default: break; } diff --git a/forge-gui-mobile/src/forge/screens/quest/QuestDeckEditor.java b/forge-gui-mobile/src/forge/screens/quest/QuestDeckEditor.java new file mode 100644 index 00000000000..3f8d24495ab --- /dev/null +++ b/forge-gui-mobile/src/forge/screens/quest/QuestDeckEditor.java @@ -0,0 +1,89 @@ +package forge.screens.quest; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import com.google.common.base.Function; + +import forge.deck.Deck; +import forge.deck.DeckProxy; +import forge.deck.FDeckEditor; +import forge.item.InventoryItem; +import forge.item.PaperCard; +import forge.itemmanager.ColumnDef; +import forge.itemmanager.ItemColumn; +import forge.itemmanager.ItemManagerConfig; +import forge.model.FModel; + +public class QuestDeckEditor extends FDeckEditor { + private Map decksUsingMyCards; + + public QuestDeckEditor() { + super(EditorType.Quest, "", false); + } + public QuestDeckEditor(DeckProxy editDeck) { + super(EditorType.Quest, editDeck, true); + } + + @Override + public void onActivate() { + super.onActivate(); + decksUsingMyCards = countDecksForEachCard(); + } + + @Override + protected Map getColOverrides(ItemManagerConfig config) { + Map colOverrides = new HashMap(); + switch (config) { + case QUEST_EDITOR_POOL: + ItemColumn.addColOverride(config, colOverrides, ColumnDef.NEW, FModel.getQuest().getCards().getFnNewCompare(), FModel.getQuest().getCards().getFnNewGet()); + break; + case QUEST_DECK_EDITOR: + ItemColumn.addColOverride(config, colOverrides, ColumnDef.NEW, FModel.getQuest().getCards().getFnNewCompare(), FModel.getQuest().getCards().getFnNewGet()); + ItemColumn.addColOverride(config, colOverrides, ColumnDef.DECKS, + new Function, Comparable>() { + @Override + public Comparable apply(final Entry from) { + final Integer iValue = decksUsingMyCards.get(from.getKey()); + return iValue == null ? Integer.valueOf(0) : iValue; + } + }, + new Function, Object>() { + @Override + public Object apply(final Entry from) { + final Integer iValue = decksUsingMyCards.get(from.getKey()); + return iValue == null ? "" : iValue.toString(); + } + }); + break; + default: + colOverrides = null; //shouldn't happen + break; + } + return colOverrides; + } + + /** + * Adds any card to the catalog and data pool. + * + * @param card {@link forge.item.PaperCard} + */ + public void addCheatCard(final PaperCard card, int qty) { + getCatalogPage().addCard(card, qty); + FModel.getQuest().getCards().getCardpool().add(card, qty); + } + + // fills number of decks using each card + private Map countDecksForEachCard() { + final Map result = new HashMap(); + for (final Deck deck : FModel.getQuest().getMyDecks()) { + for (final Entry 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; + } +} diff --git a/forge-gui-mobile/src/forge/screens/quest/QuestDecksScreen.java b/forge-gui-mobile/src/forge/screens/quest/QuestDecksScreen.java index 042115d069f..0f7ccb89178 100644 --- a/forge-gui-mobile/src/forge/screens/quest/QuestDecksScreen.java +++ b/forge-gui-mobile/src/forge/screens/quest/QuestDecksScreen.java @@ -1,15 +1,150 @@ package forge.screens.quest; +import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment; + +import forge.Forge; +import forge.assets.FSkinFont; +import forge.deck.DeckProxy; +import forge.deck.FDeckChooser; +import forge.game.GameType; +import forge.itemmanager.DeckManager; +import forge.itemmanager.ItemManagerConfig; +import forge.model.FModel; +import forge.quest.QuestController; +import forge.quest.QuestUtil; +import forge.quest.data.QuestPreferences.QPref; import forge.screens.FScreen; +import forge.toolbox.FButton; +import forge.toolbox.FEvent; +import forge.toolbox.FLabel; +import forge.toolbox.FOptionPane; +import forge.toolbox.FEvent.FEventHandler; +import forge.util.ThreadUtil; public class QuestDecksScreen extends FScreen { + private static final float PADDING = FOptionPane.PADDING; + + private final DeckManager lstDecks = add(new DeckManager(GameType.Quest)); + private final FButton btnNewDeck = add(new FButton("New Deck")); + private final FButton btnEditDeck = add(new FButton("Edit Deck")); + + private final FLabel lblInfo = add(new FLabel.Builder() + .align(HAlignment.CENTER).font(FSkinFont.get(16)) + .text("Build or select a deck").build()); + + private final FEventHandler onDeckSelectionChanged = new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + DeckProxy deck = lstDecks.getSelectedItem(); + if (deck != null) { + FModel.getQuestPreferences().setPref(QPref.CURRENT_DECK, deck.toString()); + } + else { + FModel.getQuestPreferences().setPref(QPref.CURRENT_DECK, QPref.CURRENT_DECK.getDefault()); + } + FModel.getQuestPreferences().save(); + } + }; + + private boolean needRefreshOnActivate = true; + public QuestDecksScreen() { - super("Select Quest Deck", QuestMenu.getMenu()); + super("Quest Decks", QuestMenu.getMenu()); + + lstDecks.setup(ItemManagerConfig.QUEST_DECKS); + lstDecks.setItemActivateHandler(new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + Forge.back(); + } + }); + + btnNewDeck.setFont(FSkinFont.get(16)); + btnNewDeck.setCommand(new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + ThreadUtil.invokeInGameThread(new Runnable() { //must run in game thread to prevent blocking UI thread + @Override + public void run() { + if (!QuestUtil.checkActiveQuest("Create a Deck.")) { + return; + } + QuestDeckEditor editor = new QuestDeckEditor(); + editor.setSaveHandler(new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + //ensure list is refreshed if new deck is saved + needRefreshOnActivate = true; + } + }); + Forge.openScreen(editor); + } + }); + } + }); + btnEditDeck.setFont(btnNewDeck.getFont()); + btnEditDeck.setCommand(new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + editSelectedDeck(); + } + }); + } + + @Override + public void onActivate() { + if (needRefreshOnActivate) { + needRefreshOnActivate = false; + refreshDecks(); + } + } + + public void refreshDecks() { + lstDecks.setSelectionChangedHandler(null); //set to null temporarily + + final QuestController qData = FModel.getQuest(); + boolean hasQuest = qData.getAssets() != null; + // Retrieve and set all decks + lstDecks.setPool(DeckProxy.getAllQuestDecks(hasQuest ? qData.getMyDecks() : null)); + lstDecks.setup(ItemManagerConfig.QUEST_DECKS); + + // Look through list for preferred deck from prefs + final DeckProxy deck = hasQuest ? lstDecks.stringToItem(FModel.getQuestPreferences().getPref(QPref.CURRENT_DECK)) : null; + if (deck != null) { + lstDecks.setSelectedItem(deck); + } + else { + lstDecks.setSelectedIndex(0); + onDeckSelectionChanged.handleEvent(null); //update prefs immediately + } + + lstDecks.setSelectionChangedHandler(onDeckSelectionChanged); + } + + private void editSelectedDeck() { + final DeckProxy deck = lstDecks.getSelectedItem(); + if (deck == null) { return; } + + needRefreshOnActivate = true; + Forge.openScreen(new QuestDeckEditor(deck)); } @Override protected void doLayout(float startY, float width, float height) { - // TODO Auto-generated method stub - + float x = PADDING; + float y = startY + PADDING / 2; + float w = width - 2 * PADDING; + + lblInfo.setBounds(x, y, w, lblInfo.getAutoSizeBounds().height); + y += lblInfo.getHeight(); + + float buttonWidth = (w - FDeckChooser.PADDING) / 2; + float buttonHeight = btnNewDeck.getAutoSizeBounds().height * 1.2f; + float listHeight = height - buttonHeight - y - FDeckChooser.PADDING; + + lstDecks.setBounds(x, y, w, listHeight); + y += listHeight + FDeckChooser.PADDING; + btnNewDeck.setBounds(x, y, buttonWidth, buttonHeight); + btnEditDeck.setBounds(x + buttonWidth + FDeckChooser.PADDING, y, buttonWidth, buttonHeight); } } diff --git a/forge-gui-mobile/src/forge/screens/quest/QuestMenu.java b/forge-gui-mobile/src/forge/screens/quest/QuestMenu.java index e01988af25c..f37cf7465df 100644 --- a/forge-gui-mobile/src/forge/screens/quest/QuestMenu.java +++ b/forge-gui-mobile/src/forge/screens/quest/QuestMenu.java @@ -50,6 +50,12 @@ public class QuestMenu extends FPopupMenu implements IVQuestStats { Forge.openScreen(tournamentsScreen); } }); + private static final FMenuItem decksItem = new FMenuItem("Quest Decks", FSkinImage.DECKLIST, new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + Forge.openScreen(decksScreen); + } + }); private static final FMenuItem spellShopItem = new FMenuItem("Spell Shop", FSkinImage.QUEST_BOOK, new FEventHandler() { @Override public void handleEvent(FEvent e) { @@ -138,17 +144,12 @@ public class QuestMenu extends FPopupMenu implements IVQuestStats { addItem(duelsItem); duelsItem.setSelected(currentScreen == duelsScreen); addItem(challengesItem); challengesItem.setSelected(currentScreen == challengesScreen); addItem(tournamentsItem); tournamentsItem.setSelected(currentScreen == tournamentsScreen); + addItem(decksItem); decksItem.setSelected(currentScreen == decksScreen); addItem(spellShopItem); spellShopItem.setSelected(currentScreen == spellShopScreen); addItem(bazaarItem); bazaarItem.setSelected(currentScreen == bazaarScreen); addItem(statsItem); statsItem.setSelected(currentScreen == statsScreen); addItem(unlockSetsItem); addItem(travelItem); - addItem(new FMenuItem("Change Deck", FSkinImage.DECKLIST, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - Forge.openScreen(decksScreen); - } - })); addItem(new FMenuItem("New Quest", FSkinImage.NEW, new FEventHandler() { @Override public void handleEvent(FEvent e) { diff --git a/forge-gui/src/main/java/forge/itemmanager/ItemColumn.java b/forge-gui/src/main/java/forge/itemmanager/ItemColumn.java index 44945e0710d..1dc60109454 100644 --- a/forge-gui/src/main/java/forge/itemmanager/ItemColumn.java +++ b/forge-gui/src/main/java/forge/itemmanager/ItemColumn.java @@ -22,6 +22,7 @@ import com.google.common.base.Function; import forge.item.InventoryItem; import forge.itemmanager.ItemColumnConfig.SortState; +import java.util.Map; import java.util.Map.Entry; @@ -108,4 +109,14 @@ public class ItemColumn { public String toString() { return config.getLongName(); } + + public static void addColOverride(ItemManagerConfig config, Map colOverrides, ColumnDef colDef) { + ItemColumnConfig colConfig = config.getCols().get(colDef); + addColOverride(config, colOverrides, colDef, colConfig.getFnSort(), colConfig.getFnDisplay()); + } + public static void addColOverride(ItemManagerConfig config, Map colOverrides, ColumnDef colDef, + Function, Comparable> fnSort0, + Function, Object> fnDisplay0) { + colOverrides.put(colDef, new ItemColumn(config.getCols().get(colDef), fnSort0, fnDisplay0)); + } }