diff --git a/.gitattributes b/.gitattributes index 9d00a0fd3d3..d526462e28e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -15569,9 +15569,7 @@ forge-gui/src/main/java/forge/gui/home/settings/VSubmenuDownloaders.java -text forge-gui/src/main/java/forge/gui/home/settings/VSubmenuPreferences.java -text forge-gui/src/main/java/forge/gui/home/settings/VSubmenuReleaseNotes.java -text forge-gui/src/main/java/forge/gui/home/settings/package-info.java svneol=native#text/plain -forge-gui/src/main/java/forge/gui/home/variant/CSubmenuArchenemy.java -text forge-gui/src/main/java/forge/gui/home/variant/CSubmenuCommander.java -text -forge-gui/src/main/java/forge/gui/home/variant/VSubmenuArchenemy.java -text forge-gui/src/main/java/forge/gui/home/variant/VSubmenuCommander.java -text forge-gui/src/main/java/forge/gui/input/Input.java -text forge-gui/src/main/java/forge/gui/input/InputAttack.java svneol=native#text/plain diff --git a/forge-core/src/main/java/forge/deck/DeckFormat.java b/forge-core/src/main/java/forge/deck/DeckFormat.java index e945d82e972..1c3400834bf 100644 --- a/forge-core/src/main/java/forge/deck/DeckFormat.java +++ b/forge-core/src/main/java/forge/deck/DeckFormat.java @@ -104,7 +104,6 @@ public enum DeckFormat { - @SuppressWarnings("incomplete-switch") public String getDeckConformanceProblem(Deck deck) { if(deck == null) { return "is not selected"; @@ -123,63 +122,47 @@ public enum DeckFormat { return String.format("should not exceed a maximum of %d cards", max); } - switch(this) { - case Commander: //Must contain exactly 1 legendary Commander and a sideboard of 10 or zero cards. + if (this == Commander) { //Must contain exactly 1 legendary Commander and a sideboard of 10 or zero cards. - final CardPool cmd = deck.get(DeckSection.Commander); - if (null == cmd || cmd.isEmpty()) { - return "is missing a commander"; - } - if (!cmd.get(0).getRules().getType().isLegendary() - || !cmd.get(0).getRules().getType().isCreature()) { - return "has a commander that is not a legendary creature"; - } - - ColorSet cmdCI = cmd.get(0).getRules().getColorIdentity(); - List erroneousCI = new ArrayList(); - - for(Entry cp : deck.get(DeckSection.Main)) { - if(!cp.getKey().getRules().getColorIdentity().hasNoColorsExcept(cmdCI.getColor())) - { - erroneousCI.add(cp.getKey()); - } - } - if(deck.has(DeckSection.Sideboard)) - { - for(Entry cp : deck.get(DeckSection.Sideboard)) { - if(!cp.getKey().getRules().getColorIdentity().hasNoColorsExcept(cmdCI.getColor())) - { - erroneousCI.add(cp.getKey()); - } - } - } - - if(erroneousCI.size() > 0) - { - StringBuilder sb = new StringBuilder("contains card that do not match the commanders color identity:"); - - for(PaperCard cp : erroneousCI) - { - sb.append("\n").append(cp.getName()); - } - - return sb.toString(); - } - - break; + final CardPool cmd = deck.get(DeckSection.Commander); + if (null == cmd || cmd.isEmpty()) { + return "is missing a commander"; + } + if (!cmd.get(0).getRules().getType().isLegendary() + || !cmd.get(0).getRules().getType().isCreature()) { + return "has a commander that is not a legendary creature"; + } - case Archenemy: //Must contain at least 20 schemes, max 2 of each. - final CardPool schemes = deck.get(DeckSection.Schemes); - if (schemes == null || schemes.countAll() < 20) { - return "must contain at least 20 schemes"; - } + ColorSet cmdCI = cmd.get(0).getRules().getColorIdentity(); + List erroneousCI = new ArrayList(); - for (Entry cp : schemes) { - if (cp.getValue() > 2) { - return String.format("must not contain more than 2 copies of any Scheme, but has %d of '%s'", cp.getValue(), cp.getKey().getName()); - } - } - break; + for(Entry cp : deck.get(DeckSection.Main)) { + if(!cp.getKey().getRules().getColorIdentity().hasNoColorsExcept(cmdCI.getColor())) + { + erroneousCI.add(cp.getKey()); + } + } + if(deck.has(DeckSection.Sideboard)) + { + for(Entry cp : deck.get(DeckSection.Sideboard)) { + if(!cp.getKey().getRules().getColorIdentity().hasNoColorsExcept(cmdCI.getColor())) + { + erroneousCI.add(cp.getKey()); + } + } + } + + if(erroneousCI.size() > 0) + { + StringBuilder sb = new StringBuilder("contains card that do not match the commanders color identity:"); + + for(PaperCard cp : erroneousCI) + { + sb.append("\n").append(cp.getName()); + } + + return sb.toString(); + } } int maxCopies = getMaxCardCopies(); @@ -240,4 +223,18 @@ public enum DeckFormat { } return null; } + + public String getSchemeSectionConformanceProblem(CardPool schemes) { + //Must contain at least 20 schemes, max 2 of each. + if (schemes == null || schemes.countAll() < 20) { + return "must contain at least 20 schemes"; + } + + for (Entry cp : schemes) { + if (cp.getValue() > 2) { + return String.format("must not contain more than 2 copies of any Scheme, but has %d of '%s'", cp.getValue(), cp.getKey().getName()); + } + } + return null; + } } diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 1102c123e46..c741bd5c987 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -783,7 +783,8 @@ public class GameAction { } // Max: I don't know where to put this! - but since it's a state based action, it must be in check state effects - if (game.getRules().getGameType() == GameType.Archenemy) { + if (game.getRules().hasAppliedVariant(GameType.Archenemy) + || game.getRules().hasAppliedVariant(GameType.ArchenemyRumble)) { game.archenemy904_10(); } @@ -1507,7 +1508,7 @@ public class GameAction { Player goesFirst = null; // 904.6: in Archenemy games the Archenemy goes first - if (game != null && game.getRules().getGameType() == GameType.Archenemy) { + if (game != null && game.getRules().hasAppliedVariant(GameType.Archenemy)) { for (Player p : game.getPlayers()) { if (p.isArchenemy()) { return p; diff --git a/forge-game/src/main/java/forge/game/player/RegisteredPlayer.java b/forge-game/src/main/java/forge/game/player/RegisteredPlayer.java index a2483bdf35a..a79cb8fb319 100644 --- a/forge-game/src/main/java/forge/game/player/RegisteredPlayer.java +++ b/forge-game/src/main/java/forge/game/player/RegisteredPlayer.java @@ -106,13 +106,6 @@ public class RegisteredPlayer { public void setTeamNumber(int teamNumber0) { this.teamNumber = teamNumber0; } - - - public static RegisteredPlayer forArchenemy(final Deck deck, final Iterable schemes) { - RegisteredPlayer start = new RegisteredPlayer(deck); - start.schemes = schemes; - return start; - } public static RegisteredPlayer forCommander(final Deck deck) { RegisteredPlayer start = new RegisteredPlayer(deck); @@ -122,23 +115,23 @@ public class RegisteredPlayer { } public static RegisteredPlayer forVariants( - final List appliedVariants, final Deck deck, final int team, //General vars - final Iterable schemes, final boolean isPlayerArchenemy, //Archenemy specific vars - final Iterable planes, final PaperCard vanguardAvatar) { //Planechase and Vanguard + final List appliedVariants, final Deck deck, //General vars + final Iterable schemes, final boolean playerIsArchenemy, //Archenemy specific vars + final Iterable planes, final PaperCard vanguardAvatar) { //Planechase and Vanguard + RegisteredPlayer start = new RegisteredPlayer(deck); - if (appliedVariants.contains(GameType.Archenemy)) { - if (isPlayerArchenemy) { - start.setStartingLife(40); // 904.5: The Archenemy has 40 life. - } + if (appliedVariants.contains(GameType.Archenemy) && playerIsArchenemy) { + start.setStartingLife(40); // 904.5: The Archenemy has 40 life. start.schemes = schemes; } if (appliedVariants.contains(GameType.ArchenemyRumble)) { - start.setStartingLife(start.getStartingLife() + 20); // Allow + start.setStartingLife(40); start.schemes = schemes; } if (appliedVariants.contains(GameType.Commander)) { start.commander = deck.get(DeckSection.Commander).get(0); - start.setStartingLife(40); // 903.7: ...each player sets his or her life total to 40 + start.setStartingLife(start.getStartingLife() + 20); // 903.7: ...each player sets his or her life total to 40 + // Modified for layering of variants to life +20 } if (appliedVariants.contains(GameType.Planechase)) { start.planes = planes; diff --git a/forge-gui/src/main/java/forge/gui/framework/EDocID.java b/forge-gui/src/main/java/forge/gui/framework/EDocID.java index 6f8e4006348..0a6a6ce178d 100644 --- a/forge-gui/src/main/java/forge/gui/framework/EDocID.java +++ b/forge-gui/src/main/java/forge/gui/framework/EDocID.java @@ -16,7 +16,6 @@ import forge.gui.home.settings.VSubmenuAvatars; import forge.gui.home.settings.VSubmenuDownloaders; import forge.gui.home.settings.VSubmenuPreferences; import forge.gui.home.settings.VSubmenuReleaseNotes; -import forge.gui.home.variant.VSubmenuArchenemy; import forge.gui.home.variant.VSubmenuCommander; import forge.gui.match.views.*; import forge.gui.workshop.views.VCardDesigner; @@ -54,7 +53,6 @@ public enum EDocID { /** */ HOME_GAUNTLETLOAD (VSubmenuGauntletLoad.SINGLETON_INSTANCE), /** */ HOME_GAUNTLETQUICK (VSubmenuGauntletQuick.SINGLETON_INSTANCE), /** */ HOME_GAUNTLETCONTESTS (VSubmenuGauntletContests.SINGLETON_INSTANCE), /** */ - HOME_ARCHENEMY (VSubmenuArchenemy.SINGLETON_INSTANCE), /** */ HOME_COMMANDER (VSubmenuCommander.SINGLETON_INSTANCE), /** */ HOME_PREFERENCES (VSubmenuPreferences.SINGLETON_INSTANCE), /** */ HOME_AVATARS (VSubmenuAvatars.SINGLETON_INSTANCE), /** */ diff --git a/forge-gui/src/main/java/forge/gui/home/VHomeUI.java b/forge-gui/src/main/java/forge/gui/home/VHomeUI.java index f7d9035c284..4031fdc1d92 100644 --- a/forge-gui/src/main/java/forge/gui/home/VHomeUI.java +++ b/forge-gui/src/main/java/forge/gui/home/VHomeUI.java @@ -31,7 +31,6 @@ import forge.gui.home.settings.VSubmenuAvatars; import forge.gui.home.settings.VSubmenuDownloaders; import forge.gui.home.settings.VSubmenuPreferences; import forge.gui.home.settings.VSubmenuReleaseNotes; -import forge.gui.home.variant.VSubmenuArchenemy; import forge.gui.home.variant.VSubmenuCommander; import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FScrollPanel; @@ -48,9 +47,6 @@ import java.awt.*; import java.util.*; import java.util.List; -//import forge.gui.home.variant.VSubmenuPlanechase; -//import forge.gui.home.variant.VSubmenuVanguard; - /** * Top level view class for home UI drag layout.
* Uses singleton pattern.
@@ -134,9 +130,6 @@ public enum VHomeUI implements IVTopLevelUI { allSubmenus.add(VSubmenuDownloaders.SINGLETON_INSTANCE); allSubmenus.add(VSubmenuReleaseNotes.SINGLETON_INSTANCE); - allSubmenus.add(VSubmenuArchenemy.SINGLETON_INSTANCE); - //allSubmenus.add(VSubmenuVanguard.SINGLETON_INSTANCE); - //allSubmenus.add(VSubmenuPlanechase.SINGLETON_INSTANCE); allSubmenus.add(VSubmenuCommander.SINGLETON_INSTANCE); // For each group: init its panel diff --git a/forge-gui/src/main/java/forge/gui/home/sanctioned/CSubmenuConstructed.java b/forge-gui/src/main/java/forge/gui/home/sanctioned/CSubmenuConstructed.java index ef1fd504061..ce038a498ed 100644 --- a/forge-gui/src/main/java/forge/gui/home/sanctioned/CSubmenuConstructed.java +++ b/forge-gui/src/main/java/forge/gui/home/sanctioned/CSubmenuConstructed.java @@ -1,6 +1,7 @@ package forge.gui.home.sanctioned; import com.google.common.collect.Iterables; + import forge.UiCommand; import forge.Singletons; import forge.deck.CardPool; @@ -18,6 +19,7 @@ import forge.gui.menus.MenuUtil; import forge.gui.toolbox.FList; import forge.gui.toolbox.FOptionPane; import forge.item.PaperCard; +import forge.model.CardCollections; import forge.net.FServer; import forge.net.Lobby; import forge.properties.ForgePreferences; @@ -26,6 +28,7 @@ import forge.util.Aggregates; import forge.util.storage.IStorage; import javax.swing.*; + import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; @@ -57,31 +60,53 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - // Planechase: reinit deck lists and restore last selections (if any) - for (FList deckList : view.getPlanarDeckLists()) { - Vector listData = new Vector(); + final CardCollections cColl = Singletons.getModel().getDecks(); + FList deckList; - listData.add("Use deck's planes section (random if unavailable)"); - listData.add("Generate"); - if (Singletons.getModel().getDecks().getPlane().size() > 0) { - listData.add("Random"); - for (Deck planarDeck : Singletons.getModel().getDecks().getPlane()) { - listData.add(planarDeck); - } - } + for (int i = 0; i < 8; i++) { + // Archenemy: reinit deck list and restore last selections (if any) + deckList = view.getSchemeDeckLists().get(i); + Vector listData = new Vector(); + listData.add("Use deck's scheme section (random if unavailable)"); + listData.add("Generate"); + if (cColl.getScheme().size() > 0) { + listData.add("Random"); + for (Deck schemeDeck : cColl.getScheme()) { + listData.add(schemeDeck); + } + } + Object val = deckList.getSelectedValue(); + deckList.setListData(listData); + if (null != val) { + deckList.setSelectedValue(val, true); + } + if (-1 == deckList.getSelectedIndex()) { + deckList.setSelectedIndex(0); + } // End Archenemy - Object val = deckList.getSelectedValue(); - deckList.setListData(listData); - if (null != val) { - deckList.setSelectedValue(val, true); - } + // Planechase: reinit deck lists and restore last selections (if any) + deckList = view.getPlanarDeckLists().get(i); + listData = new Vector(); - if (-1 == deckList.getSelectedIndex()) { - deckList.setSelectedIndex(0); - } - } // End Planechase + listData.add("Use deck's planes section (random if unavailable)"); + listData.add("Generate"); + if (cColl.getPlane().size() > 0) { + listData.add("Random"); + for (Deck planarDeck : cColl.getPlane()) { + listData.add(planarDeck); + } + } + + val = deckList.getSelectedValue(); + deckList.setListData(listData); + if (null != val) { + deckList.setSelectedValue(val, true); + } + + if (-1 == deckList.getSelectedIndex()) { + deckList.setSelectedIndex(0); + } // End Planechase - for (int i = 0; i < 8; i++) { view.updateVanguardList(i); } @@ -141,15 +166,17 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider { /** Starts a match with the applied variants. */ private void startGame(final List variantTypes) { - if (variantTypes.contains(GameType.Archenemy) || variantTypes.contains(GameType.ArchenemyRumble) - || variantTypes.contains(GameType.Commander)) { - FOptionPane.showMessageDialog("Archenemy and Commander matches cannot currently be started via the " - + "Constructed match setup screen. Please disable any of those variants then restart the match"); + if (variantTypes.contains(GameType.Commander)) { + FOptionPane.showMessageDialog("Commander matches cannot currently be started via the " + + "Constructed match setup screen. Please this variant then restart the match"); return; } - boolean checkLegality = Singletons.getModel().getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY); - + if (!view.isEnoughTeams()) { + FOptionPane.showMessageDialog("There are not enough teams! Please adjust team allocations."); + return; + } + for (final int i : view.getParticipants()) { if (view.getDeckChooser(i).getPlayer() == null) { FOptionPane.showMessageDialog("Please specify a deck for " + view.getPlayerName(i)); @@ -157,6 +184,7 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider { } } // Is it even possible anymore? I think current implementation assigns decks automatically. + boolean checkLegality = Singletons.getModel().getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY); if (checkLegality) { for (final int i : view.getParticipants()) { String name = view.getPlayerName(i); @@ -175,17 +203,53 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider { LobbyPlayer lobbyPlayer = view.isPlayerAI(i) ? lobby.getAiPlayer(name, view.getPlayerAvatar(i)) : lobby.getGuiPlayer(); RegisteredPlayer rp = view.getDeckChooser(i).getPlayer(); + rp.setTeamNumber(view.getTeam(i)); + if (variantTypes.isEmpty()) { players.add(rp.setPlayer(lobbyPlayer)); } else { // Initialise Variant variables Deck deck = rp.getDeck(); Iterable schemes = null; - boolean isPlayerArchenemy = false; + boolean playerIsArchenemy = view.isPlayerArchenemy(i); Iterable planes = null; PaperCard vanguardAvatar = null; Random randomSeed = new Random(); + //Archenemy + if (variantTypes.contains(GameType.ArchenemyRumble) + || (variantTypes.contains(GameType.Archenemy) && playerIsArchenemy)) { + Object selected = view.getSchemeDeckLists().get(i).getSelectedValue(); + CardPool schemePool = null; + if (selected instanceof String) { + String sel = (String) selected; + if (sel.contains("Use deck's scheme section")) { + if (deck.has(DeckSection.Schemes)) { + schemePool = deck.get(DeckSection.Schemes); + } else { + sel = "Random"; + } + } + IStorage sDecks = Singletons.getModel().getDecks().getScheme(); + if (sel.equals("Random") && sDecks.size() != 0) { + schemePool = Aggregates.random(sDecks).get(DeckSection.Schemes); + } + } else { + schemePool = ((Deck) selected).get(DeckSection.Schemes); + } + if (schemePool == null) { //Can be null if player deselects the list selection or chose Generate + schemePool = DeckgenUtil.generateSchemeDeck(); + } + if (checkLegality) { + String errMsg = GameType.Archenemy.getDecksFormat().getSchemeSectionConformanceProblem(schemePool); + if (null != errMsg) { + FOptionPane.showErrorDialog(name + "'s deck " + errMsg, "Invalid Scheme Deck"); + return; + } + } + schemes = schemePool.toFlatList(); + } + //Planechase if (variantTypes.contains(GameType.Planechase)) { Object selected = view.getPlanarDeckLists().get(i).getSelectedValue(); @@ -202,16 +266,12 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider { IStorage pDecks = Singletons.getModel().getDecks().getPlane(); if (sel.equals("Random") && pDecks.size() != 0) { planePool = Aggregates.random(pDecks).get(DeckSection.Planes); - } else if (planePool == null) { - planePool = DeckgenUtil.generatePlanarDeck(); } } else { planePool = ((Deck) selected).get(DeckSection.Planes); } - if (planePool == null) { //ERROR! Can be null if player deselects the list selection - GuiDialog.message("No Planar deck selected for " + name - + ". Please choose one or disable the Planechase variant"); - return; + if (planePool == null) { //Can be null if player deselects the list selection or chose Generate + planePool = DeckgenUtil.generatePlanarDeck(); } if (checkLegality) { String errMsg = GameType.Planechase.getDecksFormat().getPlaneSectionConformanceProblem(planePool); @@ -240,15 +300,15 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider { } else { vanguardAvatar = (PaperCard)selected; } - if (vanguardAvatar == null) { //ERROR! + if (vanguardAvatar == null) { //ERROR! null if avatar deselected on list GuiDialog.message("No Vanguard avatar selected for " + name + ". Please choose one or disable the Vanguard variant"); return; } } - players.add(RegisteredPlayer.forVariants(variantTypes, rp.getDeck(), view.getTeam(i), - schemes, isPlayerArchenemy, planes, vanguardAvatar).setPlayer(lobbyPlayer)); + players.add(RegisteredPlayer.forVariants(variantTypes, rp.getDeck(), schemes, + playerIsArchenemy, planes, vanguardAvatar).setPlayer(lobbyPlayer)); } view.getDeckChooser(i).saveState(); } diff --git a/forge-gui/src/main/java/forge/gui/home/sanctioned/VSubmenuConstructed.java b/forge-gui/src/main/java/forge/gui/home/sanctioned/VSubmenuConstructed.java index a6184cf3d84..2a41ef3f06c 100644 --- a/forge-gui/src/main/java/forge/gui/home/sanctioned/VSubmenuConstructed.java +++ b/forge-gui/src/main/java/forge/gui/home/sanctioned/VSubmenuConstructed.java @@ -1,6 +1,7 @@ package forge.gui.home.sanctioned; import com.google.common.base.Predicate; + import forge.UiCommand; import forge.Singletons; import forge.deck.DeckSection; @@ -30,11 +31,13 @@ import forge.util.Lang; import forge.util.MyRandom; import forge.util.NameGenerator; import net.miginfocom.swing.MigLayout; + import org.apache.commons.lang3.StringUtils; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; + import java.awt.*; import java.awt.event.*; import java.util.*; @@ -64,6 +67,7 @@ public enum VSubmenuConstructed implements IVSubmenu { private PlayerPanel playerPanelWithFocus; private GameType currentGameMode = GameType.Constructed; private List teams = new ArrayList(MAX_PLAYERS); + private List archenemyTeams = new ArrayList(MAX_PLAYERS); private final StartButton btnStart = new StartButton(); private final JPanel pnlStart = new JPanel(new MigLayout("insets 0, gap 0, wrap 2")); @@ -78,7 +82,7 @@ public enum VSubmenuConstructed implements IVSubmenu { private final FCheckBox vntArchenemy = new FCheckBox("Archenemy"); private String archenemyType = "Classic"; private final FComboBoxWrapper comboArchenemy = new FComboBoxWrapper(new String[]{ - "Classic Archenemy (player 1 is Archenemy)", "Archenemy Rumble (All players are Archenemies)"}); + "Archenemy (Classic - One player is the Archenemy)", "Supervillan Rumble (All players are Archenemies)"}); // Player frame elements private final JPanel playersFrame = new JPanel(new MigLayout("insets 0, gap 0 5, wrap, hidemode 3")); @@ -95,6 +99,10 @@ public enum VSubmenuConstructed implements IVSubmenu { private final FCheckBox cbArtifacts = new FCheckBox("Remove Artifacts"); // Variants + private final List> schemeDeckLists = new ArrayList>(); + private final List schemeDeckPanels = new ArrayList(MAX_PLAYERS); + private int lastArchenemy = 0; + private final List> planarDeckLists = new ArrayList>(); private final List planarDeckPanels = new ArrayList(MAX_PLAYERS); @@ -121,7 +129,6 @@ public enum VSubmenuConstructed implements IVSubmenu { vntCommander.setEnabled(false); vntPlanechase.addItemListener(iListenerVariants); vntArchenemy.addItemListener(iListenerVariants); - vntArchenemy.setEnabled(false); comboArchenemy.setSelectedIndex(0); comboArchenemy.setEnabled(vntArchenemy.isSelected()); comboArchenemy.addActionListener(aeComboListener); @@ -146,6 +153,7 @@ public enum VSubmenuConstructed implements IVSubmenu { String constraints = "pushx, growx, wrap, hidemode 3"; for (int i = 0; i < MAX_PLAYERS; i++) { teams.add(i+1); + archenemyTeams.add(i == 0 ? 1 : 2); PlayerPanel player = new PlayerPanel(i); playerPanels.add(player); @@ -255,6 +263,20 @@ public enum VSubmenuConstructed implements IVSubmenu { }); deckChoosers.add(mainChooser); + // Scheme deck list + FPanel schemeDeckPanel = new FPanel(); + schemeDeckPanel.setBorderToggle(false); + schemeDeckPanel.setLayout(new MigLayout(sectionConstraints)); + schemeDeckPanel.add(new FLabel.Builder().text("Select Scheme deck:").build(), labelConstraints); + FList schemeDeckList = new FList(); + schemeDeckList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + + FScrollPane scrSchemes = new FScrollPane(schemeDeckList, true, + ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + schemeDeckPanel.add(scrSchemes, "grow, push"); + schemeDeckLists.add(schemeDeckList); + schemeDeckPanels.add(schemeDeckPanel); + // Planar deck list FPanel planarDeckPanel = new FPanel(); planarDeckPanel.setBorderToggle(false); @@ -308,11 +330,18 @@ public enum VSubmenuConstructed implements IVSubmenu { decksFrame.add(cbSingletons, strCheckboxConstraints); decksFrame.add(cbArtifacts, strCheckboxConstraints); } - } + } + else if (GameType.Archenemy == forGameType || GameType.ArchenemyRumble == forGameType) { + if (isPlayerArchenemy(playerWithFocus)) { + decksFrame.add(schemeDeckPanels.get(playerWithFocus), "grow, push"); + } else { + populateDeckPanel(GameType.Constructed); + } + } else if (GameType.Planechase == forGameType) { - decksFrame.add(planarDeckPanels.get(playerWithFocus), "grow, push"); - } - else if (GameType.Vanguard == forGameType) { + decksFrame.add(planarDeckPanels.get(playerWithFocus), "grow, push"); + } + else if (GameType.Vanguard == forGameType) { updateVanguardList(playerWithFocus); decksFrame.add(vgdPanels.get(playerWithFocus), "grow, push"); } @@ -432,10 +461,18 @@ public enum VSubmenuConstructed implements IVSubmenu { private FRadioButton radioHuman; private FRadioButton radioAi; + private FComboBoxWrapper teamComboBox = new FComboBoxWrapper(); + private FComboBoxWrapper aeTeamComboBox = new FComboBoxWrapper(); + private final FLabel deckBtn = new FLabel.ButtonBuilder().text("Select a deck").build(); private final String variantBtnConstraints = "height 30px, hidemode 3"; + private boolean playerIsArchenemy = false; + private final FLabel scmDeckSelectorBtn = new FLabel.ButtonBuilder().text("Select a scheme deck").build(); + private final FLabel scmDeckEditor = new FLabel.ButtonBuilder().text("Scheme Deck Editor").build(); + private final FLabel scmLabel = newLabel("Scheme deck:"); + private final FLabel pchDeckSelectorBtn = new FLabel.ButtonBuilder().text("Select a planar deck").build(); private final FLabel pchDeckEditor = new FLabel.ButtonBuilder().text("Planar Deck Editor").build(); private final FLabel pchLabel = newLabel("Planar deck:"); @@ -446,6 +483,7 @@ public enum VSubmenuConstructed implements IVSubmenu { public PlayerPanel(final int index) { super(); this.index = index; + playerIsArchenemy = index == 0; setLayout(new MigLayout("insets 10px, gap 5px")); @@ -469,17 +507,28 @@ public enum VSubmenuConstructed implements IVSubmenu { this.add(radioHuman, "gapright 5px"); this.add(radioAi, "wrap"); - this.add(newLabel("Deck:"), "w 40px, h 30px"); - this.add(deckBtn, "pushx, growx, wmax 100%-153px, h 30px, spanx 4, wrap"); + this.add(newLabel("Team:"), "w 40px, h 30px"); + populateTeamsComboBoxes(); + teamComboBox.addActionListener(teamListener); + aeTeamComboBox.addActionListener(teamListener); + teamComboBox.addTo(this, "h 30px, pushx, growx, gaptop 5px, hidemode 3"); + aeTeamComboBox.addTo(this, "h 30px, pushx, growx, gaptop 5px, hidemode 3"); + + this.add(newLabel("Deck:"), variantBtnConstraints + ", cell 0 2, sx 2, ax right"); + this.add(deckBtn, variantBtnConstraints + ", cell 2 2, pushx, growx, wmax 100%-153px, h 30px, spanx 4, wrap"); addHandlersDeckSelector(); - this.add(pchLabel, variantBtnConstraints + ", cell 0 2, sx 2, ax right"); - this.add(pchDeckSelectorBtn, variantBtnConstraints + ", cell 2 2, growx, pushx"); - this.add(pchDeckEditor, variantBtnConstraints + ", cell 3 2, sx 3, growx, wrap"); + this.add(scmLabel, variantBtnConstraints + ", cell 0 3, sx 2, ax right"); + this.add(scmDeckSelectorBtn, variantBtnConstraints + ", cell 2 3, growx, pushx"); + this.add(scmDeckEditor, variantBtnConstraints + ", cell 3 3, sx 3, growx, wrap"); - this.add(vgdSelectorBtn, variantBtnConstraints + ", cell 2 3, sx 4, growx, wrap"); - this.add(vgdLabel, variantBtnConstraints + ", cell 0 3, sx 2, ax right"); + this.add(pchLabel, variantBtnConstraints + ", cell 0 4, sx 2, ax right"); + this.add(pchDeckSelectorBtn, variantBtnConstraints + ", cell 2 4, growx, pushx"); + this.add(pchDeckEditor, variantBtnConstraints + ", cell 3 4, sx 3, growx, wrap"); + + this.add(vgdLabel, variantBtnConstraints + ", cell 0 5, sx 2, ax right"); + this.add(vgdSelectorBtn, variantBtnConstraints + ", cell 2 5, sx 4, growx, wrap"); addHandlersToVariantsControls(); updateVariantControlsVisibility(); @@ -564,6 +613,16 @@ public enum VSubmenuConstructed implements IVSubmenu { }; public void updateVariantControlsVisibility() { + boolean archenemyVisiblity = appliedVariants.contains(GameType.ArchenemyRumble) + || (appliedVariants.contains(GameType.Archenemy) && playerIsArchenemy); + scmDeckSelectorBtn.setVisible(archenemyVisiblity); + scmDeckEditor.setVisible(archenemyVisiblity); + scmLabel.setVisible(archenemyVisiblity); + + teamComboBox.setVisible(!appliedVariants.contains(GameType.Archenemy)); + aeTeamComboBox.setVisible(appliedVariants.contains(GameType.Archenemy)); + aeTeamComboBox.setEnabled(!(appliedVariants.contains(GameType.Archenemy) && playerIsArchenemy)); + pchDeckSelectorBtn.setVisible(appliedVariants.contains(GameType.Planechase)); pchDeckEditor.setVisible(appliedVariants.contains(GameType.Planechase)); pchLabel.setVisible(appliedVariants.contains(GameType.Planechase)); @@ -597,10 +656,90 @@ public enum VSubmenuConstructed implements IVSubmenu { avatarLabel.requestFocusInWindow(); } + private void populateTeamsComboBoxes() { + aeTeamComboBox.addItem("Archenemy"); + aeTeamComboBox.addItem("Heroes"); + aeTeamComboBox.setSelectedIndex(archenemyTeams.get(index) - 1); + aeTeamComboBox.setEnabled(playerIsArchenemy); + + for (int i = 1; i <= MAX_PLAYERS; i++) { + teamComboBox.addItem(i); + } + teamComboBox.setSelectedIndex(teams.get(index) - 1); + teamComboBox.setEnabled(true); + } + + private ActionListener teamListener = new ActionListener() { + @SuppressWarnings("unchecked") + @Override + public void actionPerformed(ActionEvent e) { + FComboBox cb = (FComboBox)e.getSource(); + cb.requestFocusInWindow(); + Object selection = cb.getSelectedItem(); + + if (null == selection) { + return; + } + if (appliedVariants.contains(GameType.Archenemy)) { + String sel = (String) selection; + if (sel.contains("Archenemy")) { + lastArchenemy = index; + for (PlayerPanel pp : playerPanels) { + int i = pp.index; + archenemyTeams.set(i, i == lastArchenemy ? 1 : 2); + pp.aeTeamComboBox.setSelectedIndex(i == lastArchenemy ? 0 : 1); + pp.toggleIsPlayerArchenemy(); + } + } + } else { + Integer sel = (Integer) selection; + teams.set(index, sel); + } + + changePlayerFocus(index); + } + }; + + public void toggleIsPlayerArchenemy() { + if (appliedVariants.contains(GameType.Archenemy)) { + playerIsArchenemy = lastArchenemy == index; + } else { + playerIsArchenemy = appliedVariants.contains(GameType.ArchenemyRumble); + } + updateVariantControlsVisibility(); + } + /** * @param index */ private void addHandlersToVariantsControls() { + // Archenemy buttons + scmDeckSelectorBtn.setCommand(new Runnable() { + @Override + public void run() { + currentGameMode = archenemyType.contains("Classic") ? GameType.Archenemy : GameType.ArchenemyRumble; + scmDeckSelectorBtn.requestFocusInWindow(); + changePlayerFocus(index, currentGameMode); + } + }); + + scmDeckEditor.setCommand(new UiCommand() { + @Override + public void run() { + currentGameMode = archenemyType.contains("Classic") ? GameType.Archenemy : GameType.ArchenemyRumble; + Predicate predSchemes = new Predicate() { + @Override + public boolean apply(PaperCard arg0) { + return arg0.getRules().getType().isScheme(); + } + }; + + Singletons.getControl().setCurrentScreen(FScreen.DECK_EDITOR_ARCHENEMY); + CDeckEditorUI.SINGLETON_INSTANCE.setEditorController( + new CEditorVariant(Singletons.getModel().getDecks().getScheme(), predSchemes, DeckSection.Schemes, FScreen.DECK_EDITOR_PLANECHASE)); + } + }); + // Planechase buttons pchDeckSelectorBtn.setCommand(new Runnable() { @Override @@ -742,12 +881,6 @@ public enum VSubmenuConstructed implements IVSubmenu { else { setRandomAvatar(); } - this.addMouseListener(new FMouseAdapter() { - @Override - public void onLeftClick(MouseEvent e) { - avatarLabel.requestFocusInWindow(); - } - }); avatarLabel.setToolTipText("L-click: Select avatar. R-click: Randomize avatar."); avatarLabel.addFocusListener(avatarFocusListener); @@ -878,9 +1011,6 @@ public enum VSubmenuConstructed implements IVSubmenu { return newName; } - ///////////////////////////////////////////// - //========== Various listeners in build order - private List getPlayerNames() { List names = new ArrayList(); for (PlayerPanel pp : playerPanels) { @@ -889,6 +1019,32 @@ public enum VSubmenuConstructed implements IVSubmenu { return names; } + public String getPlayerName(int i) { + return playerPanels.get(i).getPlayerName(); + } + + public int getPlayerAvatar(int i) { + return playerPanels.get(i).getAvatarIndex(); + } + + public boolean isEnoughTeams() { + int lastTeam = -1; + final List teamList = appliedVariants.contains(GameType.Archenemy) ? archenemyTeams : teams; + System.out.println(teamList); + + for (final int i : getParticipants()) { + if (lastTeam == -1) { + lastTeam = teamList.get(i); + } else if (lastTeam != teamList.get(i)) { + return true; + } + } + return false; + } + + ///////////////////////////////////////////// + //========== Various listeners in build order + /** This listener unlocks the relevant buttons for players * and enables/disables archenemy combobox as appropriate. */ private ItemListener iListenerVariants = new ItemListener() { @@ -929,6 +1085,7 @@ public enum VSubmenuConstructed implements IVSubmenu { } for (PlayerPanel pp : playerPanels) { + pp.toggleIsPlayerArchenemy(); pp.updateVariantControlsVisibility(); } changePlayerFocus(playerWithFocus, currentGameMode); @@ -942,10 +1099,17 @@ public enum VSubmenuConstructed implements IVSubmenu { public void actionPerformed(ActionEvent e) { FComboBox cb = (FComboBox)e.getSource(); archenemyType = (String)cb.getSelectedItem(); + GameType mode = archenemyType.contains("Classic") ? GameType.Archenemy : GameType.ArchenemyRumble; appliedVariants.remove(GameType.Archenemy); appliedVariants.remove(GameType.ArchenemyRumble); - appliedVariants.add(archenemyType.contains("Classic") - ? GameType.Archenemy : GameType.ArchenemyRumble); + appliedVariants.add(mode); + + currentGameMode = mode; + for (PlayerPanel pp : playerPanels) { + pp.toggleIsPlayerArchenemy(); + pp.updateVariantControlsVisibility(); + } + changePlayerFocus(playerWithFocus, currentGameMode); } }; @@ -1032,7 +1196,7 @@ public enum VSubmenuConstructed implements IVSubmenu { } public int getTeam(final int playerIndex) { - return teams.get(playerIndex); + return appliedVariants.contains(GameType.Archenemy) ? archenemyTeams.get(playerIndex) : teams.get(playerIndex); } /** Gets the list of planar deck lists. */ @@ -1040,6 +1204,15 @@ public enum VSubmenuConstructed implements IVSubmenu { return planarDeckLists; } + /** Gets the list of planar deck lists. */ + public List> getSchemeDeckLists() { + return schemeDeckLists; + } + + public boolean isPlayerArchenemy(final int playernum) { + return playerPanels.get(playernum).playerIsArchenemy; + } + /** Gets the list of Vanguard avatar lists. */ public List> getVanguardLists() { return vgdAvatarLists; @@ -1106,12 +1279,4 @@ public enum VSubmenuConstructed implements IVSubmenu { vgdList.setSelectedIndex(0); } } - - public String getPlayerName(int i) { - return playerPanels.get(i).getPlayerName(); - } - - public int getPlayerAvatar(int i) { - return playerPanels.get(i).getAvatarIndex(); - } } diff --git a/forge-gui/src/main/java/forge/gui/home/variant/CSubmenuArchenemy.java b/forge-gui/src/main/java/forge/gui/home/variant/CSubmenuArchenemy.java deleted file mode 100644 index 761cc1805a6..00000000000 --- a/forge-gui/src/main/java/forge/gui/home/variant/CSubmenuArchenemy.java +++ /dev/null @@ -1,243 +0,0 @@ -package forge.gui.home.variant; - -import com.google.common.base.Predicate; -import forge.UiCommand; -import forge.Singletons; -import forge.deck.Deck; -import forge.deck.DeckSection; -import forge.game.GameType; -import forge.game.player.RegisteredPlayer; -import forge.gui.GuiDialog; -import forge.gui.SOverlayUtils; -import forge.gui.deckchooser.DeckgenUtil; -import forge.gui.deckchooser.FDeckChooser; -import forge.gui.deckeditor.CDeckEditorUI; -import forge.gui.deckeditor.controllers.CEditorVariant; -import forge.gui.framework.FScreen; -import forge.gui.framework.ICDoc; -import forge.gui.toolbox.FList; -import forge.item.PaperCard; -import forge.net.FServer; -import forge.net.Lobby; -import forge.properties.ForgePreferences; -import forge.properties.ForgePreferences.FPref; -import forge.util.Aggregates; - -import javax.swing.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.ArrayList; -import java.util.List; -import java.util.Vector; - -/** - * Controls the constructed submenu in the home UI. - * - *

(C at beginning of class name denotes a control class.) - * - */ -public enum CSubmenuArchenemy implements ICDoc { - /** */ - SINGLETON_INSTANCE; - private final VSubmenuArchenemy view = VSubmenuArchenemy.SINGLETON_INSTANCE; - - - /* (non-Javadoc) - * @see forge.gui.home.ICSubmenu#initialize() - */ - @Override - public void update() { - // reinit deck list and restore last selections (if any) - FList deckList = view.getArchenemySchemes(); - Vector listData = new Vector(); - listData.add("Random"); - listData.add("Generate"); - for (Deck schemeDeck : Singletons.getModel().getDecks().getScheme()) { - listData.add(schemeDeck); - } - - Object val = deckList.getSelectedValue(); - deckList.setListData(listData); - if (null != val) { - deckList.setSelectedValue(val, true); - } - - if (-1 == deckList.getSelectedIndex()) { - deckList.setSelectedIndex(0); - } - - SwingUtilities.invokeLater(new Runnable() { - @Override public void run() { view.getBtnStart().requestFocusInWindow(); } - }); - } - - /* (non-Javadoc) - * @see forge.gui.home.ICSubmenu#initialize() - */ - @Override - public void initialize() { - - VSubmenuArchenemy.SINGLETON_INSTANCE.getLblEditor().setCommand(new UiCommand() { - private static final long serialVersionUID = -4548064747843903896L; - - @Override - public void run() { - - Predicate predSchemes = new Predicate() { - @Override - public boolean apply(PaperCard arg0) { - if(arg0.getRules().getType().isScheme()) - { - return true; - } - - return false; - } - }; - - Singletons.getControl().setCurrentScreen(FScreen.DECK_EDITOR_ARCHENEMY); - CDeckEditorUI.SINGLETON_INSTANCE.setEditorController( - new CEditorVariant(Singletons.getModel().getDecks().getScheme(), predSchemes, DeckSection.Schemes, FScreen.DECK_EDITOR_ARCHENEMY)); - } - }); - - 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)); - } - - - /** @param lists0   {@link java.util.List}<{@link javax.swing.JList}> */ - private void startGame() { - - - - boolean usedDefaults = false; - - List playerDecks = new ArrayList(); - for (int i = 0; i < view.getNumPlayers(); i++) { - RegisteredPlayer d = view.getDeckChoosers().get(i).getPlayer(); - - if (d == null) { - //ERROR! - GuiDialog.message("No deck selected for player " + (i + 1)); - return; - } - playerDecks.add(d.getDeck()); - } - - List schemes = null; - Object obj = view.getArchenemySchemes().getSelectedValue(); - - boolean useDefault = VSubmenuArchenemy.SINGLETON_INSTANCE.getCbUseDefaultSchemes().isSelected(); - useDefault &= playerDecks.get(0).has(DeckSection.Schemes); - - System.out.println(useDefault); - if (useDefault) { - schemes = playerDecks.get(0).get(DeckSection.Schemes).toFlatList(); - System.out.println(schemes.toString()); - usedDefaults = true; - } else { - if (obj instanceof String) { - String sel = (String) obj; - if (sel.equals("Random")) { - if (view.getAllSchemeDecks().isEmpty()) { - //Generate if no constructed scheme decks are available - System.out.println("Generating scheme deck - no others available"); - schemes = DeckgenUtil.generateSchemeDeck().toFlatList(); - } else { - System.out.println("Using scheme deck: " + Aggregates.random(view.getAllSchemeDecks()).getName()); - schemes = Aggregates.random(view.getAllSchemeDecks()).get(DeckSection.Schemes).toFlatList(); - } - } else { - //Generate - schemes = DeckgenUtil.generateSchemeDeck().toFlatList(); - } - } else { - schemes = ((Deck) obj).get(DeckSection.Schemes).toFlatList(); - } - } - if (schemes == null) { - //ERROR! - GuiDialog.message("No scheme deck selected!"); - return; - } - - if (usedDefaults) { - - GuiDialog.message("Using default scheme deck."); - } - - // won't cancel after this point - SOverlayUtils.startGameOverlay(); - SOverlayUtils.showOverlay(); - - Lobby lobby = FServer.instance.getLobby(); - - List players = new ArrayList(); - for (int i = 0; i < view.getNumPlayers(); i++) { - if (i == 0) { - - RegisteredPlayer psc = RegisteredPlayer.forArchenemy(playerDecks.get(i), schemes); - psc.setStartingLife(40); // 904.5: The Archenemy has 40 life. - players.add(psc.setPlayer(view.isPlayerAI(i) ? lobby.getAiPlayer() : lobby.getGuiPlayer())); - } else { - RegisteredPlayer psc = new RegisteredPlayer(playerDecks.get(i)); - psc.setTeamNumber(0); - players.add(psc.setPlayer(view.isPlayerAI(i) ? lobby.getAiPlayer() : lobby.getGuiPlayer())); - } - } - - Singletons.getControl().startMatch(GameType.Archenemy, players); - } - - /* (non-Javadoc) - * @see forge.gui.framework.ICDoc#getCommandOnSelect() - */ - @Override - public UiCommand getCommandOnSelect() { - return null; - } -} diff --git a/forge-gui/src/main/java/forge/gui/home/variant/VSubmenuArchenemy.java b/forge-gui/src/main/java/forge/gui/home/variant/VSubmenuArchenemy.java deleted file mode 100644 index 1c0b1736211..00000000000 --- a/forge-gui/src/main/java/forge/gui/home/variant/VSubmenuArchenemy.java +++ /dev/null @@ -1,327 +0,0 @@ -package forge.gui.home.variant; - -import forge.Singletons; -import forge.deck.Deck; -import forge.gui.deckchooser.FDeckChooser; -import forge.gui.framework.DragCell; -import forge.gui.framework.DragTab; -import forge.gui.framework.EDocID; -import forge.gui.home.*; -import forge.gui.toolbox.*; -import net.miginfocom.swing.MigLayout; - -import javax.swing.*; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.util.ArrayList; -import java.util.List; - -/** - * Assembles Swing components of constructed submenu singleton. - * - *

(V at beginning of class name denotes a view class.) - * - */ -public enum VSubmenuArchenemy implements IVSubmenu { - /** */ - SINGLETON_INSTANCE; - - // Fields used with interface IVDoc - private DragCell parentCell; - private final DragTab tab = new DragTab("Archenemy Mode"); - - /** */ - 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 final FLabel lblEditor = new FLabel.ButtonBuilder().text("Scheme Deck Editor").fontSize(16).build(); - private final FTabbedPane tabPane = new FTabbedPane(); - private final List playerPanels = new ArrayList(); - private final List deckChoosers = new ArrayList(); - private final FList archenemySchemes = new FList(); - private final List allSchemeDecks = new ArrayList(); - private final JCheckBox cbUseDefaultSchemes = new FCheckBox("Use default scheme decks if possible."); - private final List playerIsAIRadios = new ArrayList(); - private final List fieldRadios = new ArrayList(); - private int currentNumTabsShown = 8; - - ////////////////////////////// - - private VSubmenuArchenemy() { - 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())); - } - } - - }; - - //Settings panel - FPanel settingsPanel = new FPanel(); - settingsPanel.setLayout(new MigLayout("wrap 2, ax center")); - FPanel radioPaneContainer = new FPanel(new MigLayout()); - radioPaneContainer.setOpaque(false); - JXButtonPanel radioPane = new JXButtonPanel(); - radioPane.add(new FLabel.Builder().text("Set number of opponents").build()); - for (int i = 1; i < 8; i++) { - FRadioButton tempRadio = new FRadioButton(String.valueOf(i)); - fieldRadios.add(tempRadio); - tempRadio.addItemListener(iListener); - radioPane.add(tempRadio, "align 50% 50%, gaptop 5"); - } - radioPaneContainer.add(radioPane); - settingsPanel.add(radioPaneContainer, "span 1 2"); - settingsPanel.add(cbUseDefaultSchemes); - settingsPanel.add(lblEditor, "w pref + 24, h pref + 8, ax center"); - tabPane.add("Settings", settingsPanel); - - for (Deck schemeDeck : Singletons.getModel().getDecks().getScheme()) { - if (!allSchemeDecks.contains(schemeDeck)) { - allSchemeDecks.add(schemeDeck); - } - } - - //Player panels (Human + 7 AIs) - for (int i = 0; i < 8; i++) { - FPanel tempPanel = new FPanel(); - tempPanel.setLayout(new MigLayout("insets 0, gap 0 , wrap 2, flowy, ax center")); - - FDeckChooser tempChooser = new FDeckChooser(i != 0); - tempChooser.initialize(); - - deckChoosers.add(tempChooser); - - ButtonGroup tempBtnGroup = new ButtonGroup(); - FRadioButton tmpAI = new FRadioButton(); - tmpAI.setText("AI"); - tmpAI.setSelected(i != 0); - FRadioButton tmpHuman = new FRadioButton(); - tmpHuman.setText("Human"); - tmpHuman.setSelected(i == 0); - - FPanel typeBtnPanel = new FPanel(); - typeBtnPanel.add(tmpAI); - typeBtnPanel.add(tmpHuman,"wrap"); - tempPanel.add(typeBtnPanel); - - tempBtnGroup.add(tmpAI); - tempBtnGroup.add(tmpHuman); - playerIsAIRadios.add(tmpAI); - - tempPanel.add(tempChooser, "span 1 2, w 55%!, gap 10px 10px 0px 10px, growy, pushy, wrap"); - if (i == 0) { - - tempPanel.add(new FLabel.Builder().text("Select Scheme deck:").build(), "gap 0px 0px 10px 10px, flowy"); - - archenemySchemes.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); - - FScrollPane scrSchemes = new FScrollPane(archenemySchemes, true, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - tempPanel.add(scrSchemes, "h 90%, w 33%, gap 0px 10px 0px 10px, growy, pushy, wrap"); - } - - playerPanels.add(tempPanel); - - tabPane.add("Player " + (i+1), tempPanel); - } - - final String strCheckboxConstraints = "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); - - // ensure we don't fire the selected event before the tabPane is populated - fieldRadios.get(fieldRadios.size() - 1).setSelected(true); - } - - public boolean isPlayerAI(int playernum) { - return playerIsAIRadios.get(playernum).isSelected(); - } - - 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("Player " + i, playerPanels.get(i)); - } - currentNumTabsShown = tabPane.getComponentCount() - 1; - } - } - - /* (non-Javadoc) - * @see forge.gui.home.IVSubmenu#getGroupEnum() - */ - @Override - public EMenuGroup getGroupEnum() { - return EMenuGroup.VARIANT; - } - - /* (non-Javadoc) - * @see forge.gui.home.IVSubmenu#getMenuTitle() - */ - @Override - public String getMenuTitle() { - return "Archenemy"; - } - - /* (non-Javadoc) - * @see forge.gui.home.IVSubmenu#getItemEnum() - */ - @Override - public EDocID getItemEnum() { - return EDocID.HOME_ARCHENEMY; - } - - /* (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, ax right"); - - for (FDeckChooser fdc : deckChoosers) { - fdc.populate(); - } - - VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(tabPane, "gap 20px 20px 20px 0px, pushx, pushy, growx, growy"); - - VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(pnlStart, "gap 0 0 3.5%! 3.5%!, 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) - * @see forge.gui.framework.IVDoc#getDocumentID() - */ - @Override - public EDocID getDocumentID() { - return EDocID.HOME_ARCHENEMY; - } - - /* (non-Javadoc) - * @see forge.gui.framework.IVDoc#getTabLabel() - */ - @Override - public DragTab getTabLabel() { - return tab; - } - - /* (non-Javadoc) - * @see forge.gui.framework.IVDoc#getLayoutControl() - */ - @Override - public CSubmenuArchenemy getLayoutControl() { - return CSubmenuArchenemy.SINGLETON_INSTANCE; - } - - /* (non-Javadoc) - * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) - */ - @Override - public void setParentCell(DragCell cell0) { - this.parentCell = cell0; - } - - /* (non-Javadoc) - * @see forge.gui.framework.IVDoc#getParentCell() - */ - @Override - public DragCell getParentCell() { - return parentCell; - } - - /** - * - * @return a deckchooser for every player - */ - public List getDeckChoosers() { - return deckChoosers; - } - - /** - * @return the currentNumTabsShown - */ - public int getNumPlayers() { - return currentNumTabsShown; - } - - /** - * @return the lblEditor - */ - public FLabel getLblEditor() { - return lblEditor; - } - - /** - * @return the cbUseDefaultSchemes - */ - public JCheckBox getCbUseDefaultSchemes() { - return cbUseDefaultSchemes; - } - - /** - * @return the archenemySchemes - */ - public FList getArchenemySchemes() { - return archenemySchemes; - } - - /** - * @return the allSchemeDecks - */ - public List getAllSchemeDecks() { - return allSchemeDecks; - } -}