mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
- Archenemy moved to Constructed match setup
- Basic team setup implemented
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -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
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
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<PaperCard> erroneousCI = new ArrayList<PaperCard>();
|
||||
ColorSet cmdCI = cmd.get(0).getRules().getColorIdentity();
|
||||
List<PaperCard> erroneousCI = new ArrayList<PaperCard>();
|
||||
|
||||
for(Entry<PaperCard, Integer> cp : deck.get(DeckSection.Main)) {
|
||||
if(!cp.getKey().getRules().getColorIdentity().hasNoColorsExcept(cmdCI.getColor()))
|
||||
{
|
||||
erroneousCI.add(cp.getKey());
|
||||
}
|
||||
}
|
||||
if(deck.has(DeckSection.Sideboard))
|
||||
{
|
||||
for(Entry<PaperCard, Integer> cp : deck.get(DeckSection.Sideboard)) {
|
||||
if(!cp.getKey().getRules().getColorIdentity().hasNoColorsExcept(cmdCI.getColor()))
|
||||
{
|
||||
erroneousCI.add(cp.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
for(Entry<PaperCard, Integer> cp : deck.get(DeckSection.Main)) {
|
||||
if(!cp.getKey().getRules().getColorIdentity().hasNoColorsExcept(cmdCI.getColor()))
|
||||
{
|
||||
erroneousCI.add(cp.getKey());
|
||||
}
|
||||
}
|
||||
if(deck.has(DeckSection.Sideboard))
|
||||
{
|
||||
for(Entry<PaperCard, Integer> 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:");
|
||||
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());
|
||||
}
|
||||
for(PaperCard cp : erroneousCI)
|
||||
{
|
||||
sb.append("\n").append(cp.getName());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
for (Entry<PaperCard, Integer> 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;
|
||||
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<PaperCard, Integer> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -107,13 +107,6 @@ public class RegisteredPlayer {
|
||||
this.teamNumber = teamNumber0;
|
||||
}
|
||||
|
||||
|
||||
public static RegisteredPlayer forArchenemy(final Deck deck, final Iterable<PaperCard> schemes) {
|
||||
RegisteredPlayer start = new RegisteredPlayer(deck);
|
||||
start.schemes = schemes;
|
||||
return start;
|
||||
}
|
||||
|
||||
public static RegisteredPlayer forCommander(final Deck deck) {
|
||||
RegisteredPlayer start = new RegisteredPlayer(deck);
|
||||
start.commander = deck.get(DeckSection.Commander).get(0);
|
||||
@@ -122,23 +115,23 @@ public class RegisteredPlayer {
|
||||
}
|
||||
|
||||
public static RegisteredPlayer forVariants(
|
||||
final List<GameType> appliedVariants, final Deck deck, final int team, //General vars
|
||||
final Iterable<PaperCard> schemes, final boolean isPlayerArchenemy, //Archenemy specific vars
|
||||
final Iterable<PaperCard> planes, final PaperCard vanguardAvatar) { //Planechase and Vanguard
|
||||
final List<GameType> appliedVariants, final Deck deck, //General vars
|
||||
final Iterable<PaperCard> schemes, final boolean playerIsArchenemy, //Archenemy specific vars
|
||||
final Iterable<PaperCard> 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;
|
||||
|
||||
@@ -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), /** */
|
||||
|
||||
@@ -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.<br>
|
||||
* Uses singleton pattern.<br>
|
||||
@@ -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
|
||||
|
||||
@@ -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<Object> deckList : view.getPlanarDeckLists()) {
|
||||
Vector<Object> listData = new Vector<Object>();
|
||||
final CardCollections cColl = Singletons.getModel().getDecks();
|
||||
FList<Object> 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<Object> listData = new Vector<Object>();
|
||||
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<Object>();
|
||||
|
||||
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,14 +166,16 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider {
|
||||
|
||||
/** Starts a match with the applied variants. */
|
||||
private void startGame(final List<GameType> 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) {
|
||||
@@ -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<PaperCard> schemes = null;
|
||||
boolean isPlayerArchenemy = false;
|
||||
boolean playerIsArchenemy = view.isPlayerArchenemy(i);
|
||||
Iterable<PaperCard> 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<Deck> 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<Deck> 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();
|
||||
}
|
||||
|
||||
@@ -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<CSubmenuConstructed> {
|
||||
private PlayerPanel playerPanelWithFocus;
|
||||
private GameType currentGameMode = GameType.Constructed;
|
||||
private List<Integer> teams = new ArrayList<Integer>(MAX_PLAYERS);
|
||||
private List<Integer> archenemyTeams = new ArrayList<Integer>(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<CSubmenuConstructed> {
|
||||
private final FCheckBox vntArchenemy = new FCheckBox("Archenemy");
|
||||
private String archenemyType = "Classic";
|
||||
private final FComboBoxWrapper<String> comboArchenemy = new FComboBoxWrapper<String>(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<CSubmenuConstructed> {
|
||||
private final FCheckBox cbArtifacts = new FCheckBox("Remove Artifacts");
|
||||
|
||||
// Variants
|
||||
private final List<FList<Object>> schemeDeckLists = new ArrayList<FList<Object>>();
|
||||
private final List<FPanel> schemeDeckPanels = new ArrayList<FPanel>(MAX_PLAYERS);
|
||||
private int lastArchenemy = 0;
|
||||
|
||||
private final List<FList<Object>> planarDeckLists = new ArrayList<FList<Object>>();
|
||||
private final List<FPanel> planarDeckPanels = new ArrayList<FPanel>(MAX_PLAYERS);
|
||||
|
||||
@@ -121,7 +129,6 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
|
||||
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<CSubmenuConstructed> {
|
||||
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<CSubmenuConstructed> {
|
||||
});
|
||||
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<Object> schemeDeckList = new FList<Object>();
|
||||
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<CSubmenuConstructed> {
|
||||
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<CSubmenuConstructed> {
|
||||
private FRadioButton radioHuman;
|
||||
private FRadioButton radioAi;
|
||||
|
||||
private FComboBoxWrapper<Object> teamComboBox = new FComboBoxWrapper<Object>();
|
||||
private FComboBoxWrapper<Object> aeTeamComboBox = new FComboBoxWrapper<Object>();
|
||||
|
||||
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<CSubmenuConstructed> {
|
||||
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<CSubmenuConstructed> {
|
||||
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<CSubmenuConstructed> {
|
||||
};
|
||||
|
||||
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<CSubmenuConstructed> {
|
||||
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<Object> cb = (FComboBox<Object>)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<PaperCard> predSchemes = new Predicate<PaperCard>() {
|
||||
@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<CSubmenuConstructed> {
|
||||
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<CSubmenuConstructed> {
|
||||
return newName;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//========== Various listeners in build order
|
||||
|
||||
private List<String> getPlayerNames() {
|
||||
List<String> names = new ArrayList<String>();
|
||||
for (PlayerPanel pp : playerPanels) {
|
||||
@@ -889,6 +1019,32 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
|
||||
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<Integer> 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<CSubmenuConstructed> {
|
||||
}
|
||||
|
||||
for (PlayerPanel pp : playerPanels) {
|
||||
pp.toggleIsPlayerArchenemy();
|
||||
pp.updateVariantControlsVisibility();
|
||||
}
|
||||
changePlayerFocus(playerWithFocus, currentGameMode);
|
||||
@@ -942,10 +1099,17 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
FComboBox<String> cb = (FComboBox<String>)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<CSubmenuConstructed> {
|
||||
}
|
||||
|
||||
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<CSubmenuConstructed> {
|
||||
return planarDeckLists;
|
||||
}
|
||||
|
||||
/** Gets the list of planar deck lists. */
|
||||
public List<FList<Object>> getSchemeDeckLists() {
|
||||
return schemeDeckLists;
|
||||
}
|
||||
|
||||
public boolean isPlayerArchenemy(final int playernum) {
|
||||
return playerPanels.get(playernum).playerIsArchenemy;
|
||||
}
|
||||
|
||||
/** Gets the list of Vanguard avatar lists. */
|
||||
public List<FList<Object>> getVanguardLists() {
|
||||
return vgdAvatarLists;
|
||||
@@ -1106,12 +1279,4 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
|
||||
vgdList.setSelectedIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
public String getPlayerName(int i) {
|
||||
return playerPanels.get(i).getPlayerName();
|
||||
}
|
||||
|
||||
public int getPlayerAvatar(int i) {
|
||||
return playerPanels.get(i).getAvatarIndex();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
|
||||
*
|
||||
*/
|
||||
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<Object> deckList = view.getArchenemySchemes();
|
||||
Vector<Object> listData = new Vector<Object>();
|
||||
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<PaperCard> predSchemes = new Predicate<PaperCard>() {
|
||||
@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<Deck> playerDecks = new ArrayList<Deck>();
|
||||
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<PaperCard> 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<RegisteredPlayer> players = new ArrayList<RegisteredPlayer>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
*
|
||||
* <br><br><i>(V at beginning of class name denotes a view class.)</i>
|
||||
*
|
||||
*/
|
||||
public enum VSubmenuArchenemy implements IVSubmenu<CSubmenuArchenemy> {
|
||||
/** */
|
||||
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<FPanel> playerPanels = new ArrayList<FPanel>();
|
||||
private final List<FDeckChooser> deckChoosers = new ArrayList<FDeckChooser>();
|
||||
private final FList<Object> archenemySchemes = new FList<Object>();
|
||||
private final List<Deck> allSchemeDecks = new ArrayList<Deck>();
|
||||
private final JCheckBox cbUseDefaultSchemes = new FCheckBox("Use default scheme decks if possible.");
|
||||
private final List<JRadioButton> playerIsAIRadios = new ArrayList<JRadioButton>();
|
||||
private final List<JRadioButton> fieldRadios = new ArrayList<JRadioButton>();
|
||||
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<FDeckChooser> 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<Object> getArchenemySchemes() {
|
||||
return archenemySchemes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the allSchemeDecks
|
||||
*/
|
||||
public List<Deck> getAllSchemeDecks() {
|
||||
return allSchemeDecks;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user