*Schemes:Let the player specify the deck of each opponent in Archenemy mode.

*Let the player specify his own scheme deck.
*Fixed Scheme deck editor.
This commit is contained in:
Hellfish
2012-12-02 13:35:21 +00:00
parent 7f4da2c303
commit f69a6e08a2
5 changed files with 398 additions and 121 deletions

View File

@@ -154,6 +154,7 @@ public class Deck extends DeckBase {
result.sideboard.addAll(this.sideboard);
result.avatar = this.avatar;
result.commander = this.commander;
result.schemes.addAll(this.schemes);
}
/*

View File

@@ -16,17 +16,22 @@ import javax.swing.JOptionPane;
import org.apache.commons.lang3.ArrayUtils;
import com.google.common.collect.Iterables;
import forge.Singletons;
import forge.deck.generate.Generate2ColorDeck;
import forge.deck.generate.Generate3ColorDeck;
import forge.deck.generate.Generate5ColorDeck;
import forge.deck.generate.GenerateThemeDeck;
import forge.game.player.PlayerType;
import forge.item.CardDb;
import forge.item.CardPrinted;
import forge.item.ItemPool;
import forge.item.ItemPoolView;
import forge.quest.QuestEvent;
import forge.quest.QuestEventManager;
import forge.util.IStorage;
import forge.util.MyRandom;
/**
* Utility collection for various types of decks.
@@ -302,4 +307,32 @@ public class DeckgenUtil {
}
return result;
}
public static Deck generateSchemeDeck() {
Deck res = new Deck();
Iterable<CardPrinted> allSchemes = Iterables.filter(CardDb.instance().getAllNonTraditionalCards(),CardPrinted.Predicates.type("Scheme"));
for(int i=0;i<20;i++) {
CardPrinted cp = Iterables.get(allSchemes, MyRandom.getRandom().nextInt(Iterables.size(allSchemes)));
int appearances = 0;
for(CardPrinted added : res.getSchemes().toFlatList()) {
if(added.getName().equals(cp.getName()))
{
appearances++;
}
}
if(appearances < 2)
{
res.getSchemes().add(cp);
}
else
{
i--;
}
}
return res;
}
}

View File

@@ -121,7 +121,6 @@ public final class CEditorScheme extends ACEditorBase<CardPrinted, Deck> {
*/
@Override
public void resetTables() {
// Constructed mode can use all cards, no limitations.
this.getTableCatalog().setDeck(ItemPool.createFrom(Iterables.filter(CardDb.instance().getAllNonTraditionalCards(),CardPrinted.Predicates.type("Scheme")), CardPrinted.class));
this.getTableDeck().setDeck(this.controller.getModel().getSchemes());
}

View File

