Quest duels and challenges stored in separate arrays.

When you chose a quest challenge from Home screen, you also get all extra creatures on battlefield
Deck generation now able to correctly generate decks of definite + random color
MyRandom uses SecureRandom
This commit is contained in:
Maxmtg
2013-05-19 13:17:30 +00:00
parent 588273d5ee
commit 84674aeb86
40 changed files with 675 additions and 1048 deletions

View File

@@ -1,12 +1,10 @@
package forge.deck;
package forge.deck;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
@@ -15,6 +13,9 @@ import javax.swing.JOptionPane;
import org.apache.commons.lang3.ArrayUtils;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import forge.Singletons;
import forge.deck.generate.Generate2ColorDeck;
import forge.deck.generate.Generate3ColorDeck;
@@ -26,9 +27,12 @@ import forge.game.player.PlayerType;
import forge.item.CardDb;
import forge.item.CardPrinted;
import forge.item.ItemPoolView;
import forge.quest.QuestController;
import forge.quest.QuestEvent;
import forge.quest.QuestEventManager;
import forge.quest.QuestEventChallenge;
import forge.quest.QuestEventDuel;
import forge.util.Aggregates;
import forge.util.Lang;
import forge.util.MyRandom;
import forge.util.storage.IStorage;
@@ -42,21 +46,6 @@ import forge.util.storage.IStorage;
// TODO This class can be used for home menu constructed deck generation as well.
public class DeckgenUtil {
/** */
public static final Map<String, String> COLOR_VALS = new HashMap<String, String>();
static {
COLOR_VALS.clear();
COLOR_VALS.put("Random 1", "AI");
COLOR_VALS.put("Random 2", "AI");
COLOR_VALS.put("Random 3", "AI");
COLOR_VALS.put("Random 4", "AI");
COLOR_VALS.put("Black", "black");
COLOR_VALS.put("Blue", "blue");
COLOR_VALS.put("Green", "green");
COLOR_VALS.put("Red", "red");
COLOR_VALS.put("White", "white");
}
public enum DeckTypes {
COLORS,
THEMES,
@@ -71,12 +60,8 @@ public class DeckgenUtil {
public static Deck buildColorDeck(final String[] selection, PlayerType pt) {
final Deck deck;
// Replace "random" with "AI" for deck generation code
for (int i = 0; i < selection.length; i++) {
selection[i] = COLOR_VALS.get(selection[i]);
}
String deckName = null;
GenerateColoredDeckBase gen = null;
if (selection.length == 1) {
@@ -87,12 +72,16 @@ public class DeckgenUtil {
gen = new Generate3ColorDeck(selection[0], selection[1], selection[2]);
} else {
gen = new Generate5ColorDeck();
deckName = "5 colors";
}
ItemPoolView<CardPrinted> cards = gen == null ? null : gen.getDeck(60, pt);
if(null == deckName)
deckName = Lang.joinHomogenous(Arrays.asList(selection));
// After generating card lists, build deck.
deck = new Deck();
deck = new Deck("Random deck : " + deckName);
deck.getMain().addAll(cards);
return deck;
@@ -127,7 +116,18 @@ public class DeckgenUtil {
* @return {@link forge.deck.Deck}
*/
public static Deck buildQuestDeck(final String[] selection) {
return Singletons.getModel().getQuest().getDuelsManager().getEvent(selection[0]).getEventDeck();
return getQuestEvent(selection[0]).getEventDeck();
}
public static QuestEvent getQuestEvent(final String name) {
QuestController qCtrl = Singletons.getModel().getQuest();
QuestEventChallenge challenge = qCtrl.getChallenges().get(name);
if( null != challenge ) return challenge;
QuestEventDuel duel = Iterables.find(qCtrl.getDuelsManager().getAllDuels(), new Predicate<QuestEventDuel>() {
@Override public boolean apply(QuestEventDuel in) { return in.getName().equals(name); }
});
return duel;
}
/** @return {@link forge.deck.Deck} */
@@ -161,13 +161,14 @@ public class DeckgenUtil {
/** @return {@link forge.deck.Deck} */
public static Deck getRandomQuestDeck() {
final List<Deck> allQuestDecks = new ArrayList<Deck>();
final QuestEventManager manager = Singletons.getModel().getQuest().getDuelsManager();
QuestController qCtrl = Singletons.getModel().getQuest();
for (final QuestEvent e : manager.getAllDuels()) {
for (final QuestEvent e : qCtrl.getDuelsManager().getAllDuels()) {
allQuestDecks.add(e.getEventDeck());
}
for (final QuestEvent e : manager.getAllChallenges()) {
for (final QuestEvent e : qCtrl.getChallenges()) {
allQuestDecks.add(e.getEventDeck());
}
@@ -227,10 +228,8 @@ public class DeckgenUtil {
// Retrieve from custom or quest deck maps
if (lst0.getName().equals(DeckTypes.CUSTOM.toString())) {
deck = Singletons.getModel().getDecks().getConstructed().get(deckName);
}
else {
deck = Singletons.getModel().getQuest().getDuelsManager().getEvent(deckName).getEventDeck();
}
} else
deck = getQuestEvent(deckName).getEventDeck();
// Dump into map and display.
final String nl = System.getProperty("line.separator");

View File

@@ -17,6 +17,7 @@
*/
package forge.deck.generate;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang3.tuple.ImmutablePair;
@@ -68,13 +69,20 @@ public class Generate2ColorDeck extends GenerateColoredDeckBase {
* a {@link java.lang.String} object.
*/
public Generate2ColorDeck(final String clr1, final String clr2) {
if (clr1.equals("AI")) {
int c1 = MagicColor.fromName(clr1);
int c2 = MagicColor.fromName(clr2);
if( c1 == 0 && c2 == 0) {
int color1 = r.nextInt(5);
int color2 = (color1 + 1 + r.nextInt(4)) % 5;
colors = ColorSet.fromMask(MagicColor.WHITE << color1 | MagicColor.WHITE << color2);
} else if ( c1 == 0 || c2 == 0 ) {
byte knownColor = (byte) (c1 | c2);
int color1 = Arrays.binarySearch(MagicColor.WUBRG, knownColor);
int color2 = (color1 + 1 + r.nextInt(4)) % 5;
colors = ColorSet.fromMask(MagicColor.WHITE << color1 | MagicColor.WHITE << color2);
} else {
colors = ColorSet.fromNames(clr1, clr2);
colors = ColorSet.fromMask(c1 | c2);
}
}

View File

@@ -29,6 +29,7 @@ import forge.deck.generate.GenerateDeckUtil.FilterCMC;
import forge.game.player.PlayerType;
import forge.item.CardPrinted;
import forge.item.ItemPoolView;
import forge.util.MyRandom;
/**
* <p>
@@ -59,13 +60,40 @@ public class Generate3ColorDeck extends GenerateColoredDeckBase {
* a {@link java.lang.String} object.
*/
public Generate3ColorDeck(final String clr1, final String clr2, final String clr3) {
if (clr1.equals("AI")) {
int color1 = r.nextInt(5);
int color2 = (color1 + 1 + r.nextInt(4)) % 5;
colors = ColorSet.fromMask(MagicColor.WHITE << color1 | MagicColor.WHITE << color2).inverse();
} else {
colors = ColorSet.fromNames(clr1, clr2, clr3);
int c1 = MagicColor.fromName(clr1);
int c2 = MagicColor.fromName(clr2);
int c3 = MagicColor.fromName(clr3);
int rc = 0;
int combo = c1 | c2 | c3;
ColorSet param = ColorSet.fromMask(combo);
switch(param.countColors()) {
case 3:
colors = param;
return;
case 0:
int color1 = r.nextInt(5);
int color2 = (color1 + 1 + r.nextInt(4)) % 5;
colors = ColorSet.fromMask(MagicColor.WHITE << color1 | MagicColor.WHITE << color2).inverse();
return;
case 1:
do {
rc = MagicColor.WHITE << MyRandom.getRandom().nextInt(5);
} while ( rc == combo );
combo |= rc;
// fall-through
case 2:
do {
rc = MagicColor.WHITE << MyRandom.getRandom().nextInt(5);
} while ( (rc & combo) != 0 );
combo |= rc;
break;
}
colors = ColorSet.fromMask(combo);
}
/**

View File

@@ -69,8 +69,7 @@ public class GenerateMonoColorDeck extends GenerateColoredDeckBase {
* a {@link java.lang.String} object.
*/
public GenerateMonoColorDeck(final String clr1) {
if (clr1.equals("AI")) {
if (MagicColor.fromName(clr1) == 0) {
int color1 = r.nextInt(5);
colors = ColorSet.fromMask(MagicColor.WHITE << color1);
} else {

View File

@@ -106,11 +106,11 @@ public enum CDeckgen implements ICDoc {
switch (colorCount0) {
case 2:
genConstructed.getMain().addAll(
(new Generate2ColorDeck("AI", "AI")).getDeck(60, PlayerType.HUMAN));
(new Generate2ColorDeck(null, null)).getDeck(60, PlayerType.HUMAN));
break;
case 3:
genConstructed.getMain().addAll(
(new Generate3ColorDeck("AI", "AI", "AI")).getDeck(60, PlayerType.HUMAN));
(new Generate3ColorDeck(null, null, null)).getDeck(60, PlayerType.HUMAN));
break;
case 5:
genConstructed.getMain().addAll(

View File

@@ -1,16 +1,10 @@
package forge.gui.home.gauntlet;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JFileChooser;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
@@ -19,19 +13,11 @@ import javax.swing.filechooser.FileFilter;
import org.apache.commons.lang3.ArrayUtils;
import forge.Command;
import forge.Singletons;
import forge.deck.Deck;
import forge.deck.DeckgenUtil;
import forge.deck.DeckgenUtil.DeckTypes;
import forge.deck.generate.GenerateThemeDeck;
import forge.game.player.PlayerType;
import forge.gauntlet.GauntletData;
import forge.gauntlet.GauntletIO;
import forge.gui.framework.ICDoc;
import forge.properties.NewConstants;
import forge.quest.QuestController;
import forge.quest.QuestEvent;
import forge.util.storage.IStorage;
/**
* Controls the "build gauntlet" submenu in the home UI.
@@ -65,17 +51,6 @@ public enum CSubmenuGauntletBuild implements ICDoc {
}
};
private final MouseAdapter madDecklist = new MouseAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
if (e.getClickCount() == 2) {
if (view.getRadColorDecks().isSelected()) { return; }
if (view.getRadThemeDecks().isSelected()) { return; }
DeckgenUtil.showDecklist(((JList) e.getSource())); }
}
};
//private final KeyAdapter kadSearch = new KeyAdapter() { @Override
//public void keyPressed(final KeyEvent e) { search(); } };
@@ -115,22 +90,7 @@ public enum CSubmenuGauntletBuild implements ICDoc {
*/
@Override
public void initialize() {
final ActionListener deckUpdate = new ActionListener() {
@Override
public void actionPerformed(final ActionEvent arg0) {
updateDecks(); }
};
view.getLstRight().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
view.getLstLeft().addMouseListener(madDecklist);
// Deck list and radio button event handling
view.getRadUserDecks().setSelected(true);
view.getRadQuestDecks().addActionListener(deckUpdate);
view.getRadColorDecks().addActionListener(deckUpdate);
view.getRadThemeDecks().addActionListener(deckUpdate);
view.getRadUserDecks().addActionListener(deckUpdate);
view.getBtnRight().setCommand(cmdAddDeck);
view.getBtnLeft().setCommand(cmdRemoveDeck);
@@ -140,7 +100,9 @@ public enum CSubmenuGauntletBuild implements ICDoc {
view.getBtnSave().setCommand(cmdSave);
view.getBtnOpen().setCommand(cmdOpen);
view.getBtnNew().setCommand(cmdNew);
updateDecks();
view.getLstLeft().initialize();
// updateDecks();
}
/* (non-Javadoc)
@@ -151,103 +113,11 @@ public enum CSubmenuGauntletBuild implements ICDoc {
return null;
}
/** Handles all control for "custom" radio button click. */
private void updateDecks() {
if (view.getRadUserDecks().isSelected()) {
updateUserDecks();
}
else if (view.getRadQuestDecks().isSelected()) {
updateQuestDecks();
}
else if (view.getRadThemeDecks().isSelected()) {
updateThemeDecks();
}
else if (view.getRadColorDecks().isSelected()) {
updateColorDecks();
}
}
private void updateUserDecks() {
final List<String> customNames = new ArrayList<String>();
final IStorage<Deck> allDecks = Singletons.getModel().getDecks().getConstructed();
for (final Deck d : allDecks) { customNames.add(d.getName()); }
view.getLstLeft().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
view.getLstLeft().setListData(customNames.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
view.getLstLeft().setName(DeckTypes.CUSTOM.toString());
// Init first in list
view.getLstLeft().setSelectedIndex(0);
}
/** Handles all control for "quest event" radio button click. */
private void updateQuestDecks() {
final List<String> eventNames = new ArrayList<String>();
QuestController quest = Singletons.getModel().getQuest();
for (final QuestEvent e : quest.getDuelsManager().getAllDuels()) {
eventNames.add(e.getEventDeck().getName());
}
for (final QuestEvent e : quest.getChallengesManager().getAllChallenges()) {
eventNames.add(e.getEventDeck().getName());
}
view.getLstLeft().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
view.getLstLeft().setListData(eventNames.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
view.getLstLeft().setName(DeckTypes.QUESTEVENTS.toString());
// Init first in list
view.getLstLeft().setSelectedIndex(0);
}
/** Handles all control for "themes" radio button click. */
private void updateThemeDecks() {
final List<String> themeNames = new ArrayList<String>();
for (final String s : GenerateThemeDeck.getThemeNames()) { themeNames.add(s); }
view.getLstLeft().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
view.getLstLeft().setListData(themeNames.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
view.getLstLeft().setName(DeckTypes.THEMES.toString());
// Init first in list
view.getLstLeft().setSelectedIndex(0);
}
/** Handles all control for "colors" radio button click. */
private void updateColorDecks() {
view.getLstLeft().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
view.getLstLeft().setListData(new String[] {"Random 1", "Random 2", "Random 3",
"Random 4", "Black", "Blue", "Green", "Red", "White"});
view.getLstLeft().setName(DeckTypes.COLORS.toString());
// Init basic two color deck
view.getLstLeft().setSelectedIndices(new int[]{0, 1});
}
private void addDeck() {
final Deck deckToAdd;
final String[] selection = Arrays.asList(
view.getLstLeft().getSelectedValues()).toArray(new String[0]);
if (selection.length == 0) { return; }
if (view.getRadColorDecks().isSelected()) {
if (!DeckgenUtil.colorCheck(selection)) { return; }
deckToAdd = DeckgenUtil.buildColorDeck(selection, PlayerType.HUMAN);
}
else if (view.getRadQuestDecks().isSelected()) {
deckToAdd = DeckgenUtil.buildQuestDeck(selection);
}
else if (view.getRadThemeDecks().isSelected()) {
deckToAdd = DeckgenUtil.buildThemeDeck(selection);
}
else {
deckToAdd = DeckgenUtil.getConstructedDeck(selection);
}
final Deck deckToAdd = view.getLstLeft().getDeck().getOriginalDeck();
if ( null == deckToAdd ) return;
workingDecks.add(deckToAdd);
view.getLblSave().setVisible(false);
dumpDecksIntoList();
}

View File

@@ -6,34 +6,24 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JList;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import org.apache.commons.lang3.ArrayUtils;
import forge.Command;
import forge.FThreads;
import forge.Singletons;
import forge.control.Lobby;
import forge.deck.Deck;
import forge.deck.DeckgenUtil;
import forge.deck.DeckgenUtil.DeckTypes;
import forge.deck.generate.GenerateThemeDeck;
import forge.game.GameType;
import forge.game.MatchController;
import forge.game.MatchStartHelper;
import forge.game.player.PlayerType;
import forge.gauntlet.GauntletData;
import forge.gauntlet.GauntletIO;
import forge.gui.SOverlayUtils;
import forge.gui.framework.ICDoc;
import forge.model.FModel;
import forge.quest.QuestController;
import forge.quest.QuestEvent;
import forge.util.storage.IStorage;
/**
* Controls the "gauntlet contests" submenu in the home UI.
@@ -64,20 +54,6 @@ public enum CSubmenuGauntletContests implements ICDoc {
}
};
private final Command cmdRandomRegular = new Command() {
@Override
public void run() {
DeckgenUtil.randomSelect(view.getLstDecks());
}
};
private final Command cmdRandomColors = new Command() {
@Override
public void run() {
view.getLstDecks().setSelectedIndices(DeckgenUtil.randomSelectColors());
}
};
/* (non-Javadoc)
* @see forge.gui.home.ICSubmenu#initialize()
*/
@@ -93,48 +69,15 @@ public enum CSubmenuGauntletContests implements ICDoc {
*/
@Override
public void initialize() {
final ActionListener deckUpdate = new ActionListener() {
@Override
public void actionPerformed(final ActionEvent arg0) {
updateDecks(); }
};
view.getBtnStart().addActionListener(actStartGame);
view.getLstDecks().addMouseListener(madDecklist);
// Deck list and radio button event handling
view.getRadUserDecks().setSelected(true);
view.getRadQuestDecks().addActionListener(deckUpdate);
view.getRadColorDecks().addActionListener(deckUpdate);
view.getRadThemeDecks().addActionListener(deckUpdate);
view.getRadUserDecks().addActionListener(deckUpdate);
updateDecks();
view.getLstDecks().initialize();
updateData();
view.getGauntletLister().setSelectedIndex(0);
}
/** Handles all control for "custom" radio button click. */
private void updateDecks() {
if (view.getRadUserDecks().isSelected()) {
view.getBtnRandom().setCommand(cmdRandomRegular);
updateUserDecks();
}
else if (view.getRadQuestDecks().isSelected()) {
view.getBtnRandom().setCommand(cmdRandomRegular);
updateQuestDecks();
}
else if (view.getRadThemeDecks().isSelected()) {
view.getBtnRandom().setCommand(cmdRandomRegular);
updateThemeDecks();
}
else if (view.getRadColorDecks().isSelected()) {
view.getBtnRandom().setCommand(cmdRandomColors);
updateColorDecks();
}
}
private void updateData() {
final File[] files = GauntletIO.getGauntletFilesLocked();
@@ -147,64 +90,6 @@ public enum CSubmenuGauntletContests implements ICDoc {
view.getGauntletLister().setSelectedIndex(0);
}
private void updateUserDecks() {
final List<String> customNames = new ArrayList<String>();
final IStorage<Deck> allDecks = Singletons.getModel().getDecks().getConstructed();
for (final Deck d : allDecks) { customNames.add(d.getName()); }
view.getLstDecks().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
view.getLstDecks().setListData(customNames.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
view.getLstDecks().setName(DeckTypes.CUSTOM.toString());
// Init first in list
view.getLstDecks().setSelectedIndex(0);
}
/** Handles all control for "quest event" radio button click. */
private void updateQuestDecks() {
final List<String> eventNames = new ArrayList<String>();
QuestController quest = Singletons.getModel().getQuest();
for (final QuestEvent e : quest.getDuelsManager().getAllDuels()) {
eventNames.add(e.getEventDeck().getName());
}
for (final QuestEvent e : quest.getChallengesManager().getAllChallenges()) {
eventNames.add(e.getEventDeck().getName());
}
view.getLstDecks().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
view.getLstDecks().setListData(eventNames.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
view.getLstDecks().setName(DeckTypes.QUESTEVENTS.toString());
// Init first in list
view.getLstDecks().setSelectedIndex(0);
}
/** Handles all control for "themes" radio button click. */
private void updateThemeDecks() {
final List<String> themeNames = new ArrayList<String>();
for (final String s : GenerateThemeDeck.getThemeNames()) { themeNames.add(s); }
view.getLstDecks().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
view.getLstDecks().setListData(themeNames.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
view.getLstDecks().setName(DeckTypes.THEMES.toString());
// Init first in list
view.getLstDecks().setSelectedIndex(0);
}
/** Handles all control for "colors" radio button click. */
private void updateColorDecks() {
view.getLstDecks().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
view.getLstDecks().setListData(new String[] {"Random 1", "Random 2", "Random 3",
"Random 4", "Black", "Blue", "Green", "Red", "White"});
view.getLstDecks().setName(DeckTypes.COLORS.toString());
// Init basic two color deck
view.getLstDecks().setSelectedIndices(new int[]{0, 1});
}
/** */
private void startGame() {
final GauntletData gd = view.getGauntletLister().getSelectedGauntlet();
@@ -214,22 +99,7 @@ public enum CSubmenuGauntletContests implements ICDoc {
userDeck = gd.getUserDeck();
}
else {
final String[] selection = Arrays.asList(
view.getLstDecks().getSelectedValues()).toArray(new String[0]);
if (view.getRadColorDecks().isSelected()) {
if (!DeckgenUtil.colorCheck(selection)) { return; }
userDeck = DeckgenUtil.buildColorDeck(selection, PlayerType.HUMAN);
}
else if (view.getRadQuestDecks().isSelected()) {
userDeck = DeckgenUtil.buildQuestDeck(selection);
}
else if (view.getRadThemeDecks().isSelected()) {
userDeck = DeckgenUtil.buildThemeDeck(selection);
}
else {
userDeck = DeckgenUtil.getConstructedDeck(selection);
}
userDeck = view.getLstDecks().getDeck().getOriginalDeck();
gd.setUserDeck(userDeck);
}

View File

@@ -170,7 +170,7 @@ public enum CSubmenuGauntletQuick implements ICDoc {
eventNames.add(e.getEventDeck().getName());
}
for (final QuestEvent e : quest.getChallengesManager().getAllChallenges()) {
for (final QuestEvent e : quest.getChallenges()) {
eventNames.add(e.getEventDeck().getName());
}
@@ -279,18 +279,14 @@ public enum CSubmenuGauntletQuick implements ICDoc {
lstGauntletDecks.add(tempDeck);
}
FModel.SINGLETON_INSTANCE.getGauntletData()
.setDecks(lstGauntletDecks);
FModel.SINGLETON_INSTANCE.getGauntletData()
.setEventNames(lstEventNames);
final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData();
gd.setDecks(lstGauntletDecks);
gd.setEventNames(lstEventNames);
// Reset all variable fields to 0, stamps and saves automatically.
FModel.SINGLETON_INSTANCE.getGauntletData().reset();
gd.reset();
gd.setUserDeck(userDeck);
FModel.SINGLETON_INSTANCE.getGauntletData().setUserDeck(userDeck);
final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData();
final Deck aiDeck = gd.getDecks().get(gd.getCompleted());
MatchStartHelper starter = new MatchStartHelper();

View File

@@ -2,18 +2,17 @@ package forge.gui.home.gauntlet;
import java.awt.Color;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import net.miginfocom.swing.MigLayout;
import forge.game.player.PlayerType;
import forge.gauntlet.GauntletIO;
import forge.gui.framework.DragCell;
import forge.gui.framework.DragTab;
@@ -21,9 +20,9 @@ import forge.gui.framework.EDocID;
import forge.gui.home.EMenuGroup;
import forge.gui.home.IVSubmenu;
import forge.gui.home.VHomeUI;
import forge.gui.toolbox.FDeckChooser;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FList;
import forge.gui.toolbox.FRadioButton;
import forge.gui.toolbox.FScrollPane;
import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FTextField;
@@ -48,30 +47,19 @@ public enum VSubmenuGauntletBuild implements IVSubmenu<CSubmenuGauntletBuild> {
.opaque(true).fontSize(16).build();
private final JPanel pnlFileHandling = new JPanel(new MigLayout("insets 0, gap 0, align center"));
private final JPanel pnlRadios = new JPanel(new MigLayout("insets 0, gap 0, wrap"));
private final JPanel pnlButtons = new JPanel();
private final JPanel pnlStrut = new JPanel();
private final JPanel pnlDirections = new JPanel();
private final JRadioButton radUserDecks = new FRadioButton("Custom user decks");
private final JRadioButton radQuestDecks = new FRadioButton("Quest Decks");
private final JRadioButton radColorDecks = new FRadioButton("Fully random color decks");
private final JRadioButton radThemeDecks = new FRadioButton("Semi-random theme decks");
private final JList lstLeft = new FList();
private final FDeckChooser lstLeft = new FDeckChooser("Deck", PlayerType.HUMAN);
private final JList lstRight = new FList();
private final JScrollPane scrLeft = new FScrollPane(lstLeft,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
private final JScrollPane scrRight = new FScrollPane(lstRight,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
private final JTextField txfFilename = new FTextField.Builder().text(GauntletIO.TXF_PROMPT).build();
private final FLabel lblDesc1 = new FLabel.Builder()
.text("Left/right arrows add or remove decks.")
.fontSize(12).build();
private final FLabel lblDesc1 = new FLabel.Builder().text("Left/right arrows add or remove decks.").fontSize(12).build();
private final FLabel lblDesc2 = new FLabel.Builder()
.text("Up/down arrows change opponent order.")
@@ -131,12 +119,6 @@ public enum VSubmenuGauntletBuild implements IVSubmenu<CSubmenuGauntletBuild> {
private VSubmenuGauntletBuild() {
lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
// Radio button grouping
final ButtonGroup grpRadios = new ButtonGroup();
grpRadios.add(radUserDecks);
grpRadios.add(radQuestDecks);
grpRadios.add(radColorDecks);
grpRadios.add(radThemeDecks);
// File handling panel
final FLabel lblFilename = new FLabel.Builder()
@@ -148,13 +130,6 @@ public enum VSubmenuGauntletBuild implements IVSubmenu<CSubmenuGauntletBuild> {
pnlFileHandling.add(btnNew, "h 30px!, w 30px!, gap 0 5px 0 0");
pnlFileHandling.add(btnOpen, "h 30px!, w 30px!, gap 0 5px 0 0");
// Radios panel
pnlRadios.setOpaque(false);
pnlRadios.add(radUserDecks, "h 30px!, gap 0 0 0 5px");
pnlRadios.add(radQuestDecks, "h 30px!, gap 0 0 0 5px");
pnlRadios.add(radColorDecks, "h 30px!, gap 0 0 0 5px");
pnlRadios.add(radThemeDecks, "h 30px!, gap 0 0 0 5px");
// Directions panel
final JPanel pnlSpacer = new JPanel();
pnlSpacer.setOpaque(false);
@@ -211,15 +186,18 @@ public enum VSubmenuGauntletBuild implements IVSubmenu<CSubmenuGauntletBuild> {
*/
@Override
public void populate() {
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().removeAll();
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().setLayout(new MigLayout("insets 0, gap 0, wrap 3"));
lstLeft.populate();
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(lblTitle, "w 98%!, h 30px!, gap 1% 0 15px 15px, span 3");
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(pnlFileHandling, "w 98%!, gap 1% 0 1% 5px, span 3");
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(pnlRadios, "w 48% - 20px!, gap 1% 0 0 15px");
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(lstLeft, "w 48% - 20px!, gap 1% 0 0 25px, spany 2, growy");
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(pnlStrut, "w 40px!, gap 1% 1% 0 15px");
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(pnlDirections, "w 48% - 20px!, gap 0 0 0 15px");
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(scrLeft, "w 48% - 20px!, gap 1% 0 0 25px, pushy, growy");
// VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(lstLeft, "w 48% - 20px!, gap 1% 0 0 25px, pushy, growy");
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(pnlButtons, "w 40px!, gap 1% 1% 0 25px, pushy, growy");
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(scrRight, "w 48% - 20px!, gap 0 0 0 25px, pushy, growy");
@@ -228,7 +206,7 @@ public enum VSubmenuGauntletBuild implements IVSubmenu<CSubmenuGauntletBuild> {
}
/** @return {@link javax.swing.JList} */
public JList getLstLeft() {
public FDeckChooser getLstLeft() {
return this.lstLeft;
}
@@ -237,26 +215,6 @@ public enum VSubmenuGauntletBuild implements IVSubmenu<CSubmenuGauntletBuild> {
return this.lstRight;
}
/** @return {@link javax.swing.JRadioButton} */
public JRadioButton getRadUserDecks() {
return this.radUserDecks;
}
/** @return {@link javax.swing.JRadioButton} */
public JRadioButton getRadQuestDecks() {
return this.radQuestDecks;
}
/** @return {@link javax.swing.JRadioButton} */
public JRadioButton getRadColorDecks() {
return this.radColorDecks;
}
/** @return {@link javax.swing.JRadioButton} */
public JRadioButton getRadThemeDecks() {
return this.radThemeDecks;
}
/** @return {@link forge.gui.toolbox.FLabel} */
public FLabel getBtnUp() {
return btnUp;

View File

@@ -2,17 +2,15 @@ package forge.gui.home.gauntlet;
import java.awt.Font;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import net.miginfocom.swing.MigLayout;
import forge.game.player.PlayerType;
import forge.gui.framework.DragCell;
import forge.gui.framework.DragTab;
import forge.gui.framework.EDocID;
@@ -20,9 +18,8 @@ import forge.gui.home.EMenuGroup;
import forge.gui.home.IVSubmenu;
import forge.gui.home.StartButton;
import forge.gui.home.VHomeUI;
import forge.gui.toolbox.FDeckChooser;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FList;
import forge.gui.toolbox.FRadioButton;
import forge.gui.toolbox.FScrollPane;
import forge.gui.toolbox.FSkin;
@@ -54,18 +51,11 @@ public enum VSubmenuGauntletContests implements IVSubmenu<CSubmenuGauntletContes
private final JPanel pnlDecks = new JPanel();
private final ContestGauntletLister gauntletList = new ContestGauntletLister();
private final JList lstDecks = new FList();
private final FDeckChooser lstDecks = new FDeckChooser("Deck", PlayerType.HUMAN);
private final JScrollPane scrLeft = new FScrollPane(gauntletList,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
private final JScrollPane scrRight = new FScrollPane(lstDecks,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
private final JRadioButton radUserDecks = new FRadioButton("Custom user decks");
private final JRadioButton radQuestDecks = new FRadioButton("Quest Decks");
private final JRadioButton radColorDecks = new FRadioButton("Fully random color decks");
private final JRadioButton radThemeDecks = new FRadioButton("Semi-random theme decks");
private final JLabel lblDeck = new FLabel.Builder().fontSize(16)
.fontStyle(Font.BOLD).text("DECK").fontAlign(SwingConstants.CENTER).build();
@@ -78,14 +68,7 @@ public enum VSubmenuGauntletContests implements IVSubmenu<CSubmenuGauntletContes
private VSubmenuGauntletContests() {
lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
// Radio button grouping
final ButtonGroup grpRight = new ButtonGroup();
grpRight.add(radUserDecks);
grpRight.add(radQuestDecks);
grpRight.add(radColorDecks);
grpRight.add(radThemeDecks);
scrLeft.setBorder(null);
pnlLoad.setLayout(new MigLayout("insets 0, gap 0, wrap"));
pnlLoad.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
pnlLoad.add(lblLoad, "h 30px!, w 94%!, gap 1% 0 0 5px, ax center");
@@ -97,12 +80,8 @@ public enum VSubmenuGauntletContests implements IVSubmenu<CSubmenuGauntletContes
pnlDecks.setLayout(new MigLayout("insets 0, gap 0, wrap"));
pnlDecks.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
pnlDecks.add(lblDeck, "h 30px!, w 94%!, gap 1% 0 0 5px, ax center");
pnlDecks.add(radUserDecks, "w 96%!, h 30px!, gap 2% 0 0 5px");
pnlDecks.add(radQuestDecks, "w 96%!, h 30px!, gap 2% 0 0 5px");
pnlDecks.add(radColorDecks, "w 96%!, h 30px!, gap 2% 0 0 5px");
pnlDecks.add(radThemeDecks, "w 96%!, h 30px!, gap 2% 0 0 5px");
pnlDecks.add(btnRandom, "h 30px!, w 200px!, gap 25% 0 0 10px");
pnlDecks.add(scrRight, "w 94%!, pushy, growy, gap 3% 0 0 10px");
pnlDecks.add(lstDecks, "w 94%!, pushy, growy, gap 3% 0 0 10px");
}
/* (non-Javadoc)
@@ -164,30 +143,10 @@ public enum VSubmenuGauntletContests implements IVSubmenu<CSubmenuGauntletContes
}
/** @return {@link javax.swing.JList} */
public JList getLstDecks() {
public FDeckChooser getLstDecks() {
return this.lstDecks;
}
/** @return {@link javax.swing.JRadioButton} */
public JRadioButton getRadUserDecks() {
return this.radUserDecks;
}
/** @return {@link javax.swing.JRadioButton} */
public JRadioButton getRadQuestDecks() {
return this.radQuestDecks;
}
/** @return {@link javax.swing.JRadioButton} */
public JRadioButton getRadColorDecks() {
return this.radColorDecks;
}
/** @return {@link javax.swing.JRadioButton} */
public JRadioButton getRadThemeDecks() {
return this.radThemeDecks;
}
//========== Overridden from IVDoc
/* (non-Javadoc)

View File

@@ -7,6 +7,7 @@ import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JRadioButton;
@@ -126,45 +127,54 @@ public enum CSubmenuChallenges implements ICDoc {
final VSubmenuChallenges view = VSubmenuChallenges.SINGLETON_INSTANCE;
final QuestController qCtrl = Singletons.getModel().getQuest();
if (qCtrl.getAchievements() != null) {
view.getLblTitle().setText("Challenges: " + qCtrl.getRank());
if (qCtrl.getAchievements() == null) return;
view.getLblTitle().setText("Challenges: " + qCtrl.getRank());
view.getPnlChallenges().removeAll();
final List<QuestEventChallenge> challenges = qCtrl.getChallengesManager().generateChallenges();
JXButtonPanel grpPanel = new JXButtonPanel();
for (int i = 0; i < challenges.size(); i++) {
final PnlEvent temp = new PnlEvent(challenges.get(i));
final JRadioButton rad = temp.getRad();
if (i == 0) {
rad.setSelected(true);
SwingUtilities.invokeLater(new Runnable() {
@Override public void run() { rad.requestFocusInWindow(); }
});
}
rad.addKeyListener(_startOnEnter);
rad.addMouseListener(_startOnDblClick);
grpPanel.add(temp, rad, "w 100%!, h 135px!, gap 2% 0 15px 15px");
}
view.getPnlChallenges().add(grpPanel, "w 96%!");
if (challenges.size() == 0) {
final FLabel lbl = new FLabel.Builder()
.text(VSubmenuChallenges.SINGLETON_INSTANCE.getLblNextChallengeInWins().getText())
.fontAlign(SwingConstants.CENTER).build();
lbl.setForeground(Color.red);
lbl.setBackground(Color.white);
lbl.setBorder(new EmptyBorder(10, 10, 10, 10));
lbl.setOpaque(true);
view.getPnlChallenges().add(lbl, "w 50%!, h 30px!, gap 25% 0 50px 0");
SwingUtilities.invokeLater(new Runnable() {
@Override public void run() { view.getBtnTravel().requestFocusInWindow(); }
});
}
Singletons.getView().getFrame().validate();
view.getPnlChallenges().removeAll();
qCtrl.regenerateChallenges();
final List<String> ids = qCtrl.getAchievements().getCurrentChallenges();
final List<QuestEventChallenge> challenges = new ArrayList<QuestEventChallenge>();
for(final QuestEventChallenge qc : qCtrl.getChallenges()) {
if(ids.contains(qc.getId()))
challenges.add(qc);
}
JXButtonPanel grpPanel = new JXButtonPanel();
boolean haveAnyChallenges = true;
for (QuestEventChallenge qc : challenges) {
final PnlEvent temp = new PnlEvent(qc);
final JRadioButton rad = temp.getRad();
if (haveAnyChallenges) {
rad.setSelected(true);
SwingUtilities.invokeLater(new Runnable() {
@Override public void run() { rad.requestFocusInWindow(); }
});
haveAnyChallenges = false;
}
rad.addKeyListener(_startOnEnter);
rad.addMouseListener(_startOnDblClick);
grpPanel.add(temp, rad, "w 100%!, h 135px!, gap 2% 0 15px 15px");
}
view.getPnlChallenges().add(grpPanel, "w 96%!");
if (!haveAnyChallenges) {
final FLabel lbl = new FLabel.Builder()
.text(VSubmenuChallenges.SINGLETON_INSTANCE.getLblNextChallengeInWins().getText())
.fontAlign(SwingConstants.CENTER).build();
lbl.setForeground(Color.red);
lbl.setBackground(Color.white);
lbl.setBorder(new EmptyBorder(10, 10, 10, 10));
lbl.setOpaque(true);
view.getPnlChallenges().add(lbl, "w 50%!, h 30px!, gap 25% 0 50px 0");
SwingUtilities.invokeLater(new Runnable() {
@Override public void run() { view.getBtnTravel().requestFocusInWindow(); }
});
}
Singletons.getView().getFrame().validate();
}
/* (non-Javadoc)

View File

@@ -56,7 +56,7 @@ class PnlEvent extends JPanel {
hSrc = img.getHeight(null);
// Title and description
this.rad = new FRadioButton(event.getTitle() + " (" + event.getDifficulty() + ")");
this.rad = new FRadioButton(event.getTitle() + " (" + event.getDifficulty().getTitle() + ")");
this.rad.setFont(FSkin.getBoldFont(16));
final FTextArea tarDesc = new FTextArea();

View File

@@ -60,7 +60,7 @@ public class SSubmenuQuestUtil {
final int challengesPlayed = qData.getAchievements().getChallengesPlayed();
final int wins = qData.getAchievements().getWin();
final int turnsToUnlock = Singletons.getModel().getQuest().getChallengesManager().getTurnsToUnlockChallenge();
final int turnsToUnlock = Singletons.getModel().getQuest().getTurnsToUnlockChallenge();
final int delta;
// First challenge unlocks after minimum wins reached.
@@ -341,7 +341,6 @@ public class SSubmenuQuestUtil {
// (OTOH, you can 'swap' opponents even more easily by simply selecting a different quest data file and
// then re-selecting your current quest data file.)
qCtrl.getDuelsManager().randomizeOpponents();
qCtrl.getChallengesManager().randomizeOpponents();
qCtrl.getCards().clearShopList();
qCtrl.save();
}
@@ -379,8 +378,6 @@ public class SSubmenuQuestUtil {
final SwingWorker<Object, Void> worker = new SwingWorker<Object, Void>() {
@Override
public Object doInBackground() {
qData.getChallengesManager().randomizeOpponents();
qData.getDuelsManager().randomizeOpponents();
qData.setCurrentEvent(event);
qData.save();
@@ -394,8 +391,6 @@ public class SSubmenuQuestUtil {
}
};
worker.execute();
PlayerStartConditions humanStart = new PlayerStartConditions(SSubmenuQuestUtil.getCurrentDeck());
PlayerStartConditions aiStart = new PlayerStartConditions(event.getEventDeck());
int extraLifeHuman = 0;
int lifeAI = 20;
@@ -406,10 +401,13 @@ public class SSubmenuQuestUtil {
extraLifeHuman = 3;
}
}
humanStart.setStartingLife(qData.getAssets().getLife(qData.getMode()) + extraLifeHuman);
aiStart.setStartingLife(lifeAI);
PlayerStartConditions humanStart = new PlayerStartConditions(SSubmenuQuestUtil.getCurrentDeck());
humanStart.setStartingLife(qData.getAssets().getLife(qData.getMode()) + extraLifeHuman);
humanStart.setCardsOnBattlefield(QuestUtil.getHumanStartingCards(qData, event));
PlayerStartConditions aiStart = new PlayerStartConditions(event.getEventDeck());
aiStart.setStartingLife(lifeAI);
aiStart.setCardsOnBattlefield(QuestUtil.getComputerStartingCards(event));
MatchStartHelper msh = new MatchStartHelper();

View File

@@ -40,7 +40,6 @@ import forge.item.PreconDeck;
import forge.quest.QuestController;
import forge.quest.QuestWorld;
import forge.quest.StartingPoolType;
import forge.util.storage.IStorage;
import forge.util.storage.IStorageView;
/**
@@ -118,6 +117,7 @@ public enum VSubmenuQuestData implements IVSubmenu<CSubmenuQuestData> {
/* Listeners */
private final ActionListener alStartingPool = new ActionListener() {
@SuppressWarnings("incomplete-switch")
@Override
public void actionPerformed(ActionEvent e) {
StartingPoolType newVal = getStartingPoolType();

View File

@@ -9,10 +9,10 @@ import forge.Command;
import forge.FThreads;
import forge.Singletons;
import forge.control.Lobby;
import forge.deck.Deck;
import forge.game.GameType;
import forge.game.MatchController;
import forge.game.MatchStartHelper;
import forge.game.PlayerStartConditions;
import forge.gui.SOverlayUtils;
import forge.gui.framework.ICDoc;
import forge.properties.ForgePreferences;
@@ -96,15 +96,15 @@ public enum CSubmenuConstructed implements ICDoc {
* @param gameType
*/
private void startGame(final GameType gameType) {
Deck humanDeck = VSubmenuConstructed.SINGLETON_INSTANCE.getDcHuman().getDeck();
String humanDeckErrorMessage = gameType.getDecksFormat().getDeckConformanceProblem(humanDeck);
PlayerStartConditions humanPsc = VSubmenuConstructed.SINGLETON_INSTANCE.getDcHuman().getDeck();
String humanDeckErrorMessage = gameType.getDecksFormat().getDeckConformanceProblem(humanPsc.getOriginalDeck());
if (null != humanDeckErrorMessage) {
JOptionPane.showMessageDialog(null, "Your deck " + humanDeckErrorMessage, "Invalid deck", JOptionPane.ERROR_MESSAGE);
return;
}
Deck aiDeck = VSubmenuConstructed.SINGLETON_INSTANCE.getDcAi().getDeck();
String aiDeckErrorMessage = gameType.getDecksFormat().getDeckConformanceProblem(aiDeck);
PlayerStartConditions aiDeck = VSubmenuConstructed.SINGLETON_INSTANCE.getDcAi().getDeck();
String aiDeckErrorMessage = gameType.getDecksFormat().getDeckConformanceProblem(aiDeck.getOriginalDeck());
if (null != aiDeckErrorMessage) {
JOptionPane.showMessageDialog(null, "AI deck " + aiDeckErrorMessage, "Invalid deck", JOptionPane.ERROR_MESSAGE);
return;
@@ -115,7 +115,7 @@ public enum CSubmenuConstructed implements ICDoc {
final MatchStartHelper starter = new MatchStartHelper();
Lobby lobby = Singletons.getControl().getLobby();
starter.addPlayer(lobby.getGuiPlayer(), humanDeck);
starter.addPlayer(lobby.getGuiPlayer(), humanPsc);
starter.addPlayer(lobby.getAiPlayer(), aiDeck);
final MatchController mc = new MatchController(gameType, starter.getPlayerMap());

View File

@@ -20,6 +20,7 @@ import forge.deck.DeckgenUtil;
import forge.game.GameType;
import forge.game.MatchController;
import forge.game.MatchStartHelper;
import forge.game.PlayerStartConditions;
import forge.game.player.LobbyPlayer;
import forge.gui.GuiDialog;
import forge.gui.SOverlayUtils;
@@ -162,14 +163,14 @@ public enum CSubmenuArchenemy implements ICDoc {
List<Deck> playerDecks = new ArrayList<Deck>();
for (int i = 0; i < view.getNumPlayers(); i++) {
Deck d = view.getDeckChoosers().get(i).getDeck();
PlayerStartConditions d = view.getDeckChoosers().get(i).getDeck();
if (d == null) {
//ERROR!
GuiDialog.message("No deck selected for player " + (i + 1));
return;
}
playerDecks.add(d);
playerDecks.add(d.getOriginalDeck());
}
List<CardPrinted> schemes = null;

View File

@@ -20,6 +20,7 @@ import forge.deck.DeckgenUtil;
import forge.game.GameType;
import forge.game.MatchController;
import forge.game.MatchStartHelper;
import forge.game.PlayerStartConditions;
import forge.game.player.LobbyPlayer;
import forge.gui.GuiDialog;
import forge.gui.SOverlayUtils;
@@ -152,14 +153,14 @@ public enum CSubmenuPlanechase implements ICDoc {
MatchStartHelper helper = new MatchStartHelper();
List<Deck> playerDecks = new ArrayList<Deck>();
for (int i = 0; i < view.getNumPlayers(); i++) {
Deck d = view.getDeckChoosers().get(i).getDeck();
PlayerStartConditions d = view.getDeckChoosers().get(i).getDeck();
if (d == null) {
//ERROR!
GuiDialog.message("No deck selected for player " + (i + 1));
return;
}
playerDecks.add(d);
playerDecks.add(d.getOriginalDeck());
List<CardPrinted> planes = null;

View File

@@ -18,6 +18,7 @@ import forge.deck.DeckSection;
import forge.game.GameType;
import forge.game.MatchController;
import forge.game.MatchStartHelper;
import forge.game.PlayerStartConditions;
import forge.game.player.LobbyPlayer;
import forge.gui.GuiDialog;
import forge.gui.SOverlayUtils;
@@ -120,14 +121,14 @@ public enum CSubmenuVanguard implements ICDoc {
List<Deck> playerDecks = new ArrayList<Deck>();
for (int i = 0; i < view.getNumPlayers(); i++) {
Deck d = view.getDeckChoosers().get(i).getDeck();
PlayerStartConditions d = view.getDeckChoosers().get(i).getDeck();
if (d == null) {
//ERROR!
GuiDialog.message("No deck selected for player " + (i + 1));
return;
}
playerDecks.add(d);
playerDecks.add(d.getOriginalDeck());
}
List<CardPrinted> playerAvatars = new ArrayList<CardPrinted>();

View File

@@ -30,6 +30,8 @@ import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import org.apache.commons.lang.StringUtils;
import forge.Card;
import forge.Singletons;
import forge.card.BoosterTemplate;
@@ -63,6 +65,7 @@ import forge.quest.IQuestRewardCard;
import forge.quest.QuestController;
import forge.quest.QuestEvent;
import forge.quest.QuestEventChallenge;
import forge.quest.QuestEventDifficulty;
import forge.quest.bazaar.QuestItemType;
import forge.quest.data.QuestPreferences;
import forge.quest.data.QuestPreferences.DifficultyPrefs;
@@ -185,7 +188,7 @@ public class QuestWinLose extends ControlWinLose {
else {
awardSpecialReward("Special bonus reward:"); // If any
// Random rare for winning against a very hard deck
if (qEvent.getDifficulty().toLowerCase().equals("very hard")) {
if (qEvent.getDifficulty() == QuestEventDifficulty.EXPERT) {
this.awardRandomRare("You've won a random rare for winning against a very hard deck.");
}
}
@@ -279,18 +282,9 @@ public class QuestWinLose extends ControlWinLose {
}
if (qEvent instanceof QuestEventChallenge) {
final int id = ((QuestEventChallenge) qEvent).getId();
final int size = qData.getAchievements().getCurrentChallenges().size();
for (int i = 0; i < size; i++) {
if (qData.getAchievements().getCurrentChallenges().get(i) == id) {
qData.getAchievements().getCurrentChallenges().remove(i);
break;
}
}
if (!((QuestEventChallenge) qEvent).isRepeatable()) {
qData.getAchievements().addLockedChallenge(((QuestEventChallenge) qEvent).getId());
}
final String id = ((QuestEventChallenge) qEvent).getId();
qData.getAchievements().getCurrentChallenges().remove(id);
qData.getAchievements().addLockedChallenge(id);
// Increment challenge counter to limit challenges available
qData.getAchievements().addChallengesPlayed();
@@ -331,23 +325,20 @@ public class QuestWinLose extends ControlWinLose {
final int base = Singletons.getModel().getQuestPreferences().getPrefInt(QPref.REWARDS_BASE);
double multiplier = 1;
String diff = qEvent.getDifficulty();
diff = diff.substring(0, 1).toUpperCase() + diff.substring(1);
if (diff.equalsIgnoreCase("medium")) {
multiplier = 1.5;
} else if (diff.equalsIgnoreCase("hard")) {
multiplier = 2;
} else if (diff.equalsIgnoreCase("very hard")) {
multiplier = 2.5;
} else if (diff.equalsIgnoreCase("expert")) {
multiplier = 3;
switch(qEvent.getDifficulty()) {
case EASY: multiplier = 1; break;
case MEDIUM: multiplier = 1.5; break;
case HARD: multiplier = 2; break;
case EXPERT: multiplier = 3; break;
}
credBase += (int) ((base * multiplier) + (Double.parseDouble(Singletons.getModel().getQuestPreferences()
.getPref(QPref.REWARDS_WINS_MULTIPLIER)) * qData.getAchievements().getWin()));
sb.append(diff + " opponent: " + credBase + " credits.<br>");
sb.append(StringUtils.capitalize(qEvent.getDifficulty().getTitle()));
sb.append(" opponent: ").append(credBase).append(" credits.<br>");
// Gameplay bonuses (for each game win)
boolean hasNeverLost = true;

View File

@@ -25,9 +25,12 @@ import forge.Singletons;
import forge.deck.Deck;
import forge.deck.DeckgenUtil;
import forge.deck.generate.GenerateThemeDeck;
import forge.game.PlayerStartConditions;
import forge.game.player.PlayerType;
import forge.quest.QuestController;
import forge.quest.QuestEvent;
import forge.quest.QuestEventChallenge;
import forge.quest.QuestUtil;
import forge.util.storage.IStorage;
@SuppressWarnings("serial")
@@ -176,11 +179,11 @@ public class FDeckChooser extends JPanel {
QuestController quest = Singletons.getModel().getQuest();
for (QuestEvent e : quest.getDuelsManager().getAllDuels()) {
eventNames.add(e.getEventDeck().getName());
eventNames.add(e.getName());
}
for (QuestEvent e : quest.getChallengesManager().getAllChallenges()) {
eventNames.add(e.getEventDeck().getName());
for (QuestEvent e : quest.getChallenges()) {
eventNames.add(e.getTitle());
}
lst.setListData(eventNames.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
@@ -196,24 +199,35 @@ public class FDeckChooser extends JPanel {
}
/** Generates deck from current list selection(s). */
public Deck getDeck() {
public PlayerStartConditions getDeck() {
JList lst0 = getLstDecks();
final String[] selection = Arrays.copyOf(lst0.getSelectedValues(), lst0.getSelectedValues().length, String[].class);
if (selection.length == 0) { return null; }
if (lst0.getName().equals(DeckgenUtil.DeckTypes.COLORS.toString()) && DeckgenUtil.colorCheck(selection)) {
return DeckgenUtil.buildColorDeck(selection, getPlayerType());
} else if (lst0.getName().equals(DeckgenUtil.DeckTypes.THEMES.toString())) {
return DeckgenUtil.buildThemeDeck(selection);
} else if (lst0.getName().equals(DeckgenUtil.DeckTypes.QUESTEVENTS.toString())) {
return DeckgenUtil.buildQuestDeck(selection);
} else if (lst0.getName().equals(DeckgenUtil.DeckTypes.CUSTOM.toString())) {
return DeckgenUtil.getConstructedDeck(selection);
// Special branch for quest events
if (lst0.getName().equals(DeckgenUtil.DeckTypes.QUESTEVENTS.toString())) {
QuestEvent event = DeckgenUtil.getQuestEvent(selection[0]);
PlayerStartConditions result = new PlayerStartConditions(event.getEventDeck());
if( event instanceof QuestEventChallenge ) {
result.setStartingLife(((QuestEventChallenge) event).getAiLife());
}
result.setCardsOnBattlefield(QuestUtil.getComputerStartingCards(event));
return result;
}
// Failure, for some reason
return null;
Deck deck = null;
if (lst0.getName().equals(DeckgenUtil.DeckTypes.COLORS.toString()) && DeckgenUtil.colorCheck(selection)) {
deck = DeckgenUtil.buildColorDeck(selection, getPlayerType());
} else if (lst0.getName().equals(DeckgenUtil.DeckTypes.THEMES.toString())) {
deck = DeckgenUtil.buildThemeDeck(selection);
} else if (lst0.getName().equals(DeckgenUtil.DeckTypes.CUSTOM.toString())) {
deck = DeckgenUtil.getConstructedDeck(selection);
}
return new PlayerStartConditions(deck);
}
private PlayerType getPlayerType() {

View File

@@ -37,10 +37,6 @@ public class PreconDeck implements InventoryItemFromSet {
private final Deck deck;
private final String imageFilename;
public final String getImageFilename() {
return imageFilename;
}
private final String set;
private final String description;
@@ -107,6 +103,10 @@ public class PreconDeck implements InventoryItemFromSet {
return this.recommendedDeals;
}
public final String getImageFilename() {
return imageFilename;
}
/*
* (non-Javadoc)
*

View File

@@ -18,6 +18,9 @@
package forge.quest;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
@@ -40,6 +43,7 @@ import forge.quest.data.QuestAssets;
import forge.quest.data.QuestData;
import forge.quest.data.QuestPreferences.DifficultyPrefs;
import forge.quest.io.PreconReader;
import forge.quest.io.QuestChallengeReader;
import forge.util.storage.IStorage;
import forge.util.storage.IStorageView;
import forge.util.storage.StorageView;
@@ -65,8 +69,8 @@ public class QuestController {
/** The decks. */
private transient IStorage<Deck> decks;
private QuestEventManager duelManager = null;
private QuestEventManager challengesManager = null;
private QuestEventDuelManager duelManager = null;
private IStorageView<QuestEventChallenge> allChallenges = null;
private QuestBazaarManager bazaar = null;
@@ -193,7 +197,6 @@ public class QuestController {
this.resetDuelsManager();
this.resetChallengesManager();
this.getChallengesManager().randomizeOpponents();
this.getDuelsManager().randomizeOpponents();
}
@@ -352,7 +355,7 @@ public class QuestController {
*
* @return the event manager
*/
public QuestEventManager getDuelsManager() {
public QuestEventDuelManager getDuelsManager() {
if (this.duelManager == null) {
resetDuelsManager();
}
@@ -364,11 +367,11 @@ public class QuestController {
* TODO: Write javadoc for this method.
* @return QuestEventManager
*/
public QuestEventManager getChallengesManager() {
if (this.challengesManager == null) {
public IStorageView<QuestEventChallenge> getChallenges() {
if (this.allChallenges == null) {
resetChallengesManager();
}
return this.challengesManager;
return this.allChallenges;
}
/**
@@ -376,17 +379,9 @@ public class QuestController {
* Reset the duels manager.
*/
public void resetDuelsManager() {
if (this.model == null || this.model.getWorldId() == null) {
this.duelManager = new QuestEventManager(new File(NewConstants.DEFAULT_DUELS_DIR));
} else {
QuestWorld world = Singletons.getModel().getWorlds().get(this.model.getWorldId());
if (world == null || world.getDuelsDir() == null) {
this.duelManager = new QuestEventManager(new File(NewConstants.DEFAULT_DUELS_DIR));
} else {
this.duelManager = new QuestEventManager(new File("res/quest/world/" + world.getDuelsDir()));
}
}
QuestWorld world = getWorld();
String path = world == null || world.getDuelsDir() == null ? NewConstants.DEFAULT_DUELS_DIR : "res/quest/world/" + world.getDuelsDir();
this.duelManager = new QuestEventDuelManager(new File(path));
}
/**
@@ -394,18 +389,9 @@ public class QuestController {
* Reset the challenges manager.
*/
public void resetChallengesManager() {
if (this.model == null || this.model.getWorldId() == null) {
this.challengesManager = new QuestEventManager(new File(NewConstants.DEFAULT_CHALLENGES_DIR));
}
else {
QuestWorld world = Singletons.getModel().getWorlds().get(this.model.getWorldId());
if (world == null || world.getChallengesDir() == null) {
this.challengesManager = new QuestEventManager(new File(NewConstants.DEFAULT_CHALLENGES_DIR));
} else {
this.challengesManager = new QuestEventManager(new File("res/quest/world/" + world.getChallengesDir()));
}
}
QuestWorld world = getWorld();
String path = world == null || world.getChallengesDir() == null ? NewConstants.DEFAULT_CHALLENGES_DIR : "res/quest/world/" + world.getChallengesDir();
this.allChallenges = new StorageView<QuestEventChallenge>(new QuestChallengeReader(new File(path)));
}
/**
@@ -450,5 +436,51 @@ public class QuestController {
}
}
}
public int getTurnsToUnlockChallenge() {
if (Singletons.getModel().getQuest().getAssets().hasItem(QuestItemType.ZEPPELIN)) {
return 8;
}
// User may have MAP and ZEPPELIN, so MAP must be tested second.
else if (Singletons.getModel().getQuest().getAssets().hasItem(QuestItemType.MAP)) {
return 9;
}
return 10;
}
public final void regenerateChallenges() {
final QuestAchievements achievements = model.getAchievements();
final List<String> unlockedChallengeIds = new ArrayList<String>();
final List<String> availableChallengeIds = achievements.getCurrentChallenges();
int maxChallenges = achievements.getWin() / getTurnsToUnlockChallenge() - achievements.getChallengesPlayed();
if (maxChallenges > 5) {
maxChallenges = 5;
}
// Generate IDs as needed.
if (achievements.getCurrentChallenges().size() < maxChallenges) {
for (final QuestEventChallenge qc : allChallenges) {
if( qc.getWinsReqd() > achievements.getWin()) continue;
if( !qc.isRepeatable() && achievements.getLockedChallenges().contains(qc.getId())) continue;
if (!availableChallengeIds.contains(qc.getId())) {
unlockedChallengeIds.add(qc.getId());
}
}
Collections.shuffle(unlockedChallengeIds);
maxChallenges = Math.min(maxChallenges, unlockedChallengeIds.size());
for (int i = availableChallengeIds.size(); i < maxChallenges; i++) {
availableChallengeIds.add(unlockedChallengeIds.get(i));
}
}
achievements.setCurrentChallenges(availableChallengeIds);
save();
}
}

View File

@@ -22,6 +22,9 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import forge.deck.Deck;
import forge.util.storage.IStorage;
@@ -125,4 +128,12 @@ public class QuestDeckMap implements IStorage<Deck> {
return map.size();
}
/* (non-Javadoc)
* @see forge.util.storage.IStorageView#find(com.google.common.base.Predicate)
*/
@Override
public Deck find(Predicate<Deck> condition) {
return Iterables.tryFind(map.values(), condition).orNull();
}
}

View File

@@ -21,6 +21,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.google.common.base.Function;
import forge.deck.Deck;
import forge.game.player.IHasIcon;
import forge.item.InventoryItem;
@@ -38,12 +40,21 @@ public abstract class QuestEvent implements IHasIcon {
private Deck eventDeck = null;
private String title = "Mystery Event";
private String description = "";
private String difficulty = "Medium";
private QuestEventDifficulty difficulty = QuestEventDifficulty.MEDIUM;
private String imageKey = "";
private String name = "Noname";
private String cardReward = null;
private List<InventoryItem> cardRewardList = null;
public static final Function<QuestEvent, String> FN_GET_NAME = new Function<QuestEvent, String>() {
@Override public final String apply(QuestEvent qe) { return qe.name; }
};
public static final Function<QuestEvent, String> FN_GET_TITLE = new Function<QuestEvent, String>() {
@Override public final String apply(QuestEvent qe) { return qe.title; }
};
public final String getTitle() {
return this.title;
}
@@ -55,7 +66,7 @@ public abstract class QuestEvent implements IHasIcon {
return null;
}
public final String getDifficulty() {
public final QuestEventDifficulty getDifficulty() {
return this.difficulty;
}
@@ -84,7 +95,7 @@ public abstract class QuestEvent implements IHasIcon {
this.title = title0;
}
public void setDifficulty(final String difficulty0) {
public void setDifficulty(final QuestEventDifficulty difficulty0) {
this.difficulty = difficulty0;
}

View File

@@ -32,7 +32,7 @@ import java.util.List;
public class QuestEventChallenge extends QuestEvent {
// ID (default -1, should be explicitly set at later time.)
/** The id. */
private int id = -1;
private String id = "-1";
// Opponent name if different from the challenge name
private String opponentName = null;
@@ -94,7 +94,7 @@ public class QuestEventChallenge extends QuestEvent {
*
* @return {@link java.lang.Integer}.
*/
public final int getId() {
public final String getId() {
return this.id;
}
@@ -161,7 +161,7 @@ public class QuestEventChallenge extends QuestEvent {
* @param id0
* the id to set
*/
public void setId(final int id0) {
public void setId(final String id0) {
this.id = id0;
}

View File

@@ -5,8 +5,26 @@ package forge.quest;
*
*/
public enum QuestEventDifficulty {
EASY,
MEDIUM,
HARD,
EXPERT
EASY("easy"),
MEDIUM("medium"),
HARD("hard"),
EXPERT("very hard");
String inFile;
private QuestEventDifficulty(String storedInFile) {
inFile = storedInFile;
}
public final String getTitle() {
return inFile;
}
public static QuestEventDifficulty fromString(String src) {
for(QuestEventDifficulty qd : QuestEventDifficulty.values()) {
if( src.equalsIgnoreCase(qd.inFile) || src.equalsIgnoreCase(qd.name()) )
return qd;
}
return null;
}
}

View File

@@ -0,0 +1,162 @@
/*
* 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.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import forge.Singletons;
import forge.quest.data.QuestPreferences;
import forge.quest.data.QuestPreferences.DifficultyPrefs;
import forge.quest.io.QuestDuelReader;
import forge.util.maps.CollectionSuppliers;
import forge.util.maps.EnumMapOfLists;
import forge.util.maps.MapOfLists;
import forge.util.storage.IStorageView;
import forge.util.storage.StorageView;
/**
* QuestEventManager.
*
* @author Forge
* @version $Id: QuestEventManager.java 20404 2013-03-17 05:34:13Z myk $
*/
public class QuestEventDuelManager {
private final MapOfLists<QuestEventDifficulty, QuestEventDuel> sortedDuels = new EnumMapOfLists<QuestEventDifficulty, QuestEventDuel>(QuestEventDifficulty.class, CollectionSuppliers.<QuestEventDuel>arrayLists());
private final IStorageView<QuestEventDuel> allDuels;
/** Instantiate all events and difficulty lists.
* @param dir &emsp; File object */
public QuestEventDuelManager(final File dir) {
allDuels = new StorageView<>(new QuestDuelReader(dir));
assembleDuelDifficultyLists();
} // End assembleAllEvents()
/** @return List<QuestEventDuel> */
public Iterable<QuestEventDuel> getAllDuels() {
return allDuels;
}
// define fallback orders if there aren't enough opponents defined for a particular difficultly level
private static List<QuestEventDifficulty> _easyOrder = Arrays.asList(QuestEventDifficulty.EASY, QuestEventDifficulty.MEDIUM, QuestEventDifficulty.HARD, QuestEventDifficulty.EXPERT);
private static List<QuestEventDifficulty> _mediumOrder = Arrays.asList(QuestEventDifficulty.MEDIUM, QuestEventDifficulty.HARD, QuestEventDifficulty.EASY, QuestEventDifficulty.EXPERT);
private static List<QuestEventDifficulty> _hardOrder = Arrays.asList(QuestEventDifficulty.HARD, QuestEventDifficulty.MEDIUM, QuestEventDifficulty.EASY, QuestEventDifficulty.EXPERT);
private static List<QuestEventDifficulty> _expertOrder = Arrays.asList(QuestEventDifficulty.EXPERT, QuestEventDifficulty.HARD, QuestEventDifficulty.MEDIUM, QuestEventDifficulty.EASY);
private void _addDuel(List<QuestEventDuel> outList, QuestEventDifficulty targetDifficulty, int toAdd) {
// if there's no way we can satisfy the request, return now
if (allDuels.size() <= toAdd) {
return;
}
final List<QuestEventDifficulty> difficultyOrder;
switch (targetDifficulty) {
case EASY: difficultyOrder = _easyOrder; break;
case MEDIUM: difficultyOrder = _mediumOrder; break;
case HARD: difficultyOrder = _hardOrder; break;
case EXPERT: difficultyOrder = _expertOrder; break;
default:
throw new RuntimeException("unhandled difficulty: " + targetDifficulty);
}
for (QuestEventDifficulty d : difficultyOrder) { // will add duels from preferred difficulty, will use others if the former has too few options.
for( QuestEventDuel duel : sortedDuels.get(d)) {
if(toAdd <= 0)
return;
if (!outList.contains(duel)) {
outList.add(duel);
toAdd--;
}
}
}
}
/** Generates an array of new duel opponents based on current win conditions.
*
* @return an array of {@link java.lang.String} objects.
*/
public final List<QuestEventDuel> generateDuels() {
final QuestPreferences qpref = Singletons.getModel().getQuestPreferences();
if (Singletons.getModel().getQuest().getAchievements() == null) {
return null;
}
final QuestController qCtrl = Singletons.getModel().getQuest();
final int cntWins = qCtrl.getAchievements().getWin();
final int index = qCtrl.getAchievements().getDifficulty();
final List<QuestEventDuel> duelOpponents = new ArrayList<QuestEventDuel>();
if (cntWins < qpref.getPrefInt(DifficultyPrefs.WINS_MEDIUMAI, index)) {
_addDuel(duelOpponents, QuestEventDifficulty.EASY, 3);
} else if (cntWins == qpref.getPrefInt(DifficultyPrefs.WINS_MEDIUMAI, index)) {
_addDuel(duelOpponents, QuestEventDifficulty.EASY, 1);
_addDuel(duelOpponents, QuestEventDifficulty.MEDIUM, 2);
} else if (cntWins < qpref.getPrefInt(DifficultyPrefs.WINS_HARDAI, index)) {
_addDuel(duelOpponents, QuestEventDifficulty.MEDIUM, 3);
} else if (cntWins == qpref.getPrefInt(DifficultyPrefs.WINS_HARDAI, index)) {
_addDuel(duelOpponents, QuestEventDifficulty.MEDIUM, 1);
_addDuel(duelOpponents, QuestEventDifficulty.HARD, 2);
} else if (cntWins < qpref.getPrefInt(DifficultyPrefs.WINS_EXPERTAI, index)) {
_addDuel(duelOpponents, QuestEventDifficulty.HARD, 3);
} else {
_addDuel(duelOpponents, QuestEventDifficulty.HARD, 2);
_addDuel(duelOpponents, QuestEventDifficulty.EXPERT, 1);
}
return duelOpponents;
}
/**
* <p>
* assembleDuelDifficultyLists.
* </p>
* Assemble duel deck difficulty lists
*/
private void assembleDuelDifficultyLists() {
sortedDuels.clear();
sortedDuels.put(QuestEventDifficulty.EASY, new ArrayList<QuestEventDuel>());
sortedDuels.put(QuestEventDifficulty.MEDIUM, new ArrayList<QuestEventDuel>());
sortedDuels.put(QuestEventDifficulty.HARD, new ArrayList<QuestEventDuel>());
sortedDuels.put(QuestEventDifficulty.EXPERT, new ArrayList<QuestEventDuel>());
for (final QuestEventDuel qd : allDuels) {
sortedDuels.add(qd.getDifficulty(), qd);
}
}
/** */
public void randomizeOpponents() {
final long seed = new Random().nextLong();
final Random r = new Random(seed);
for(QuestEventDifficulty qd : sortedDuels.keySet()) {
List<QuestEventDuel> list = (List<QuestEventDuel>) sortedDuels.get(qd);
Collections.shuffle(list, r);
}
}
}

View File

@@ -1,464 +0,0 @@
/*
* 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.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.apache.commons.lang3.StringUtils;
import forge.ImageCache;
import forge.Singletons;
import forge.deck.Deck;
import forge.deck.io.DeckSerializer;
import forge.quest.bazaar.QuestItemType;
import forge.quest.data.QuestAchievements;
import forge.quest.data.QuestPreferences;
import forge.quest.data.QuestPreferences.DifficultyPrefs;
import forge.util.FileSection;
import forge.util.FileUtil;
/**
* QuestEventManager.
*
* @author Forge
* @version $Id$
*/
public class QuestEventManager {
private final Map<QuestEventDifficulty, List<QuestEventDuel>> sortedDuels = new EnumMap<QuestEventDifficulty, List<QuestEventDuel>>(QuestEventDifficulty.class);
private final List<QuestEventDuel> allDuels = new ArrayList<QuestEventDuel>();
private final List<QuestEventChallenge> allChallenges = new ArrayList<QuestEventChallenge>();
/** Instantiate all events and difficulty lists.
* @param dir &emsp; File object */
public QuestEventManager(final File dir) {
QuestEvent tempEvent;
final File[] allFiles = dir.listFiles(DeckSerializer.DCK_FILE_FILTER);
for (final File f : allFiles) {
final Map<String, List<String>> contents = FileSection.parseSections(FileUtil.readFile(f));
if (contents.containsKey("quest")) {
tempEvent = readChallenge(contents.get("quest"));
allChallenges.add((QuestEventChallenge) tempEvent);
}
else {
tempEvent = readDuel(contents.get("metadata"));
allDuels.add((QuestEventDuel) tempEvent);
}
// Assemble metadata (may not be necessary later) and deck object.
readMetadata(contents.get("metadata"), tempEvent);
tempEvent.setEventDeck(Deck.fromSections(contents));
} // End for(allFiles)
assembleDuelDifficultyLists();
} // End assembleAllEvents()
/**
* Retrieve single event, using its name.
*
* @param s0
* &emsp; {@link java.lang.String}
* @return {@link forge.quest.data.QuestEvent}
*/
public QuestEvent getEvent(final String s0) {
for (final QuestEvent q : allDuels) {
if (q.getName().equals(s0)) {
return q;
}
}
for (final QuestEventChallenge q : allChallenges) {
if (q.getName().equals(s0)) {
return q;
}
}
return null;
}
/** @return List<QuestEventDuel> */
public List<QuestEventDuel> getAllDuels() {
return allDuels;
}
/** @return List<QuestEventChallenge> */
public List<QuestEventChallenge> getAllChallenges() {
return allChallenges;
}
// define fallback orders if there aren't enough opponents defined for a particular difficultly level
private static List<QuestEventDifficulty> _easyOrder = Arrays.asList(QuestEventDifficulty.EASY, QuestEventDifficulty.MEDIUM, QuestEventDifficulty.HARD, QuestEventDifficulty.EXPERT);
private static List<QuestEventDifficulty> _mediumOrder = Arrays.asList(QuestEventDifficulty.MEDIUM, QuestEventDifficulty.HARD, QuestEventDifficulty.EASY, QuestEventDifficulty.EXPERT);
private static List<QuestEventDifficulty> _hardOrder = Arrays.asList(QuestEventDifficulty.HARD, QuestEventDifficulty.MEDIUM, QuestEventDifficulty.EASY, QuestEventDifficulty.EXPERT);
private static List<QuestEventDifficulty> _expertOrder = Arrays.asList(QuestEventDifficulty.EXPERT, QuestEventDifficulty.HARD, QuestEventDifficulty.MEDIUM, QuestEventDifficulty.EASY);
private void _addDuel(List<QuestEventDuel> outList, QuestEventDifficulty targetDifficulty, int targetIdx) {
// if there's no way we can satisfy the request, return now
if (allDuels.size() <= targetIdx) {
return;
}
final List<QuestEventDifficulty> difficultyOrder;
switch (targetDifficulty) {
case EASY: difficultyOrder = _easyOrder; break;
case MEDIUM: difficultyOrder = _mediumOrder; break;
case HARD: difficultyOrder = _hardOrder; break;
case EXPERT: difficultyOrder = _expertOrder; break;
default:
throw new RuntimeException("unhandled difficulty: " + targetDifficulty);
}
for (QuestEventDifficulty d : difficultyOrder) {
List<QuestEventDuel> opponents = sortedDuels.get(d);
if (opponents.size() > targetIdx) {
QuestEventDuel duel = opponents.get(targetIdx);
// if we wanted to get fancy here, we could search for a duel that hasn't been
// added yet. this is just intended to handle the simple (and common) case of
// not having enough opponents defined for a particular level, as often happens
// when new worlds are in development
if (!outList.contains(duel)) {
outList.add(duel);
return;
}
continue;
}
targetIdx -= opponents.size();
}
}
/** Generates an array of new duel opponents based on current win conditions.
*
* @return an array of {@link java.lang.String} objects.
*/
public final List<QuestEventDuel> generateDuels() {
final QuestPreferences qpref = Singletons.getModel().getQuestPreferences();
if (Singletons.getModel().getQuest().getAchievements() == null) {
return null;
}
final QuestController qCtrl = Singletons.getModel().getQuest();
final int cntWins = qCtrl.getAchievements().getWin();
final int index = qCtrl.getAchievements().getDifficulty();
final List<QuestEventDuel> duelOpponents = new ArrayList<QuestEventDuel>();
if (cntWins < qpref.getPrefInt(DifficultyPrefs.WINS_MEDIUMAI, index)) {
_addDuel(duelOpponents, QuestEventDifficulty.EASY, 0);
_addDuel(duelOpponents, QuestEventDifficulty.EASY, 1);
_addDuel(duelOpponents, QuestEventDifficulty.EASY, 2);
} else if (cntWins == qpref.getPrefInt(DifficultyPrefs.WINS_MEDIUMAI, index)) {
_addDuel(duelOpponents, QuestEventDifficulty.EASY, 0);
_addDuel(duelOpponents, QuestEventDifficulty.MEDIUM, 0);
_addDuel(duelOpponents, QuestEventDifficulty.MEDIUM, 1);
} else if (cntWins < qpref.getPrefInt(DifficultyPrefs.WINS_HARDAI, index)) {
_addDuel(duelOpponents, QuestEventDifficulty.MEDIUM, 0);
_addDuel(duelOpponents, QuestEventDifficulty.MEDIUM, 1);
_addDuel(duelOpponents, QuestEventDifficulty.MEDIUM, 2);
} else if (cntWins == qpref.getPrefInt(DifficultyPrefs.WINS_HARDAI, index)) {
_addDuel(duelOpponents, QuestEventDifficulty.MEDIUM, 0);
_addDuel(duelOpponents, QuestEventDifficulty.HARD, 0);
_addDuel(duelOpponents, QuestEventDifficulty.HARD, 1);
} else if (cntWins < qpref.getPrefInt(DifficultyPrefs.WINS_EXPERTAI, index)) {
_addDuel(duelOpponents, QuestEventDifficulty.HARD, 0);
_addDuel(duelOpponents, QuestEventDifficulty.HARD, 1);
_addDuel(duelOpponents, QuestEventDifficulty.HARD, 2);
} else {
_addDuel(duelOpponents, QuestEventDifficulty.HARD, 0);
_addDuel(duelOpponents, QuestEventDifficulty.HARD, 1);
_addDuel(duelOpponents, QuestEventDifficulty.EXPERT, 0);
}
return duelOpponents;
}
/** Generates an array of new challenge opponents based on current win conditions.
*
* @return a {@link java.util.List} object.
*/
public final List<QuestEventChallenge> generateChallenges() {
final QuestController qCtrl = Singletons.getModel().getQuest();
final QuestAchievements achievements = qCtrl.getAchievements();
final List<QuestEventChallenge> challengeOpponents = new ArrayList<QuestEventChallenge>();
final List<Integer> unlockedChallengeIds = new ArrayList<Integer>();
final List<Integer> availableChallengeIds = achievements.getCurrentChallenges();
int maxChallenges = ((achievements.getWin() / this.getTurnsToUnlockChallenge()) - achievements.getChallengesPlayed());
if (maxChallenges > 5) {
maxChallenges = 5;
}
// Generate IDs as needed.
if (achievements.getCurrentChallenges().size() < maxChallenges) {
for (final QuestEventChallenge qc : allChallenges) {
if ((qc.getWinsReqd() <= achievements.getWin())
&& !achievements.getLockedChallenges().contains(qc.getId())
&& !availableChallengeIds.contains(qc.getId())) {
unlockedChallengeIds.add(qc.getId());
}
}
Collections.shuffle(unlockedChallengeIds);
maxChallenges = Math.min(maxChallenges, unlockedChallengeIds.size());
for (int i = availableChallengeIds.size(); i < maxChallenges; i++) {
availableChallengeIds.add(unlockedChallengeIds.get(i));
}
achievements.setCurrentChallenges(availableChallengeIds);
qCtrl.save();
}
// Finally, pull challenge events from available IDs and return.
for (final int i : achievements.getCurrentChallenges()) {
challengeOpponents.add(getChallengeEventByNumber(i));
}
return challengeOpponents;
}
/**
* Returns the current number of turns required to unlock a new challenge.
* Varies depending on map or zeppelin purchase.
*
* @return int
*/
public int getTurnsToUnlockChallenge() {
if (Singletons.getModel().getQuest().getAssets().hasItem(QuestItemType.ZEPPELIN)) {
return 8;
}
// User may have MAP and ZEPPELIN, so MAP must be tested second.
else if (Singletons.getModel().getQuest().getAssets().hasItem(QuestItemType.MAP)) {
return 9;
}
return 10;
}
/**
* <p>
* assembleDuelUniqueData.
* </p>
* Handler for any unique data contained in duel files.
*
* @param contents
* @param qd
*/
private QuestEventDuel readDuel(final List<String> contents) {
final QuestEventDuel qd = new QuestEventDuel();
int eqpos;
String key, value;
for (final String s : contents) {
if (s.equals("")) {
continue;
}
eqpos = s.indexOf('=');
if (eqpos < 0) {
continue;
}
key = s.substring(0, eqpos);
value = s.substring(eqpos + 1);
if (key.equalsIgnoreCase("Name")) {
qd.setName(value);
}
}
return qd;
}
/**
* <p>
* assembleChallengeUniquedata.
* </p>
* Handler for any unique data contained in a challenge file.
*
* @param contents
* @param qc
*/
private QuestEventChallenge readChallenge(final List<String> contents) {
int eqpos;
String key, value;
final QuestEventChallenge qc = new QuestEventChallenge();
// Unique properties
for (final String s : contents) {
if (StringUtils.isBlank(s)) {
continue;
}
eqpos = s.indexOf('=');
key = s.substring(0, eqpos);
value = s.substring(eqpos + 1).trim();
if (key.equalsIgnoreCase("ID")) {
qc.setId(Integer.parseInt(value));
} else if (key.equalsIgnoreCase("OpponentName")) {
qc.setOpponent(value);
} else if (key.equalsIgnoreCase("Repeat")) {
qc.setRepeatable(Boolean.parseBoolean(value));
} else if (key.equalsIgnoreCase("AILife")) {
qc.setAiLife(Integer.parseInt(value));
} else if (key.equalsIgnoreCase("Wins")) {
qc.setWinsReqd(Integer.parseInt(value));
} else if (key.equalsIgnoreCase("Credit Reward")) {
qc.setCreditsReward(Integer.parseInt(value));
} else if (key.equalsIgnoreCase("Card Reward")) {
qc.setCardReward(value);
}
// Human extra card list assembled here.
else if (key.equalsIgnoreCase("HumanExtras") && !value.equals("")) {
final String[] names = value.split("\\|");
final List<String> templist = new ArrayList<String>();
for (final String n : names) {
templist.add(n);
}
qc.setHumanExtraCards(templist);
}
// AI extra card list assembled here.
else if (key.equalsIgnoreCase("AIExtras") && !value.equals("")) {
final String[] names = value.split("\\|");
final List<String> templist = new ArrayList<String>();
for (final String n : names) {
templist.add(n);
}
qc.setAiExtraCards(templist);
}
// Card reward list assembled here.
else if (key.equalsIgnoreCase("Card Reward")) {
qc.setCardReward(value);
}
}
return qc;
}
/**
* <p>
* assembleEventMetadata.
* </p>
* Handler for metadata contained in event files.
*
* @param contents
* @param qe
*/
private void readMetadata(final List<String> contents, final QuestEvent qe) {
int eqpos;
String key, value;
for (String s : contents) {
s = s.trim();
eqpos = s.indexOf('=');
if (eqpos == -1) {
continue;
}
key = s.substring(0, eqpos);
value = s.substring(eqpos + 1);
if (key.equalsIgnoreCase("Name")) {
qe.setName(value);
} else if (key.equalsIgnoreCase("Title")) {
qe.setTitle(value);
} else if (key.equalsIgnoreCase("Difficulty")) {
qe.setDifficulty(value);
} else if (key.equalsIgnoreCase("Description")) {
qe.setDescription(value);
} else if (key.equalsIgnoreCase("Icon")) {
qe.setIconImageKey(ImageCache.ICON_PREFIX + value);
} else if (key.equalsIgnoreCase("Card Reward")) {
qe.setCardReward(value);
}
}
}
/**
* <p>
* assembleDuelDifficultyLists.
* </p>
* Assemble duel deck difficulty lists
*/
private void assembleDuelDifficultyLists() {
sortedDuels.clear();
sortedDuels.put(QuestEventDifficulty.EASY, new ArrayList<QuestEventDuel>());
sortedDuels.put(QuestEventDifficulty.MEDIUM, new ArrayList<QuestEventDuel>());
sortedDuels.put(QuestEventDifficulty.HARD, new ArrayList<QuestEventDuel>());
sortedDuels.put(QuestEventDifficulty.EXPERT, new ArrayList<QuestEventDuel>());
String s;
for (final QuestEventDuel qd : allDuels) {
s = qd.getDifficulty();
if (s.equalsIgnoreCase("easy")) {
sortedDuels.get(QuestEventDifficulty.EASY).add(qd);
} else if (s.equalsIgnoreCase("medium")) {
sortedDuels.get(QuestEventDifficulty.MEDIUM).add(qd);
} else if (s.equalsIgnoreCase("hard")) {
sortedDuels.get(QuestEventDifficulty.HARD).add(qd);
} else if (s.equalsIgnoreCase("very hard")) {
sortedDuels.get(QuestEventDifficulty.EXPERT).add(qd);
}
}
}
/** */
public void randomizeOpponents() {
final long seed = new Random().nextLong();
final Random r = new Random(seed);
Collections.shuffle(sortedDuels.get(QuestEventDifficulty.EASY), r);
Collections.shuffle(sortedDuels.get(QuestEventDifficulty.MEDIUM), r);
Collections.shuffle(sortedDuels.get(QuestEventDifficulty.HARD), r);
Collections.shuffle(sortedDuels.get(QuestEventDifficulty.EXPERT), r);
}
/**
* <p>
* getChallengeOpponentByNumber.
* </p>
* Returns specific challenge event using its ID. This is to make sure that
* the opponents do not change when the deck editor is launched.
*
* @param n
* @return
*/
private QuestEventChallenge getChallengeEventByNumber(final int n) {
for (final QuestEventChallenge qc : allChallenges) {
if (qc.getId() == n) {
return qc;
}
}
return null;
}
}

View File

@@ -15,10 +15,9 @@ public class QuestAchievements {
// Challenge history
/** The challenges played. */
private int challengesPlayed = 0;
/** */
private List<Integer> completedChallenges = new ArrayList<Integer>();
/** */
private List<Integer> currentChallenges = new ArrayList<Integer>();
private List<String> completedChallenges = new ArrayList<String>();
private List<String> currentChallenges = new ArrayList<String>();
private int win;
private int winstreakBest = 0;
@@ -75,7 +74,7 @@ public class QuestAchievements {
*
* @return List<Integer>
*/
public List<Integer> getLockedChallenges() {
public List<String> getLockedChallenges() {
return this.completedChallenges;
}
@@ -88,7 +87,7 @@ public class QuestAchievements {
* @param i
* the i
*/
public void addLockedChallenge(final int i) {
public void addLockedChallenge(final String i) {
this.completedChallenges.add(i);
}
@@ -97,9 +96,9 @@ public class QuestAchievements {
*
* @return List<Integer>
*/
public List<Integer> getCurrentChallenges() {
public List<String> getCurrentChallenges() {
if (this.currentChallenges == null) {
this.currentChallenges = new ArrayList<Integer>();
this.currentChallenges = new ArrayList<String>();
}
return this.currentChallenges;
@@ -110,7 +109,7 @@ public class QuestAchievements {
*
* @param lst0 List<Integer>
*/
public void setCurrentChallenges(final List<Integer> lst0) {
public void setCurrentChallenges(final List<String> lst0) {
this.currentChallenges = lst0;
}

View File

@@ -40,7 +40,7 @@ import forge.quest.io.QuestDataIO;
public final class QuestData {
/** Holds the latest version of the Quest Data. */
public static final int CURRENT_VERSION_NUMBER = 6;
public static final int CURRENT_VERSION_NUMBER = 7;
// This field places the version number into QD instance,
// but only when the object is created through the constructor

View File

@@ -0,0 +1,60 @@
package forge.quest.io;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import forge.ImageCache;
import forge.deck.Deck;
import forge.deck.io.DeckSerializer;
import forge.quest.QuestEvent;
import forge.quest.QuestEventChallenge;
import forge.quest.QuestEventDifficulty;
import forge.util.FileSection;
import forge.util.FileUtil;
import forge.util.TextUtil;
import forge.util.storage.StorageReaderFolder;
public class QuestChallengeReader extends StorageReaderFolder<QuestEventChallenge> {
public QuestChallengeReader(File deckDir0) {
super(deckDir0, QuestEvent.FN_GET_TITLE);
// TODO Auto-generated constructor stub
}
@Override
protected QuestEventChallenge read(File file) {
final Map<String, List<String>> contents = FileSection.parseSections(FileUtil.readFile(file));
final QuestEventChallenge qc = new QuestEventChallenge();
// Unique properties
FileSection sectionQuest = FileSection.parse(contents.get("quest"), "=");
qc.setId(sectionQuest.get("ID", "-1"));
qc.setOpponent(sectionQuest.get("OpponentName"));
qc.setRepeatable(sectionQuest.getBoolean("Repeat", false));
qc.setAiLife(sectionQuest.getInt("AILife", 25));
qc.setWinsReqd(sectionQuest.getInt("Wins", 20));
qc.setCreditsReward(sectionQuest.getInt("Credit Reward", 100));
qc.setCardReward(sectionQuest.get("Card Reward"));
qc.setHumanExtraCards(Arrays.asList(TextUtil.split(sectionQuest.get("HumanExtras", ""), '|')));
qc.setAiExtraCards(Arrays.asList(TextUtil.split(sectionQuest.get("AIExtras", ""), '|')));
// Common properties
FileSection sectionMeta = FileSection.parse(contents.get("metadata"), "=");
qc.setTitle(sectionMeta.get("Title"));
qc.setName(qc.getTitle()); // Challenges have unique titles
qc.setDifficulty(QuestEventDifficulty.fromString(sectionMeta.get("Difficulty")));
qc.setDescription(sectionMeta.get("Description"));
qc.setIconImageKey(ImageCache.ICON_PREFIX + sectionMeta.get("Icon"));
// Deck
qc.setEventDeck(Deck.fromSections(contents));
return qc;
}
@Override
protected FilenameFilter getFileFilter() {
return DeckSerializer.DCK_FILE_FILTER;
}
}

View File

@@ -121,7 +121,6 @@ public class QuestDataIO {
QuestData data = null;
final GZIPInputStream zin = new GZIPInputStream(new FileInputStream(xmlSaveFile));
final StringBuilder xml = new StringBuilder();
final char[] buf = new char[1024];
final InputStreamReader reader = new InputStreamReader(zin);
@@ -134,12 +133,13 @@ public class QuestDataIO {
}
zin.close();
data = (QuestData) QuestDataIO.getSerializer(true).fromXML(xml.toString());
String bigXML = xml.toString();
data = (QuestData) QuestDataIO.getSerializer(true).fromXML(bigXML);
if (data.getVersionNumber() != QuestData.CURRENT_VERSION_NUMBER) {
try {
QuestDataIO.updateSaveFile(data, xml.toString(), xmlSaveFile.getName().replace(".dat", ""));
QuestDataIO.updateSaveFile(data, bigXML, xmlSaveFile.getName().replace(".dat", ""));
} catch (final Exception e) {
forge.error.BugReporter.reportException(e);
}
@@ -204,9 +204,10 @@ public class QuestDataIO {
}
final QuestAssets qS = newData.getAssets();
final QuestAchievements qA = newData.getAchievements();
switch (saveVersion) {
// There should be a fall-through b/w the cases so that each
// There should be a fall-through between the cases so that each
// version's changes get applied progressively
case 0:
// First beta release with new file format,
@@ -234,7 +235,6 @@ public class QuestDataIO {
QuestDataIO.setFinalField(QuestData.class, "name", newData, filename);
}
final QuestAchievements qA = newData.getAchievements();
QuestDataIO.setFinalField(QuestAchievements.class, "win", qA, Integer.parseInt(document.getElementsByTagName("win").item(0).getTextContent()));
QuestDataIO.setFinalField(QuestAchievements.class, "lost", qA, Integer.parseInt(document.getElementsByTagName("lost").item(0).getTextContent()));
@@ -319,6 +319,19 @@ public class QuestDataIO {
// pet manager will be re-engineered here
case 6:
// have to convert completed challenges list members to strings.
for(int i = qA.getLockedChallenges().size()-1; i >= 0; i-- ) {
Object lc = qA.getLockedChallenges().get(i);
if (!(lc instanceof String))
qA.getLockedChallenges().set(i, lc.toString());
}
for(int i = qA.getCurrentChallenges().size()-1; i >= 0; i-- ) {
Object lc = qA.getCurrentChallenges().get(i);
if (!(lc instanceof String))
qA.getCurrentChallenges().set(i, lc.toString());
}
default:
break;
}

View File

@@ -0,0 +1,47 @@
package forge.quest.io;
import java.io.File;
import java.io.FilenameFilter;
import java.util.List;
import java.util.Map;
import forge.ImageCache;
import forge.deck.Deck;
import forge.deck.io.DeckSerializer;
import forge.quest.QuestEvent;
import forge.quest.QuestEventDifficulty;
import forge.quest.QuestEventDuel;
import forge.util.FileSection;
import forge.util.FileUtil;
import forge.util.storage.StorageReaderFolder;
public class QuestDuelReader extends StorageReaderFolder<QuestEventDuel> {
public QuestDuelReader(File deckDir0) {
super(deckDir0, QuestEvent.FN_GET_NAME);
// TODO Auto-generated constructor stub
}
@Override
protected QuestEventDuel read(File file) {
final Map<String, List<String>> contents = FileSection.parseSections(FileUtil.readFile(file));
final QuestEventDuel qc = new QuestEventDuel();
// Common properties
FileSection sectionMeta = FileSection.parse(contents.get("metadata"), "=");
qc.setTitle(sectionMeta.get("Title"));
qc.setName(sectionMeta.get("Name")); // Challenges have unique titles
qc.setDifficulty(QuestEventDifficulty.fromString(sectionMeta.get("Difficulty")));
qc.setDescription(sectionMeta.get("Description"));
qc.setCardReward(sectionMeta.get("Card Reward"));
qc.setIconImageKey(ImageCache.ICON_PREFIX + sectionMeta.get("Icon"));
// Deck
qc.setEventDeck(Deck.fromSections(contents));
return qc;
}
@Override
protected FilenameFilter getFileFilter() {
return DeckSerializer.DCK_FILE_FILTER;
}
}

View File

@@ -32,4 +32,15 @@ public class BinaryUtil {
}
return c;
} // bit count
public static int getLeastImportantBitIndex(final byte num) {
if( num == 0 ) return -1;
byte mask = 1;
for(int i = 0; mask != 0; i++) {
if( (mask & num) != 0)
return i;
mask = (byte) (mask << 1);
}
return -1;
}
}

View File

@@ -104,6 +104,14 @@ public class FileSection {
public String get(final String fieldName) {
return this.lines.get(fieldName);
}
public String get(final String fieldName, final String defaultValue) {
return lines.containsKey(fieldName) ? this.lines.get(fieldName) : defaultValue;
}
public boolean contains(String keyName) {
return lines.containsKey(keyName);
}
/**
* Gets the int.

View File

@@ -17,6 +17,7 @@
*/
package forge.util;
import java.security.SecureRandom;
import java.util.Random;
/**
@@ -30,7 +31,7 @@ import java.util.Random;
*/
public class MyRandom {
/** Constant <code>random</code>. */
private static Random random = new Random();
private static Random random = new SecureRandom();
/**
* <p>

View File

@@ -19,6 +19,8 @@ package forge.util.storage;
import java.util.Collection;
import com.google.common.base.Predicate;
/**
* TODO: Write javadoc for this type.
*
@@ -35,7 +37,9 @@ public interface IStorageView<T> extends Iterable<T> {
* @return a {@link forge.deck.Deck} object.
*/
T get(final String name);
T find(final Predicate<T> condition);
/**
* Get names of decks.
*

View File

@@ -46,7 +46,7 @@ import forge.util.IItemReader;
public abstract class StorageReaderFolder<T> implements IItemReader<T> {
private final File directory;
private final Function<T, String> keySelector;
private final Function<? super T, String> keySelector;
/**
* Gets the directory.
@@ -62,7 +62,7 @@ public abstract class StorageReaderFolder<T> implements IItemReader<T> {
*
* @param deckDir0 the deck dir0
*/
public StorageReaderFolder(final File deckDir0, Function<T, String> keySelector0) {
public StorageReaderFolder(final File deckDir0, Function<? super T, String> keySelector0) {
this.directory = deckDir0;
keySelector = keySelector0;

View File

@@ -22,6 +22,9 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import forge.util.IItemReader;
//reads and writeDeck Deck objects
@@ -57,6 +60,7 @@ public class StorageView<T> implements IStorageView<T> {
public T get(final String name) {
return this.map.get(name);
}
/*
* (non-Javadoc)
@@ -94,4 +98,9 @@ public class StorageView<T> implements IStorageView<T> {
public int size() {
return this.map.size();
}
@Override
public T find(Predicate<T> condition) {
return Iterables.tryFind(map.values(), condition).orNull();
}
}