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).

This commit is contained in:
Krazy
2014-04-20 23:26:20 +00:00
parent 61723676ed
commit dbe80258c0
9 changed files with 237 additions and 5 deletions

1
.gitattributes vendored
View File

@@ -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/download/package-info.java -text
forge-gui-desktop/src/main/java/forge/error/BugReportDialog.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/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/CardContainer.java -text
forge-gui-desktop/src/main/java/forge/gui/CardDetailPanel.java -text forge-gui-desktop/src/main/java/forge/gui/CardDetailPanel.java -text
forge-gui-desktop/src/main/java/forge/gui/CardListViewer.java -text forge-gui-desktop/src/main/java/forge/gui/CardListViewer.java -text

View File

@@ -39,6 +39,9 @@ final class ImageLoader extends CacheLoader<String, BufferedImage> {
} else if (key.startsWith(ImageKeys.FATPACK_PREFIX)) { } else if (key.startsWith(ImageKeys.FATPACK_PREFIX)) {
filename = key.substring(ImageKeys.FATPACK_PREFIX.length()); filename = key.substring(ImageKeys.FATPACK_PREFIX.length());
path = ForgeConstants.CACHE_FATPACK_PICS_DIR; 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)) { } else if (key.startsWith(ImageKeys.PRECON_PREFIX)) {
filename = key.substring(ImageKeys.PRECON_PREFIX.length()); filename = key.substring(ImageKeys.PRECON_PREFIX.length());
path = ForgeConstants.CACHE_PRECON_PICS_DIR; path = ForgeConstants.CACHE_PRECON_PICS_DIR;

View File

@@ -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_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_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_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_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_TOURNAMENTPACKS_FILE, ForgeConstants.CACHE_TOURNAMENTPACK_PICS_DIR);
addMissingItems(urls, ForgeConstants.IMAGE_LIST_QUEST_TOKENS_FILE, ForgeConstants.CACHE_TOKEN_PICS_DIR); addMissingItems(urls, ForgeConstants.IMAGE_LIST_QUEST_TOKENS_FILE, ForgeConstants.CACHE_TOKEN_PICS_DIR);

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<PaperCard> list;
// initialized before; listeners may be added to it
private final JList<PaperCard> 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<PaperCard> 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<PaperCard> 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<PaperCard> list, final Icon dialogIcon) {
this.list = Collections.unmodifiableList(list);
this.jList = new JList<PaperCard>(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<PaperCard> {
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);
}
}
}
}

View File