@@ -4,13 +4,15 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import forge.Card;
import com.google.common.collect.Iterables;
import forge.Command;
import forge.GameActionUtil;
import forge.Singletons;
import forge.control.FControl;
import forge.control.Lobby;
@@ -19,19 +21,19 @@ 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.game.player.PlayerType;
import forge.gui.SOverlayUtils;
import forge.gui.deckeditor.CDeckEditorUI;
import forge.gui.deckeditor.controllers.CEditorConstructed;
import forge.gui.deckeditor.controllers.CEditorScheme;
import forge.gui.framework.ICDoc;
import forge.gui.home.VHomeUI;
import forge.item.CardDb;
import forge.gui.toolbox.FDeckChooser;
import forge.item.CardPrinted;
import forge.properties.ForgePreferences;
import forge.properties.ForgePreferences.FPref;
/**
* Controls the deck editor submenu option in the home UI.
* Controls the constructed submenu in the home UI.
*
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
*
@@ -39,22 +41,22 @@ import forge.item.CardPrinted;
public enum CSubmenuArchenemy implements ICDoc {
/** */
SINGLETON_INSTANCE;
private final VSubmenuArchenemy view = VSubmenuArchenemy.SINGLETON_INSTANCE;
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update()
* @see forge.gui.home.ICSubmenu#initialize()
*/
@Override
public void update() {
// Nothing to see here...
}
/* (non-Javadoc)
* @see forge.gui.home.ICSubmenu#initialize()
*/
@Override
public void initialize() {
view.getDcHuman().initialize();
// Checkbox event handling
view.getBtnStart().addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent arg0) {
start();
}
});
VSubmenuArchenemy.SINGLETON_INSTANCE.getLblEditor().setCommand(new Command() {
@Override
@@ -63,32 +65,57 @@ public enum CSubmenuArchenemy implements ICDoc {
FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_CONSTRUCTED);
}
});
final ForgePreferences prefs = Singletons.getModel().getPreferences();
for (FDeckChooser fdc : view.getDeckChoosers()) {
fdc.initialize();
}
// Checkbox event handling
view.getBtnStart().addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent arg0) {
startGame();
}
});
// Checkbox event handling
view.getCbSingletons().addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent arg0) {
prefs.setPref(FPref.DECKGEN_SINGLETONS,
String.valueOf(view.getCbSingletons().isSelected()));
prefs.save();
}
});
view.getCbArtifacts().addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent arg0) {
prefs.setPref(
FPref.DECKGEN_ARTIFACTS, String.valueOf(view.getCbArtifacts().isSelected()));
prefs.save();
}
});
view.getCbRemoveSmall().addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent arg0) {
prefs.setPref(
FPref.DECKGEN_NOSMALL, String.valueOf(view.getCbRemoveSmall().isSelected()));
prefs.save();
}
});
// Pre-select checkboxes
view.getCbSingletons().setSelected(prefs.getPrefBoolean(FPref.DECKGEN_SINGLETONS));
view.getCbArtifacts().setSelected(prefs.getPrefBoolean(FPref.DECKGEN_ARTIFACTS));
view.getCbRemoveSmall().setSelected(prefs.getPrefBoolean(FPref.DECKGEN_NOSMALL));
}
/* (non-Javadoc)
* @see forge.control.home.IControlSubmenu#update()
*/
@Override
public void update() { }
/* (non-Javadoc)
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
*/
@Override
public Command getCommandOnSelect() {
return null;
}
private void start() {
// Retrieve selections
JRadioButton radTemp = null;
for (JRadioButton rad : view.getFieldRadios()) {
if (rad.isSelected()) { radTemp = rad; break; } }
final int numFields = (radTemp == null ? 2 : Integer.valueOf(radTemp.getText()));
// Boilerplate start game code
/** @param lists0 &emsp; {@link java.util.List}<{@link javax.swing.JList}> */
private void startGame() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
@@ -100,32 +127,79 @@ public enum CSubmenuArchenemy implements ICDoc {
final SwingWorker<Object, Void> worker = new SwingWorker<Object, Void>() {
@Override
public Object doInBackground() {
Deck humanDeck = view.getDcHuman().getDeck();
Random rnd = new Random();
String nl = System.getProperty("line.separator");
boolean usedDefaults = false;
MatchStartHelper starter = new MatchStartHelper();
Lobby lobby = Singletons.getControl().getLobby();
List<Deck> playerDecks = new ArrayList<Deck>();
for (int i = 0; i < view.getNumPlayers(); i++) {
Deck d = view.getDeckChoosers().get(i).getDeck();
//Debugging
List<CardPrinted> schemes = new ArrayList<CardPrinted>();
schemes.add(CardDb.instance().getCard("A Display of My Dark Power"));
schemes.add(CardDb.instance().getCard("Behold the Power of Destruction"));
schemes.add(CardDb.instance().getCard("I Know All, I See All"));
schemes.add(CardDb.instance().getCard("Look Skyward and Despair"));
schemes.add(CardDb.instance().getCard("My Genius Knows No Bounds"));
schemes.add(CardDb.instance().getCard("Realms Befitting My Majesty"));
schemes.add(CardDb.instance().getCard("Roots of All Evil"));
schemes.add(CardDb.instance().getCard("The Iron Guardian Stirs"));
schemes.add(CardDb.instance().getCard("The Very Soil Shall Shake"));
schemes.add(CardDb.instance().getCard("Which of You Burns Brightest?"));
starter.addArchenemy(lobby.findLocalPlayer(PlayerType.HUMAN), humanDeck, schemes);
for (int i = 0; i < numFields; i++) {
starter.addPlayer(lobby.findLocalPlayer(PlayerType.COMPUTER), DeckgenUtil.getRandomColorDeck(PlayerType.COMPUTER));
if (d == null) {
//ERROR!
GameActionUtil.showInfoDialg("No deck selected for player " + (i + 1));
return null;
}
playerDecks.add(d);
}
List<CardPrinted> schemes = null;
Object obj = view.getArchenemySchemes().getSelectedValue();
boolean useDefault = VSubmenuArchenemy.SINGLETON_INSTANCE.getCbUseDefaultSchemes().isSelected();
useDefault &= !playerDecks.get(0).getSchemes().isEmpty();
System.out.println(useDefault);
if (useDefault) {
schemes = playerDecks.get(0).getSchemes().toFlatList();
System.out.println(schemes.toString());
usedDefaults = true;
} else {
if (obj instanceof String) {
String sel = (String)obj;
if(sel.equals("Random"))
{
schemes = Iterables.get(view.getAllSchemeDecks(), rnd.nextInt(Iterables.size(view.getAllSchemeDecks()))).getSchemes().toFlatList();
}
else
{
//Generate
schemes = DeckgenUtil.generateSchemeDeck().getSchemes().toFlatList();
}
} else {
schemes = ((Deck)obj).getSchemes().toFlatList();
}
}
if (schemes == null) {
//ERROR!
GameActionUtil.showInfoDialg("No scheme deck selected!");
return null;
}
if (usedDefaults) {
GameActionUtil.showInfoDialg("Using default scheme deck.");
}
Lobby lobby = Singletons.getControl().getLobby();
MatchStartHelper helper = new MatchStartHelper();
for (int i = 0; i < view.getNumPlayers(); i++) {
LobbyPlayer player = lobby.findLocalPlayer(i == 0 ? PlayerType.HUMAN : PlayerType.COMPUTER);
if(i == 0)
{
helper.addArchenemy(player, playerDecks.get(i), schemes);
}
else
{
helper.addPlayer(player, playerDecks.get(i));
}
}
MatchController mc = Singletons.getModel().getMatch();
mc.initMatch(GameType.Archenemy, starter.getPlayerMap());
mc.initMatch(GameType.Archenemy, helper.getPlayerMap());
mc.startRound();
return null;
@@ -138,4 +212,13 @@ public enum CSubmenuArchenemy implements ICDoc {
};
worker.execute();
}
/* (non-Javadoc)
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
*/
@Override
public Command getCommandOnSelect() {
return null;
}
}

View File

@@ -1,30 +1,51 @@
package forge.gui.home.variant;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import com.google.common.collect.Iterables;
import net.miginfocom.swing.MigLayout;
import forge.Singletons;
import forge.deck.Deck;
import forge.game.player.PlayerType;
import forge.gui.CardDetailPanel;
import forge.gui.framework.DragCell;
import forge.gui.framework.DragTab;
import forge.gui.framework.EDocID;
import forge.gui.home.EMenuGroup;
import forge.gui.home.IVSubmenu;
import forge.gui.home.LblHeader;
import forge.gui.home.StartButton;
import forge.gui.home.VHomeUI;
import forge.gui.toolbox.ExperimentalLabel;
import forge.gui.toolbox.FCheckBox;
import forge.gui.toolbox.FDeckChooser;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FList;
import forge.gui.toolbox.FPanel;
import forge.gui.toolbox.FRadioButton;
import forge.gui.toolbox.FScrollPane;
import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FTabbedPane;
import forge.item.CardDb;
import forge.item.CardPrinted;
/**
* Assembles Swing components of deck editor submenu option singleton.
* Assembles Swing components of constructed submenu singleton.
*
* <br><br><i>(V at beginning of class name denotes a view class.)</i>
*
@@ -35,76 +56,142 @@ public enum VSubmenuArchenemy implements IVSubmenu<CSubmenuArchenemy> {
// Fields used with interface IVDoc
private DragCell parentCell;
private final DragTab tab = new DragTab("Multiplayer Test");
private final JPanel pnlFields;
private final DragTab tab = new DragTab("Archenemy Mode");
/** */
private final List<JRadioButton> fieldRadios = new ArrayList<JRadioButton>();
private final StartButton btnStart = new StartButton();
private final ButtonGroup grpFields = new ButtonGroup();
private final LblHeader lblTitle = new LblHeader("Variant: Archenemy");
private final JPanel pnlStart = new JPanel(new MigLayout("insets 0, gap 0, wrap 2"));
private final StartButton btnStart = new StartButton();
private final JCheckBox cbSingletons = new FCheckBox("Singleton Mode");
private final JCheckBox cbArtifacts = new FCheckBox("Remove Artifacts");
private final JCheckBox cbRemoveSmall = new FCheckBox("Remove Small Creatures");
//////////////////////////////
private ExperimentalLabel lblEditor = new ExperimentalLabel("Scheme Deck Editor");
private final FDeckChooser dcHuman = new FDeckChooser("Choose your deck", PlayerType.HUMAN);
private final FTabbedPane tabPane = new FTabbedPane();
private final List<FPanel> playerPanels = new ArrayList<FPanel>();
private final List<FDeckChooser> deckChoosers = new ArrayList<FDeckChooser>();
private final FList archenemySchemes = new FList();
private final List<Deck> allSchemeDecks = new ArrayList<Deck>();
private final JCheckBox cbUseDefaultSchemes = new FCheckBox("Use default scheme decks if possible.");
private final List<JRadioButton> fieldRadios = new ArrayList<JRadioButton>();
private final ButtonGroup grpFields = new ButtonGroup();
private int currentNumTabsShown = 8;
//////////////////////////////
private VSubmenuArchenemy() {
FRadioButton temp;
for (int i = 2; i < 8; i++) {
temp = new FRadioButton();
temp.setText(String.valueOf(i));
fieldRadios.add(temp);
grpFields.add(temp);
lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
//This listener will look for any of the radio buttons being selected
//and call the method that shows/hides tabs appropriately.
ItemListener iListener = new ItemListener() {
@Override
public void itemStateChanged(ItemEvent arg0) {
FRadioButton aButton = (FRadioButton) arg0.getSource();
if (arg0.getStateChange() == ItemEvent.SELECTED) {
changeTabs(Integer.parseInt(aButton.getText()));
}
}
};
//Create all 8 player settings panel
FRadioButton tempRadio = null;
FPanel tempPanel;
FDeckChooser tempChooser;
//Settings panel
FPanel settingsPanel = new FPanel();
settingsPanel.setLayout(new MigLayout("wrap 2"));
FPanel radioPane = new FPanel();
radioPane.setLayout(new MigLayout("wrap 1"));
radioPane.setOpaque(false);
radioPane.add(new FLabel.Builder().text("Set number of opponents").build(), "wrap");
for (int i = 1; i < 8; i++) {
tempRadio = new FRadioButton();
tempRadio.setText(String.valueOf(i));
fieldRadios.add(tempRadio);
grpFields.add(tempRadio);
tempRadio.setSelected(true);
tempRadio.addItemListener(iListener);
radioPane.add(tempRadio, "wrap,align 50% 50%");
}
settingsPanel.add(radioPane, "span 1 2");
settingsPanel.add(cbUseDefaultSchemes);
settingsPanel.add(lblEditor);
tabPane.add("Settings", settingsPanel);
//Player panels (Human + 7 AIs)
for (int i = 0; i < 8; i++) {
tempPanel = new FPanel();
tempPanel.setLayout(new MigLayout("insets 0, gap 0 , wrap 2, flowy"));
tempChooser = new FDeckChooser("Select deck:", i == 0 ? PlayerType.HUMAN : PlayerType.COMPUTER);
tempChooser.initialize();
deckChoosers.add(tempChooser);
tempPanel.add(tempChooser, "span 1 2, w 44%!, gap 0 0 20px 20px, growy, pushy, wrap");
if(i == 0)
{
tempPanel.add(new FLabel.Builder().text("Select Scheme deck:").build(), "flowy");
Vector<Object> listData = new Vector<Object>();
listData.add("Random");
listData.add("Generate");
for(Deck schemeDeck : Singletons.getModel().getDecks().getScheme()) {
listData.add(schemeDeck);
}
archenemySchemes.setListData(listData);
archenemySchemes.setSelectedIndex(0);
archenemySchemes.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
JScrollPane scrSchemes = new FScrollPane(archenemySchemes, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
tempPanel.add(scrSchemes, "h 90%!,wrap");
}
playerPanels.add(tempPanel);
if (i == 0) {
tabPane.add("Human", tempPanel);
} else {
tabPane.add("Opponent " + i, tempPanel);
}
}
final String strCheckboxConstraints = "w 200px!, h 30px!, gap 0 20px 0 0";
pnlStart.setOpaque(false);
pnlStart.add(cbSingletons, strCheckboxConstraints);
pnlStart.add(btnStart, "span 1 3, growx, pushx, align center");
pnlStart.add(cbArtifacts, strCheckboxConstraints);
pnlStart.add(cbRemoveSmall, strCheckboxConstraints);
}
pnlFields = new FPanel();
pnlFields.setLayout(new MigLayout("insets 0, gap 0, wrap"));
pnlFields.add(new FLabel.Builder().text("How many AI opponents are you ready to handle?").build(), "h 30px!");
for (JRadioButton rad : fieldRadios) {
pnlFields.add(rad, "w 100px!, h 30px!, gap 30px 0 0 0");
private void changeTabs(int toShow) {
if (toShow < currentNumTabsShown) {
for (int i = currentNumTabsShown; i > toShow + 1; i--) {
tabPane.remove(i);
}
currentNumTabsShown = tabPane.getComponentCount() - 1;
}
else {
for (int i = currentNumTabsShown; i <= toShow; i++) {
tabPane.add("Opponent " + i, playerPanels.get(i));
}
currentNumTabsShown = tabPane.getComponentCount() - 1;
}
pnlFields.add(lblEditor);
fieldRadios.get(0).setSelected(true);
}
/** @return {@link javax.swing.JButton} */
public JButton getBtnStart() {
return btnStart;
}
/** @return {@link java.util.List} */
public List<JRadioButton> getFieldRadios() {
return fieldRadios;
}
/* (non-Javadoc)
* @see forge.view.home.IViewSubmenu#populate()
*/
@Override
public void populate() {
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().removeAll();
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().setLayout(new MigLayout("insets 0, gap 0, wrap 2"));
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(pnlFields, "w 41%!, gap 6% 6% 50px 0, growy, pushy");
dcHuman.populate();
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(dcHuman, "w 41%!, gap 0 0 50px 0, growy, pushy");
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(new FLabel.Builder()
.text("Starts a new game with preconstructed 2 color decks for each field.")
.build(), "gap 0 0 50px 5px, ax center, span 2");
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(btnStart, "gap 0 0 50px 50px, ax center, span 2");
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().repaintSelf();
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().revalidate();
}
/* (non-Javadoc)
* @see forge.view.home.IViewSubmenu#getGroup()
* @see forge.gui.home.IVSubmenu#getGroupEnum()
*/
@Override
public EMenuGroup getGroupEnum() {
@@ -127,6 +214,51 @@ public enum VSubmenuArchenemy implements IVSubmenu<CSubmenuArchenemy> {
return EDocID.HOME_MULTITEST;
}
/* (non-Javadoc)
* @see forge.gui.home.IVSubmenu#populate()
*/
@Override
public void populate() {
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().removeAll();
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().setLayout(new MigLayout("insets 0, gap 0, wrap 1, ax right"));
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(lblTitle, "w 80%!, h 40px!, gap 0 0 15px 15px, span 2, ax right");
for (FDeckChooser fdc : deckChoosers) {
fdc.populate();
}
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(tabPane, "gap 0 0 50px 50px, growx, growy");
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(pnlStart, "span 1, ax center");
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().revalidate();
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().repaintSelf();
}
/** @return {@link javax.swing.JButton} */
public JButton getBtnStart() {
return this.btnStart;
}
/** @return {@link javax.swing.JCheckBox} */
public JCheckBox getCbSingletons() {
return cbSingletons;
}
/** @return {@link javax.swing.JCheckBox} */
public JCheckBox getCbArtifacts() {
return cbArtifacts;
}
/** @return {@link javax.swing.JCheckBox} */
public JCheckBox getCbRemoveSmall() {
return cbRemoveSmall;
}
//========== Overridden from IVDoc
/* (non-Javadoc)
@@ -169,8 +301,16 @@ public enum VSubmenuArchenemy implements IVSubmenu<CSubmenuArchenemy> {
return parentCell;
}
public final FDeckChooser getDcHuman() {
return dcHuman;
/**
*
* @return a deckchooser for every player
*/
public List<FDeckChooser> getDeckChoosers() {
return deckChoosers;
}
public int getNumPlayers() {
return currentNumTabsShown;
}
/**
@@ -179,4 +319,25 @@ public enum VSubmenuArchenemy implements IVSubmenu<CSubmenuArchenemy> {
public ExperimentalLabel getLblEditor() {
return lblEditor;
}
/**
* @return the cbUseDefaultSchemes
*/
public JCheckBox getCbUseDefaultSchemes() {
return cbUseDefaultSchemes;
}
/**
* @return the archenemySchemes
*/
public FList getArchenemySchemes() {
return archenemySchemes;
}
/**
* @return the allSchemeDecks
*/
public List<Deck> getAllSchemeDecks() {
return allSchemeDecks;
}
}