From dbe80258c03f018bfd6d429ce4956f5ab232006e Mon Sep 17 00:00:00 2001 From: Krazy Date: Sun, 20 Apr 2014 23:26:20 +0000 Subject: [PATCH] Added Booster Boxes to the quest shop. Added option to open booster boxes and fat packs one booster at a time to the preferences (default off). Re-worked FatPack class to accommodate. CardListViewers are now tall enough to hold the entire contents of a booster pack (15 cards) without creating a scrollbar (a 14px height increase). --- .gitattributes | 1 + .../src/main/java/forge/ImageLoader.java | 3 + .../download/GuiDownloadQuestImages.java | 1 + .../forge/gui/BoxedProductCardListViewer.java | 178 ++++++++++++++++++ .../main/java/forge/gui/CardListViewer.java | 2 +- .../java/forge/gui/ImportSourceAnalyzer.java | 2 + .../controllers/CEditorQuestCardShop.java | 46 ++++- .../home/settings/CSubmenuPreferences.java | 1 + .../home/settings/VSubmenuPreferences.java | 8 + 9 files changed, 237 insertions(+), 5 deletions(-) create mode 100644 forge-gui-desktop/src/main/java/forge/gui/BoxedProductCardListViewer.java diff --git a/.gitattributes b/.gitattributes index fe1734bf8b7..8fc0f3a6b9a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -698,6 +698,7 @@ forge-gui-desktop/src/main/java/forge/download/GuiDownloader.java -text forge-gui-desktop/src/main/java/forge/download/package-info.java -text forge-gui-desktop/src/main/java/forge/error/BugReportDialog.java -text forge-gui-desktop/src/main/java/forge/error/package-info.java -text +forge-gui-desktop/src/main/java/forge/gui/BoxedProductCardListViewer.java -text forge-gui-desktop/src/main/java/forge/gui/CardContainer.java -text forge-gui-desktop/src/main/java/forge/gui/CardDetailPanel.java -text forge-gui-desktop/src/main/java/forge/gui/CardListViewer.java -text diff --git a/forge-gui-desktop/src/main/java/forge/ImageLoader.java b/forge-gui-desktop/src/main/java/forge/ImageLoader.java index dfeed576bf8..15d59d8ea26 100644 --- a/forge-gui-desktop/src/main/java/forge/ImageLoader.java +++ b/forge-gui-desktop/src/main/java/forge/ImageLoader.java @@ -39,6 +39,9 @@ final class ImageLoader extends CacheLoader { } else if (key.startsWith(ImageKeys.FATPACK_PREFIX)) { filename = key.substring(ImageKeys.FATPACK_PREFIX.length()); path = ForgeConstants.CACHE_FATPACK_PICS_DIR; + } else if (key.startsWith(ImageKeys.BOOSTERBOX_PREFIX)) { + filename = key.substring(ImageKeys.BOOSTERBOX_PREFIX.length()); + path = ForgeConstants.CACHE_BOOSTERBOX_PICS_DIR; } else if (key.startsWith(ImageKeys.PRECON_PREFIX)) { filename = key.substring(ImageKeys.PRECON_PREFIX.length()); path = ForgeConstants.CACHE_PRECON_PICS_DIR; diff --git a/forge-gui-desktop/src/main/java/forge/download/GuiDownloadQuestImages.java b/forge-gui-desktop/src/main/java/forge/download/GuiDownloadQuestImages.java index 3bcbd62a8a0..e4d0ad93584 100644 --- a/forge-gui-desktop/src/main/java/forge/download/GuiDownloadQuestImages.java +++ b/forge-gui-desktop/src/main/java/forge/download/GuiDownloadQuestImages.java @@ -50,6 +50,7 @@ public class GuiDownloadQuestImages extends GuiDownloader { addMissingItems(urls, ForgeConstants.IMAGE_LIST_QUEST_PET_SHOP_ICONS_FILE, ForgeConstants.CACHE_ICON_PICS_DIR); addMissingItems(urls, ForgeConstants.IMAGE_LIST_QUEST_BOOSTERS_FILE, ForgeConstants.CACHE_BOOSTER_PICS_DIR); addMissingItems(urls, ForgeConstants.IMAGE_LIST_QUEST_FATPACKS_FILE, ForgeConstants.CACHE_FATPACK_PICS_DIR); + addMissingItems(urls, ForgeConstants.IMAGE_LIST_QUEST_BOOSTERBOXES_FILE, ForgeConstants.CACHE_BOOSTERBOX_PICS_DIR); addMissingItems(urls, ForgeConstants.IMAGE_LIST_QUEST_PRECONS_FILE, ForgeConstants.CACHE_PRECON_PICS_DIR); addMissingItems(urls, ForgeConstants.IMAGE_LIST_QUEST_TOURNAMENTPACKS_FILE, ForgeConstants.CACHE_TOURNAMENTPACK_PICS_DIR); addMissingItems(urls, ForgeConstants.IMAGE_LIST_QUEST_TOKENS_FILE, ForgeConstants.CACHE_TOKEN_PICS_DIR); diff --git a/forge-gui-desktop/src/main/java/forge/gui/BoxedProductCardListViewer.java b/forge-gui-desktop/src/main/java/forge/gui/BoxedProductCardListViewer.java new file mode 100644 index 00000000000..b12e05abc35 --- /dev/null +++ b/forge-gui-desktop/src/main/java/forge/gui/BoxedProductCardListViewer.java @@ -0,0 +1,178 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package forge.gui; + +import forge.game.card.Card; +import forge.item.PaperCard; +import forge.toolbox.FButton; +import forge.toolbox.FLabel; +import forge.toolbox.FScrollPane; +import forge.view.FDialog; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowFocusListener; +import java.util.Collections; +import java.util.List; + +/** + * A simple class that shows a list of cards in a dialog with preview in its + * right part. + * + * @author Forge + * @version $Id: ListChooser.java 9708 2011-08-09 19:34:12Z jendave $ + */ +@SuppressWarnings("serial") +public class BoxedProductCardListViewer extends FDialog { + + // Data and number of choices for the list + private final List list; + + // initialized before; listeners may be added to it + private final JList jList; + private final CardDetailPanel detail; + private final CardPicturePanel picture; + + private boolean skipTheRest = false; + + /** + * Instantiates a new card list viewer. + * + * @param title + * the title + * @param list + * the list + */ + public BoxedProductCardListViewer(final String title, final List list) { + this(title, "", list, null); + } + + /** + * Instantiates a new card list viewer. + * + * @param title + * the title + * @param message + * the message + * @param list + * the list + */ + public BoxedProductCardListViewer(final String title, final String message, final List list) { + this(title, message, list, null); + } + + /** + * Instantiates a new card list viewer. + * + * @param title + * the title + * @param message + * the message + * @param list + * the list + * @param dialogIcon + * the dialog icon + */ + public BoxedProductCardListViewer(final String title, final String message, final List list, final Icon dialogIcon) { + this.list = Collections.unmodifiableList(list); + this.jList = new JList(new ChooserListModel()); + this.detail = new CardDetailPanel(null); + this.picture = new CardPicturePanel(); + this.picture.setOpaque(false); + + this.setTitle(title); + this.setSize(720, 374); + this.addWindowFocusListener(new CardListFocuser()); + + FButton btnOK = new FButton("Next Pack"); + btnOK.addActionListener(new ActionListener() { + @Override + public void actionPerformed(final ActionEvent e) { + BoxedProductCardListViewer.this.processWindowEvent(new WindowEvent(BoxedProductCardListViewer.this, WindowEvent.WINDOW_CLOSING)); + } + }); + + FButton btnCancel = new FButton("Open All Remaining"); + btnCancel.addActionListener(new ActionListener() { + @Override + public void actionPerformed(final ActionEvent e) { + BoxedProductCardListViewer.this.skipTheRest = true; + BoxedProductCardListViewer.this.processWindowEvent(new WindowEvent(BoxedProductCardListViewer.this, WindowEvent.WINDOW_CLOSING)); + } + }); + + this.add(new FLabel.Builder().text(message).build(), "cell 0 0, spanx 3, gapbottom 4"); + this.add(new FScrollPane(this.jList, true), "cell 0 1, w 225, growy, pushy, ax c"); + this.add(this.picture, "cell 1 1, w 225, growy, pushy, ax c"); + this.add(this.detail, "cell 2 1, w 225, growy, pushy, ax c"); + this.add(btnOK, "cell 1 2, w 150, h 26, ax c, gaptop 6"); + this.add(btnCancel, "cell 2 2, w 205, h 26, ax c, gaptop 6"); + + // selection is here + this.jList.getSelectionModel().addListSelectionListener(new SelListener()); + this.jList.setSelectedIndex(0); + } + + public boolean skipTheRest() { + return skipTheRest; + } + + private class ChooserListModel extends AbstractListModel { + private static final long serialVersionUID = 3871965346333840556L; + + @Override + public int getSize() { + return BoxedProductCardListViewer.this.list.size(); + } + + @Override + public PaperCard getElementAt(final int index) { + return BoxedProductCardListViewer.this.list.get(index); + } + } + + private class CardListFocuser implements WindowFocusListener { + @Override + public void windowGainedFocus(final WindowEvent e) { + BoxedProductCardListViewer.this.jList.grabFocus(); + } + + @Override + public void windowLostFocus(final WindowEvent e) { + } + } + + private class SelListener implements ListSelectionListener { + @Override + public void valueChanged(final ListSelectionEvent e) { + final int row = BoxedProductCardListViewer.this.jList.getSelectedIndex(); + // (String) jList.getSelectedValue(); + if ((row >= 0) && (row < BoxedProductCardListViewer.this.list.size())) { + final PaperCard cp = BoxedProductCardListViewer.this.list.get(row); + BoxedProductCardListViewer.this.detail.setCard(Card.getCardForUi(cp)); + BoxedProductCardListViewer.this.picture.setCard(cp); + } + } + } +} diff --git a/forge-gui-desktop/src/main/java/forge/gui/CardListViewer.java b/forge-gui-desktop/src/main/java/forge/gui/CardListViewer.java index c25293fdccc..18073b4cb1b 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/CardListViewer.java +++ b/forge-gui-desktop/src/main/java/forge/gui/CardListViewer.java @@ -100,7 +100,7 @@ public class CardListViewer extends FDialog { this.picture.setOpaque(false); this.setTitle(title); - this.setSize(720, 360); + this.setSize(720, 374); this.addWindowFocusListener(new CardListFocuser()); FButton btnOK = new FButton("OK"); diff --git a/forge-gui-desktop/src/main/java/forge/gui/ImportSourceAnalyzer.java b/forge-gui-desktop/src/main/java/forge/gui/ImportSourceAnalyzer.java index bcd28da192b..6137424df1b 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/ImportSourceAnalyzer.java +++ b/forge-gui-desktop/src/main/java/forge/gui/ImportSourceAnalyzer.java @@ -494,6 +494,8 @@ public class ImportSourceAnalyzer { _analyzeSimpleListedDir(dir, ForgeConstants.IMAGE_LIST_QUEST_BOOSTERS_FILE, ForgeConstants.CACHE_BOOSTER_PICS_DIR, OpType.QUEST_PIC); } else if ("fatpacks".equalsIgnoreCase(dirName)) { _analyzeSimpleListedDir(dir, ForgeConstants.IMAGE_LIST_QUEST_FATPACKS_FILE, ForgeConstants.CACHE_FATPACK_PICS_DIR, OpType.QUEST_PIC); + } else if ("boosterboxes".equalsIgnoreCase(dirName)) { + _analyzeSimpleListedDir(dir, ForgeConstants.IMAGE_LIST_QUEST_BOOSTERBOXES_FILE, ForgeConstants.CACHE_BOOSTERBOX_PICS_DIR, OpType.QUEST_PIC); } else if ("precons".equalsIgnoreCase(dirName)) { _analyzeSimpleListedDir(dir, ForgeConstants.IMAGE_LIST_QUEST_PRECONS_FILE, ForgeConstants.CACHE_PRECON_PICS_DIR, OpType.QUEST_PIC); } else if ("tournamentpacks".equalsIgnoreCase(dirName)) { diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuestCardShop.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuestCardShop.java index b093bdd0223..1e8de1acaf7 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuestCardShop.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuestCardShop.java @@ -25,6 +25,7 @@ import forge.deck.CardPool; import forge.deck.Deck; import forge.deck.DeckBase; import forge.deck.DeckSection; +import forge.gui.BoxedProductCardListViewer; import forge.gui.CardListViewer; import forge.gui.framework.DragCell; import forge.gui.framework.FScreen; @@ -35,6 +36,7 @@ import forge.itemmanager.SItemManagerUtil; import forge.itemmanager.SpellShopManager; import forge.itemmanager.views.ItemTableColumn; import forge.model.FModel; +import forge.properties.ForgePreferences.FPref; import forge.quest.QuestController; import forge.quest.io.ReadPriceList; import forge.screens.deckeditor.views.*; @@ -50,6 +52,7 @@ import javax.swing.*; import java.text.DecimalFormat; import java.text.NumberFormat; +import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -213,6 +216,8 @@ public final class CEditorQuestCardShop extends ACEditorBase newCards = booster.getCards(); itemsToAdd.addAllFlat(newCards); - - final CardListViewer c = new CardListViewer(booster.getName(), "You have found the following cards inside:", newCards); - c.setVisible(true); - c.dispose(); + + if (booster instanceof BoxedProduct && FModel.getPreferences().getPrefBoolean(FPref.UI_OPEN_PACKS_INDIV)) { + + int totalPacks = ((BoxedProduct) booster).boosterPacksRemaining(); + boolean skipTheRest = false; + final List remainingCards = new ArrayList<>(); + + while (((BoxedProduct) booster).boosterPacksRemaining() > 0 && !skipTheRest) { + final BoxedProductCardListViewer c = new BoxedProductCardListViewer(booster.getName(), "You have found the following cards inside (Booster Pack " + (totalPacks - ((BoxedProduct) booster).boosterPacksRemaining() + 1) + " of " + totalPacks + "):", ((BoxedProduct) booster).getNextBoosterPack()); + c.setVisible(true); + c.dispose(); + skipTheRest = c.skipTheRest(); + } + + if (skipTheRest) { + while (((BoxedProduct) booster).boosterPacksRemaining() > 0) { + remainingCards.addAll(((BoxedProduct) booster).getNextBoosterPack()); + } + } + + remainingCards.addAll(((BoxedProduct) booster).getExtraCards()); + + if (remainingCards.size() > 0) { + final CardListViewer c = new CardListViewer(booster.getName(), "You have found the following cards inside:", remainingCards); + c.setVisible(true); + c.dispose(); + } + + } else { + final CardListViewer c = new CardListViewer(booster.getName(), "You have found the following cards inside:", newCards); + c.setVisible(true); + c.dispose(); + } + } } else if (item instanceof PreconDeck) { diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java index 09cb6bb148a..d335354f66c 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java @@ -89,6 +89,7 @@ public enum CSubmenuPreferences implements ICDoc { lstControls.add(Pair.of(view.getCbPromptFreeBlocks(), FPref.MATCHPREF_PROMPT_FREE_BLOCKS)); lstControls.add(Pair.of(view.getCbCompactPrompt(), FPref.UI_COMPACT_PROMPT)); lstControls.add(Pair.of(view.getCbHideReminderText(), FPref.UI_HIDE_REMINDER_TEXT)); + lstControls.add(Pair.of(view.getCbOpenPacksIndiv(), FPref.UI_OPEN_PACKS_INDIV)); for(final Pair kv : lstControls) { kv.getKey().addItemListener(new ItemListener() { diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java index 5a4354bb4bf..1c7da0efbe4 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java @@ -79,6 +79,7 @@ public enum VSubmenuPreferences implements IVSubmenu { private final JCheckBox cbPromptFreeBlocks = new OptionsCheckBox("Free Block Handling"); private final JCheckBox cbCompactPrompt = new OptionsCheckBox("Compact Prompt"); private final JCheckBox cbHideReminderText = new OptionsCheckBox("Hide Reminder Text"); + private final JCheckBox cbOpenPacksIndiv = new OptionsCheckBox("Open Packs Individually"); private final Map shortcutFields = new HashMap(); @@ -206,6 +207,9 @@ public enum VSubmenuPreferences implements IVSubmenu { pnlPrefs.add(cbHideReminderText, regularConstraints); pnlPrefs.add(new NoteLabel("Hide reminder text in Card Detail pane."), regularConstraints); + pnlPrefs.add(cbOpenPacksIndiv, regularConstraints); + pnlPrefs.add(new NoteLabel("When opening Fat Packs and Booster Boxes, booster packs will be opened and displayed one at a time."), regularConstraints); + // Sound options pnlPrefs.add(new SectionLabel("Sound Options"), sectionConstraints + ", gaptop 2%"); @@ -510,6 +514,10 @@ public enum VSubmenuPreferences implements IVSubmenu { return cbHideReminderText; } + public final JCheckBox getCbOpenPacksIndiv() { + return cbOpenPacksIndiv; + } + /** @return {@link forge.toolbox.FLabel} */ public FLabel getBtnReset() { return btnReset;