@@ -100,7 +100,7 @@ public class CardListViewer extends FDialog {
this.picture.setOpaque(false); this.picture.setOpaque(false);
this.setTitle(title); this.setTitle(title);
this.setSize(720, 360); this.setSize(720, 374);
this.addWindowFocusListener(new CardListFocuser()); this.addWindowFocusListener(new CardListFocuser());
FButton btnOK = new FButton("OK"); FButton btnOK = new FButton("OK");

View File

@@ -494,6 +494,8 @@ public class ImportSourceAnalyzer {
_analyzeSimpleListedDir(dir, ForgeConstants.IMAGE_LIST_QUEST_BOOSTERS_FILE, ForgeConstants.CACHE_BOOSTER_PICS_DIR, OpType.QUEST_PIC); _analyzeSimpleListedDir(dir, ForgeConstants.IMAGE_LIST_QUEST_BOOSTERS_FILE, ForgeConstants.CACHE_BOOSTER_PICS_DIR, OpType.QUEST_PIC);
} else if ("fatpacks".equalsIgnoreCase(dirName)) { } else if ("fatpacks".equalsIgnoreCase(dirName)) {
_analyzeSimpleListedDir(dir, ForgeConstants.IMAGE_LIST_QUEST_FATPACKS_FILE, ForgeConstants.CACHE_FATPACK_PICS_DIR, OpType.QUEST_PIC); _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)) { } else if ("precons".equalsIgnoreCase(dirName)) {
_analyzeSimpleListedDir(dir, ForgeConstants.IMAGE_LIST_QUEST_PRECONS_FILE, ForgeConstants.CACHE_PRECON_PICS_DIR, OpType.QUEST_PIC); _analyzeSimpleListedDir(dir, ForgeConstants.IMAGE_LIST_QUEST_PRECONS_FILE, ForgeConstants.CACHE_PRECON_PICS_DIR, OpType.QUEST_PIC);
} else if ("tournamentpacks".equalsIgnoreCase(dirName)) { } else if ("tournamentpacks".equalsIgnoreCase(dirName)) {

View File

@@ -25,6 +25,7 @@ import forge.deck.CardPool;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.DeckBase; import forge.deck.DeckBase;
import forge.deck.DeckSection; import forge.deck.DeckSection;
import forge.gui.BoxedProductCardListViewer;
import forge.gui.CardListViewer; import forge.gui.CardListViewer;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
@@ -35,6 +36,7 @@ import forge.itemmanager.SItemManagerUtil;
import forge.itemmanager.SpellShopManager; import forge.itemmanager.SpellShopManager;
import forge.itemmanager.views.ItemTableColumn; import forge.itemmanager.views.ItemTableColumn;
import forge.model.FModel; import forge.model.FModel;
import forge.properties.ForgePreferences.FPref;
import forge.quest.QuestController; import forge.quest.QuestController;
import forge.quest.io.ReadPriceList; import forge.quest.io.ReadPriceList;
import forge.screens.deckeditor.views.*; import forge.screens.deckeditor.views.*;
@@ -50,6 +52,7 @@ import javax.swing.*;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@@ -213,6 +216,8 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
value = 995; value = 995;
} else if (card instanceof FatPack) { } else if (card instanceof FatPack) {
value = 2365; value = 2365;
} else if (card instanceof BoosterBox) {
value = 8750;
} else if (card instanceof PreconDeck) { } else if (card instanceof PreconDeck) {
value = QuestController.getPreconDeals((PreconDeck) card).getCost(); value = QuestController.getPreconDeals((PreconDeck) card).getCost();
} }
@@ -348,14 +353,47 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
else if (item instanceof FatPack) { else if (item instanceof FatPack) {
booster = (FatPack) ((FatPack) item).clone(); booster = (FatPack) ((FatPack) item).clone();
} }
else if (item instanceof BoosterBox) {
booster = (BoosterBox) ((BoosterBox) item).clone();
}
this.questData.getCards().buyPack(booster, value); this.questData.getCards().buyPack(booster, value);
final List<PaperCard> newCards = booster.getCards(); final List<PaperCard> newCards = booster.getCards();
itemsToAdd.addAllFlat(newCards); itemsToAdd.addAllFlat(newCards);
final CardListViewer c = new CardListViewer(booster.getName(), "You have found the following cards inside:", newCards); if (booster instanceof BoxedProduct && FModel.getPreferences().getPrefBoolean(FPref.UI_OPEN_PACKS_INDIV)) {
c.setVisible(true);
c.dispose(); int totalPacks = ((BoxedProduct) booster).boosterPacksRemaining();
boolean skipTheRest = false;
final List<PaperCard> 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) { else if (item instanceof PreconDeck) {

View File

@@ -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.getCbPromptFreeBlocks(), FPref.MATCHPREF_PROMPT_FREE_BLOCKS));
lstControls.add(Pair.of(view.getCbCompactPrompt(), FPref.UI_COMPACT_PROMPT)); 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.getCbHideReminderText(), FPref.UI_HIDE_REMINDER_TEXT));
lstControls.add(Pair.of(view.getCbOpenPacksIndiv(), FPref.UI_OPEN_PACKS_INDIV));
for(final Pair<JCheckBox, FPref> kv : lstControls) { for(final Pair<JCheckBox, FPref> kv : lstControls) {
kv.getKey().addItemListener(new ItemListener() { kv.getKey().addItemListener(new ItemListener() {

View File

@@ -79,6 +79,7 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
private final JCheckBox cbPromptFreeBlocks = new OptionsCheckBox("Free Block Handling"); private final JCheckBox cbPromptFreeBlocks = new OptionsCheckBox("Free Block Handling");
private final JCheckBox cbCompactPrompt = new OptionsCheckBox("Compact Prompt"); private final JCheckBox cbCompactPrompt = new OptionsCheckBox("Compact Prompt");
private final JCheckBox cbHideReminderText = new OptionsCheckBox("Hide Reminder Text"); private final JCheckBox cbHideReminderText = new OptionsCheckBox("Hide Reminder Text");
private final JCheckBox cbOpenPacksIndiv = new OptionsCheckBox("Open Packs Individually");
private final Map<FPref, KeyboardShortcutField> shortcutFields = new HashMap<FPref, KeyboardShortcutField>(); private final Map<FPref, KeyboardShortcutField> shortcutFields = new HashMap<FPref, KeyboardShortcutField>();
@@ -206,6 +207,9 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
pnlPrefs.add(cbHideReminderText, regularConstraints); pnlPrefs.add(cbHideReminderText, regularConstraints);
pnlPrefs.add(new NoteLabel("Hide reminder text in Card Detail pane."), 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 // Sound options
pnlPrefs.add(new SectionLabel("Sound Options"), sectionConstraints + ", gaptop 2%"); pnlPrefs.add(new SectionLabel("Sound Options"), sectionConstraints + ", gaptop 2%");
@@ -510,6 +514,10 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
return cbHideReminderText; return cbHideReminderText;
} }
public final JCheckBox getCbOpenPacksIndiv() {
return cbOpenPacksIndiv;
}
/** @return {@link forge.toolbox.FLabel} */ /** @return {@link forge.toolbox.FLabel} */
public FLabel getBtnReset() { public FLabel getBtnReset() {
return btnReset; return btnReset;