diff --git a/forge-game/src/main/java/forge/game/GameType.java b/forge-game/src/main/java/forge/game/GameType.java index 4cf55770c9c..27cbe965a5b 100644 --- a/forge-game/src/main/java/forge/game/GameType.java +++ b/forge-game/src/main/java/forge/game/GameType.java @@ -12,37 +12,38 @@ import forge.deck.Deck; import forge.deck.DeckFormat; import forge.deck.DeckSection; import forge.game.player.RegisteredPlayer; +import forge.util.Aggregates; import forge.util.Localizer; -import forge.util.MyRandom; public enum GameType { - Sealed (DeckFormat.Limited, true, true, true, "lblSealed", ""), - Draft (DeckFormat.Limited, true, true, true, "lblDraft", ""), - Winston (DeckFormat.Limited, true, true, true, "lblWinston", ""), - Gauntlet (DeckFormat.Constructed, false, true, true, "lblGauntlet", ""), - Tournament (DeckFormat.Constructed, false, true, true, "lblTournament", ""), - Quest (DeckFormat.QuestDeck, true, true, false, "lblQuest", ""), - QuestDraft (DeckFormat.Limited, true, true, true, "lblQuestDraft", ""), - PlanarConquest (DeckFormat.PlanarConquest, true, false, false, "lblPlanarConquest", ""), - Puzzle (DeckFormat.Puzzle, false, false, false, "lblPuzzle", "lblPuzzleDesc"), - Constructed (DeckFormat.Constructed, false, true, true, "lblConstructed", ""), - DeckManager (DeckFormat.Constructed, false, true, true, "lblDeckManager", ""), - Vanguard (DeckFormat.Vanguard, true, true, true, "lblVanguard", "lblVanguardDesc"), - Commander (DeckFormat.Commander, false, false, false, "lblCommander", "lblCommanderDesc"), - Oathbreaker (DeckFormat.Oathbreaker, false, false, false, "lblOathbreaker", "lblOathbreakerDesc"), - TinyLeaders (DeckFormat.TinyLeaders, false, false, false, "lblTinyLeaders", "lblTinyLeadersDesc"), - Brawl (DeckFormat.Brawl, false, false, false, "lblBrawl", "lblBrawlDesc"), - Planeswalker (DeckFormat.PlanarConquest, false, false, true, "lblPlaneswalker", "lblPlaneswalkerDesc"), - Planechase (DeckFormat.Planechase, false, false, true, "lblPlanechase", "lblPlanechaseDesc"), - Archenemy (DeckFormat.Archenemy, false, false, true, "lblArchenemy", "lblArchenemyDesc"), - ArchenemyRumble (DeckFormat.Archenemy, false, false, true, "lblArchenemyRumble", "lblArchenemyRumbleDesc"), - MomirBasic (DeckFormat.Constructed, false, false, false, "lblMomirBasic", "lblMomirBasicDesc", new Function() { + Sealed (DeckFormat.Limited, true, true, true, "lblSealed", ""), + Draft (DeckFormat.Limited, true, true, true, "lblDraft", ""), + Winston (DeckFormat.Limited, true, true, true, "lblWinston", ""), + Gauntlet (DeckFormat.Constructed, false, true, true, "lblGauntlet", ""), + Tournament (DeckFormat.Constructed, false, true, true, "lblTournament", ""), + CommanderGauntlet (DeckFormat.Commander, false, false, false, "lblCommander", "lblCommanderDesc"), + Quest (DeckFormat.QuestDeck, true, true, false, "lblQuest", ""), + QuestDraft (DeckFormat.Limited, true, true, true, "lblQuestDraft", ""), + PlanarConquest (DeckFormat.PlanarConquest, true, false, false, "lblPlanarConquest", ""), + Puzzle (DeckFormat.Puzzle, false, false, false, "lblPuzzle", "lblPuzzleDesc"), + Constructed (DeckFormat.Constructed, false, true, true, "lblConstructed", ""), + DeckManager (DeckFormat.Constructed, false, true, true, "lblDeckManager", ""), + Vanguard (DeckFormat.Vanguard, true, true, true, "lblVanguard", "lblVanguardDesc"), + Commander (DeckFormat.Commander, false, false, false, "lblCommander", "lblCommanderDesc"), + Oathbreaker (DeckFormat.Oathbreaker, false, false, false, "lblOathbreaker", "lblOathbreakerDesc"), + TinyLeaders (DeckFormat.TinyLeaders, false, false, false, "lblTinyLeaders", "lblTinyLeadersDesc"), + Brawl (DeckFormat.Brawl, false, false, false, "lblBrawl", "lblBrawlDesc"), + Planeswalker (DeckFormat.PlanarConquest, false, false, true, "lblPlaneswalker", "lblPlaneswalkerDesc"), + Planechase (DeckFormat.Planechase, false, false, true, "lblPlanechase", "lblPlanechaseDesc"), + Archenemy (DeckFormat.Archenemy, false, false, true, "lblArchenemy", "lblArchenemyDesc"), + ArchenemyRumble (DeckFormat.Archenemy, false, false, true, "lblArchenemyRumble", "lblArchenemyRumbleDesc"), + MomirBasic (DeckFormat.Constructed, false, false, false, "lblMomirBasic", "lblMomirBasicDesc", new Function() { @Override public Deck apply(RegisteredPlayer player) { Deck deck = new Deck(); CardPool mainDeck = deck.getMain(); - String setcode = StaticData.instance().getBlockLands().get(MyRandom.getRandom().nextInt(StaticData.instance().getBlockLands().size())); + String setcode = Aggregates.random(StaticData.instance().getBlockLands()); mainDeck.add("Plains", setcode, 12, true); mainDeck.add("Island", setcode, 12, true); mainDeck.add("Swamp", setcode, 12, true); @@ -58,7 +59,7 @@ public enum GameType { public Deck apply(RegisteredPlayer player) { Deck deck = new Deck(); CardPool mainDeck = deck.getMain(); - String setcode = StaticData.instance().getBlockLands().get(MyRandom.getRandom().nextInt(StaticData.instance().getBlockLands().size())); + String setcode = Aggregates.random(StaticData.instance().getBlockLands()); mainDeck.add("Plains", setcode, 12, true); mainDeck.add("Island", setcode, 12, true); mainDeck.add("Swamp", setcode, 12, true); diff --git a/forge-gui-desktop/src/main/java/forge/gui/framework/EDocID.java b/forge-gui-desktop/src/main/java/forge/gui/framework/EDocID.java index ccad5aa532e..203f30d3204 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/framework/EDocID.java +++ b/forge-gui-desktop/src/main/java/forge/gui/framework/EDocID.java @@ -15,10 +15,7 @@ import forge.screens.deckeditor.views.VOathbreakerDecks; import forge.screens.deckeditor.views.VProbabilities; import forge.screens.deckeditor.views.VStatistics; import forge.screens.deckeditor.views.VTinyLeadersDecks; -import forge.screens.home.gauntlet.VSubmenuGauntletBuild; -import forge.screens.home.gauntlet.VSubmenuGauntletContests; -import forge.screens.home.gauntlet.VSubmenuGauntletLoad; -import forge.screens.home.gauntlet.VSubmenuGauntletQuick; +import forge.screens.home.gauntlet.*; import forge.screens.home.online.VSubmenuOnlineLobby; import forge.screens.home.puzzle.VSubmenuPuzzleCreate; import forge.screens.home.puzzle.VSubmenuPuzzleSolve; @@ -79,6 +76,7 @@ public enum EDocID { HOME_GAUNTLETBUILD (VSubmenuGauntletBuild.SINGLETON_INSTANCE), HOME_GAUNTLETLOAD (VSubmenuGauntletLoad.SINGLETON_INSTANCE), HOME_GAUNTLETQUICK (VSubmenuGauntletQuick.SINGLETON_INSTANCE), + HOME_GAUNTLETCOMMANDER (VSubmenuGauntletCommander.SINGLETON_INSTANCE), HOME_GAUNTLETCONTESTS (VSubmenuGauntletContests.SINGLETON_INSTANCE), HOME_PREFERENCES (VSubmenuPreferences.SINGLETON_INSTANCE), HOME_ACHIEVEMENTS (VSubmenuAchievements.SINGLETON_INSTANCE), diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/DeckController.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/DeckController.java index 8d0dff2db7c..25935826c98 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/DeckController.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/DeckController.java @@ -25,6 +25,7 @@ import forge.item.PaperCard; import forge.screens.deckeditor.menus.DeckFileMenu; import forge.screens.deckeditor.views.VCurrentDeck; import forge.screens.home.gauntlet.VSubmenuGauntletBuild; +import forge.screens.home.gauntlet.VSubmenuGauntletCommander; import forge.screens.home.gauntlet.VSubmenuGauntletContests; import forge.screens.home.gauntlet.VSubmenuGauntletQuick; import forge.screens.home.sanctioned.VSubmenuConstructed; @@ -90,6 +91,8 @@ public class DeckController { this.loadDeck(deck, true); } public void loadDeck(Deck deck, boolean substituteCurrentDeck) { + if (deck == null) + return; boolean isStored; boolean isInfinite = view.getCatalogManager().isInfinite(); @@ -355,6 +358,7 @@ public class DeckController { VSubmenuGauntletBuild.SINGLETON_INSTANCE.updateDeckPanel(); VSubmenuGauntletQuick.SINGLETON_INSTANCE.updateDeckPanel(); VSubmenuGauntletContests.SINGLETON_INSTANCE.updateDeckPanel(); + VSubmenuGauntletCommander.SINGLETON_INSTANCE.updateDeckPanel(); } /** diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/VHomeUI.java b/forge-gui-desktop/src/main/java/forge/screens/home/VHomeUI.java index 27a15dc17ea..9e6546d6846 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/VHomeUI.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/VHomeUI.java @@ -41,10 +41,7 @@ import forge.gui.framework.IVTopLevelUI; import forge.localinstance.properties.ForgePreferences.FPref; import forge.localinstance.skin.FSkinProp; import forge.model.FModel; -import forge.screens.home.gauntlet.VSubmenuGauntletBuild; -import forge.screens.home.gauntlet.VSubmenuGauntletContests; -import forge.screens.home.gauntlet.VSubmenuGauntletLoad; -import forge.screens.home.gauntlet.VSubmenuGauntletQuick; +import forge.screens.home.gauntlet.*; import forge.screens.home.online.VSubmenuOnlineLobby; import forge.screens.home.puzzle.VSubmenuPuzzleCreate; import forge.screens.home.puzzle.VSubmenuPuzzleSolve; @@ -136,6 +133,7 @@ public enum VHomeUI implements IVTopLevelUI { allSubmenus.add(VSubmenuGauntletBuild.SINGLETON_INSTANCE); allSubmenus.add(VSubmenuGauntletLoad.SINGLETON_INSTANCE); allSubmenus.add(VSubmenuGauntletContests.SINGLETON_INSTANCE); + allSubmenus.add(VSubmenuGauntletCommander.SINGLETON_INSTANCE); allSubmenus.add(VSubmenuPuzzleSolve.SINGLETON_INSTANCE); allSubmenus.add(VSubmenuPuzzleCreate.SINGLETON_INSTANCE); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletCommander.java b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletCommander.java new file mode 100644 index 00000000000..1a9f03a63b0 --- /dev/null +++ b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletCommander.java @@ -0,0 +1,98 @@ +package forge.screens.home.gauntlet; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.SwingUtilities; + +import forge.deck.DeckType; +import forge.game.player.RegisteredPlayer; +import forge.gamemodes.gauntlet.GauntletData; +import forge.gamemodes.gauntlet.GauntletUtil; +import forge.gui.SOverlayUtils; +import forge.gui.framework.ICDoc; +import forge.player.GamePlayerUtil; + +/** + * Controls the "commander gauntlet" submenu in the home UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ + +public enum CSubmenuGauntletCommander implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + private final ActionListener actStartGame = new ActionListener() { + @Override public void actionPerformed(final ActionEvent arg0) { + startGame(); + } + }; + + private final VSubmenuGauntletCommander view = VSubmenuGauntletCommander.SINGLETON_INSTANCE; + + /* (non-Javadoc) + * @see forge.gui.home.ICSubmenu#initialize() + */ + @Override + public void update() { + SwingUtilities.invokeLater(new Runnable() { + @Override public void run() { view.getBtnStart().requestFocusInWindow(); } + }); + } + + @Override + public void register() { + } + + /* (non-Javadoc) + * @see forge.gui.home.ICSubmenu#initialize() + */ + @Override + public void initialize() { + view.getBtnStart().addActionListener(actStartGame); + view.getLstDecks().initialize(DeckType.COMMANDER_DECK); + } + + private void startGame() { + final RegisteredPlayer player = view.getLstDecks().getPlayer(); + if (player == null) { // no deck selected + return; + } + + // Start game overlay + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + SOverlayUtils.startGameOverlay(); + SOverlayUtils.showOverlay(); + } + }); + + // Find appropriate filename for new save, create and set new save file. + final List allowedDeckTypes = new ArrayList<>(); + if (view.getBoxRandomCommanderDecks().isSelected()) { allowedDeckTypes.add(DeckType.RANDOM_COMMANDER_DECK); } + if (view.getBoxPreconCommanderDecks().isSelected()) { allowedDeckTypes.add(DeckType.PRECON_COMMANDER_DECK); } + if (view.getBoxCommanderDecks().isSelected()) { allowedDeckTypes.add(DeckType.COMMANDER_DECK); } + + final GauntletData gd = GauntletUtil.createCommanderGauntlet(player.getDeck(), view.getSliOpponents().getValue(), allowedDeckTypes, null); + + final List starter = new ArrayList<>(); + final RegisteredPlayer human = RegisteredPlayer.forCommander(player.getDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()); + starter.add(human); + starter.add(RegisteredPlayer.forCommander(gd.getDecks().get(gd.getCompleted())).setPlayer(GamePlayerUtil.createAiPlayer())); + + gd.startRound(starter, human); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + SOverlayUtils.hideOverlay(); + } + }); + } + +} diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletLoad.java b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletLoad.java index 317555851a8..fa4c46814a4 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletLoad.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletLoad.java @@ -122,7 +122,8 @@ public enum CSubmenuGauntletLoad implements ICDoc { Deck userDeck = gd.getUserDeck(); if (userDeck == null) { //give user a chance to select a deck if none saved with gauntlet - userDeck = FDeckChooser.promptForDeck(null, "Select a deck to play for this gauntlet", DeckType.CUSTOM_DECK, false); + userDeck = FDeckChooser.promptForDeck(null, "Select a deck to play for this gauntlet", gd.isCommanderGauntlet() + ? DeckType.COMMANDER_DECK : DeckType.CUSTOM_DECK, false); if (userDeck == null) { return; } //prevent crash if user doesn't select a deck gd.setUserDeck(userDeck); GauntletIO.saveGauntlet(gd); @@ -139,9 +140,13 @@ public enum CSubmenuGauntletLoad implements ICDoc { }); final List starter = new ArrayList<>(); - final RegisteredPlayer human = new RegisteredPlayer(userDeck).setPlayer(GamePlayerUtil.getGuiPlayer()); + final RegisteredPlayer human = gd.isCommanderGauntlet() + ? RegisteredPlayer.forCommander(userDeck).setPlayer(GamePlayerUtil.getGuiPlayer()) + : new RegisteredPlayer(userDeck).setPlayer(GamePlayerUtil.getGuiPlayer()); starter.add(human); - starter.add(new RegisteredPlayer(aiDeck).setPlayer(GamePlayerUtil.createAiPlayer())); + starter.add(gd.isCommanderGauntlet() + ? RegisteredPlayer.forCommander(aiDeck).setPlayer(GamePlayerUtil.createAiPlayer()) + : new RegisteredPlayer(aiDeck).setPlayer(GamePlayerUtil.createAiPlayer())); gd.startRound(starter, human); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/VSubmenuGauntletCommander.java b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/VSubmenuGauntletCommander.java new file mode 100644 index 00000000000..d1272b9daa7 --- /dev/null +++ b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/VSubmenuGauntletCommander.java @@ -0,0 +1,221 @@ +package forge.screens.home.gauntlet; + +import java.awt.Font; + +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JSlider; +import javax.swing.SwingConstants; + +import forge.deck.DeckType; +import forge.deckchooser.FDeckChooser; +import forge.game.GameType; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.screens.home.EMenuGroup; +import forge.screens.home.IVSubmenu; +import forge.screens.home.StartButton; +import forge.screens.home.VHomeUI; +import forge.toolbox.FCheckBox; +import forge.toolbox.FLabel; +import forge.toolbox.FPanel; +import forge.toolbox.FSkin; +import forge.toolbox.FSkin.SkinnedSlider; +import forge.util.Localizer; +import net.miginfocom.swing.MigLayout; + +/** + * Assembles Swing components of "commander gauntlet" submenu singleton. + * + *

(V at beginning of class name denotes a view class.) + * + */ +public enum VSubmenuGauntletCommander implements IVSubmenu { + /** */ + SINGLETON_INSTANCE; + final Localizer localizer = Localizer.getInstance(); + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab(localizer.getMessage("lblCommanderGauntlet")); + + // Other fields + private final FPanel pnlOptions = new FPanel(new MigLayout("insets 0, gap 0, wrap")); + private final FLabel lblTitle = new FLabel.Builder() + .text(localizer.getMessage("lblCommanderGauntletBuilder")).fontAlign(SwingConstants.CENTER) + .opaque(true).fontSize(16).build(); + + private final FLabel lblDecklist = new FLabel.Builder() + .text(localizer.getMessage("lblDecklist")) + .fontSize(12).build(); + + private final SkinnedSlider sliOpponents = new SkinnedSlider(SwingConstants.HORIZONTAL, 5, 50, 20); + //private SkinnedSlider sliGamesPerMatch = new SkinnedSlider(JSlider.HORIZONTAL, 1, 7, 3); + + private final JCheckBox boxRandomCommanderDecks = new FCheckBox(DeckType.RANDOM_COMMANDER_DECK.toString()); + private final JCheckBox boxPreconCommanderDecks = new FCheckBox(DeckType.PRECON_COMMANDER_DECK.toString()); + private final JCheckBox boxCommanderDecks = new FCheckBox(DeckType.COMMANDER_DECK.toString()); + + private final FDeckChooser lstDecks = new FDeckChooser(null, false, GameType.CommanderGauntlet, true); + + private final FLabel lblOptions = new FLabel.Builder().fontSize(16) + .fontStyle(Font.BOLD).text(localizer.getMessage("lblOptions")).fontAlign(SwingConstants.CENTER).build(); + + private final FLabel lblDesc1 = new FLabel.Builder() + .text(localizer.getMessage("lblMatchesperGauntlet")).fontStyle(Font.ITALIC).build(); + + private final FLabel lblDesc3 = new FLabel.Builder() + .text(localizer.getMessage("lblAllowedDeckTypes")).fontStyle(Font.ITALIC).build(); + + private final FLabel lblDesc = new FLabel.Builder().text(localizer.getMessage("lblAutosaveInf")).fontSize(12).build(); + + private final StartButton btnStart = new StartButton(); + + VSubmenuGauntletCommander() { + lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + + boxRandomCommanderDecks.setSelected(true); + boxPreconCommanderDecks.setSelected(true); + boxCommanderDecks.setSelected(true); + + sliOpponents.setMajorTickSpacing(5); + sliOpponents.setMinorTickSpacing(0); + sliOpponents.setPaintTicks(false); + sliOpponents.setPaintLabels(true); + sliOpponents.setSnapToTicks(true); + sliOpponents.setOpaque(false); + sliOpponents.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT)); + sliOpponents.setFont(FSkin.getFont()); + + pnlOptions.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + pnlOptions.add(lblOptions, "h 30px!, w 96%!, gap 2% 0 0 5px"); + pnlOptions.add(sliOpponents, "h 40px!, w 96%!, gap 2% 0 0 5px, ax center"); + pnlOptions.add(lblDesc1, "w 96%!, gap 2% 0 0 20px"); + pnlOptions.add(lblDesc3, "w 96%!, gap 2% 0 0 0"); + pnlOptions.setCornerDiameter(0); + pnlOptions.add(boxRandomCommanderDecks, "w 96%!, h 30px!, gap 2% 0 0 5px"); + pnlOptions.add(boxPreconCommanderDecks, "w 96%!, h 30px!, gap 2% 0 0 5px"); + pnlOptions.add(boxCommanderDecks, "w 96%!, h 30px!, gap 2% 0 0 5px"); + } + + public void updateDeckPanel() { + lstDecks.restoreSavedState(); + } + + /* (non-Javadoc) + * @see forge.gui.home.IVSubmenu#getGroupEnum() + */ + @Override + public EMenuGroup getGroupEnum() { + return EMenuGroup.GAUNTLET; + } + + /* (non-Javadoc) + * @see forge.gui.home.IVSubmenu#getMenuTitle() + */ + @Override + public String getMenuTitle() { + return localizer.getMessage("lblCommanderGauntlet"); + } + + /* (non-Javadoc) + * @see forge.gui.home.IVSubmenu#getItemEnum() + */ + @Override + public EDocID getItemEnum() { + return EDocID.HOME_GAUNTLETCOMMANDER; + } + + /* (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 2")); + + VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(lblTitle, "w 98%!, h 30px!, gap 1% 0 15px 15px, span 2"); + VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(lblDesc, "ax center, gap 0 0 0 5px, span 2"); + VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(lblDecklist, "ax center, gap 0 0 0 15px, span 2"); + VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(pnlOptions, "w 40%!, gap 1% 1% 0 0, pushy, growy"); + VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(lstDecks, "w 57%!, pushy, growy"); + VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(btnStart, "w 98%!, ax center, gap 1% 0 20px 20px, span 2"); + + getLstDecks().populate(); + + VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().repaintSelf(); + VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().revalidate(); + } + + /** @return {@link javax.swing.JList} */ + public FDeckChooser getLstDecks() { + return this.lstDecks; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getBoxRandomCommanderDecks() { + return boxRandomCommanderDecks; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getBoxPreconCommanderDecks() { + return boxPreconCommanderDecks; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getBoxCommanderDecks() { + return boxCommanderDecks; + } + + /** @return {@link javax.swing.JSlider} */ + public JSlider getSliOpponents() { + return this.sliOpponents; + } + + /** @return {@link javax.swing.JButton} */ + public JButton getBtnStart() { + return this.btnStart; + } + + //========== Overridden from IVDoc + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.HOME_GAUNTLETCOMMANDER; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getLayoutControl() + */ + @Override + public CSubmenuGauntletCommander getLayoutControl() { + return CSubmenuGauntletCommander.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; + } +} diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/ViewWinLose.java b/forge-gui-desktop/src/main/java/forge/screens/match/ViewWinLose.java index ac0575a48e8..596e3405f11 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/ViewWinLose.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/ViewWinLose.java @@ -49,7 +49,9 @@ public class ViewWinLose implements IWinLoseView { private final SkinnedLabel lblStats = new SkinnedLabel("WinLoseFrame > lblStats needs updating."); private final JPanel pnlOutcomes = new JPanel(new MigLayout("wrap, ax center, ay center")); - /** String constraint parameters for title blocks and cardviewer blocks. */ + /** + * String constraint parameters for title blocks and cardviewer blocks. + */ private static final SkinColor FORE_COLOR = FSkin.getColor(Colors.CLR_TEXT); private static final String CONSTRAINTS_TITLE = "w 95%!, gap 0 0 20px 10px"; private static final String CONSTRAINTS_TEXT = "w 95%!, h 220px!, gap 0 0 0 20px"; @@ -77,25 +79,26 @@ public class ViewWinLose implements IWinLoseView { // modes. ControlWinLose control = null; switch (game0.getGameType()) { - case Quest: - control = new QuestWinLose(this, game0, matchUI); - break; - case QuestDraft: - control = new QuestDraftWinLose(this, game0, matchUI); - break; - case Draft: - if (!FModel.getGauntletMini().isGauntletDraft()) { + case Quest: + control = new QuestWinLose(this, game0, matchUI); + break; + case QuestDraft: + control = new QuestDraftWinLose(this, game0, matchUI); + break; + case Draft: + if (!FModel.getGauntletMini().isGauntletDraft()) { + break; + } + //$FALL-THROUGH$ + case Sealed: + control = new LimitedWinLose(this, game0, matchUI); + break; + case CommanderGauntlet: + case Gauntlet: + control = new GauntletWinLose(this, game0, matchUI); + break; + default: // will catch it after switch break; - } - //$FALL-THROUGH$ - case Sealed: - control = new LimitedWinLose(this, game0, matchUI); - break; - case Gauntlet: - control = new GauntletWinLose(this, game0, matchUI); - break; - default: // will catch it after switch - break; } if (null == control) { control = new ControlWinLose(this, game0, matchUI); @@ -179,7 +182,7 @@ public class ViewWinLose implements IWinLoseView { pnlLog.add( new FLabel.Builder().text(localizer.getMessage("lblGameLog")).fontAlign(SwingConstants.CENTER).fontSize(18) - .fontStyle(Font.BOLD).build(), "w 300px!, h 28px!, gaptop 20px"); + .fontStyle(Font.BOLD).build(), "w 300px!, h 28px!, gaptop 20px"); pnlLog.add(scrLog, "w 300px!, h 100px!, gap 0 0 10 10"); pnlLog.add(btnCopyLog, "center, w pref+16, h pref+8"); @@ -224,25 +227,33 @@ public class ViewWinLose implements IWinLoseView { } } - /** @return {@link forge.toolbox.FButton} */ + /** + * @return {@link forge.toolbox.FButton} + */ @Override public FButton getBtnContinue() { return this.btnContinue; } - /** @return {@link forge.toolbox.FButton} */ + /** + * @return {@link forge.toolbox.FButton} + */ @Override public FButton getBtnRestart() { return this.btnRestart; } - /** @return {@link forge.toolbox.FButton} */ + /** + * @return {@link forge.toolbox.FButton} + */ @Override public FButton getBtnQuit() { return this.btnQuit; } - /** @return {@link javax.swing.JPanel} */ + /** + * @return {@link javax.swing.JPanel} + */ public SkinnedPanel getPnlCustom() { return this.pnlCustom; } @@ -279,8 +290,7 @@ public class ViewWinLose implements IWinLoseView { getPnlCustom().add(new TitleLabel(title), CONSTRAINTS_TITLE); if (FModel.getPreferences().getPrefBoolean(FPref.UI_LARGE_CARD_VIEWERS)) { getPnlCustom().add(cv, CONSTRAINTS_CARDS_LARGE); - } - else { + } else { getPnlCustom().add(cv, CONSTRAINTS_CARDS); } } diff --git a/forge-gui-mobile/src/forge/screens/gauntlet/LoadGauntletScreen.java b/forge-gui-mobile/src/forge/screens/gauntlet/LoadGauntletScreen.java index e8dc7a078ca..38c8a380bac 100644 --- a/forge-gui-mobile/src/forge/screens/gauntlet/LoadGauntletScreen.java +++ b/forge-gui-mobile/src/forge/screens/gauntlet/LoadGauntletScreen.java @@ -106,7 +106,8 @@ public class LoadGauntletScreen extends LaunchScreen { Deck userDeck = gauntlet.getUserDeck(); if (userDeck == null) { //give user a chance to select a deck if none saved with gauntlet - FDeckChooser.promptForDeck(Forge.getLocalizer().getMessage("lblSelectGauntletDeck"), GameType.Gauntlet, false, new Callback() { + FDeckChooser.promptForDeck(Forge.getLocalizer().getMessage("lblSelectGauntletDeck"), gauntlet.isCommanderGauntlet() + ? GameType.CommanderGauntlet : GameType.Gauntlet, false, new Callback() { @Override public void run(Deck result) { if (result != null) { @@ -121,9 +122,13 @@ public class LoadGauntletScreen extends LaunchScreen { LoadingOverlay.show(Forge.getLocalizer().getMessage("lblLoadingNewGame"), true, () -> { final GauntletData gauntlet1 = FModel.getGauntletData(); List players = new ArrayList<>(); - RegisteredPlayer humanPlayer = new RegisteredPlayer(gauntlet1.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()); + RegisteredPlayer humanPlayer = gauntlet1.isCommanderGauntlet() + ? RegisteredPlayer.forCommander(gauntlet1.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()) + : new RegisteredPlayer(gauntlet1.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()); players.add(humanPlayer); - players.add(new RegisteredPlayer(gauntlet1.getDecks().get(gauntlet1.getCompleted())).setPlayer(GamePlayerUtil.createAiPlayer())); + players.add(gauntlet1.isCommanderGauntlet() + ? RegisteredPlayer.forCommander(gauntlet1.getDecks().get(gauntlet1.getCompleted())).setPlayer(GamePlayerUtil.createAiPlayer()) + : new RegisteredPlayer(gauntlet1.getDecks().get(gauntlet1.getCompleted())).setPlayer(GamePlayerUtil.createAiPlayer())); gauntlet1.startRound(players, humanPlayer); }); } diff --git a/forge-gui-mobile/src/forge/screens/gauntlet/NewGauntletScreen.java b/forge-gui-mobile/src/forge/screens/gauntlet/NewGauntletScreen.java index f996ef6e541..4d482fcba7a 100644 --- a/forge-gui-mobile/src/forge/screens/gauntlet/NewGauntletScreen.java +++ b/forge-gui-mobile/src/forge/screens/gauntlet/NewGauntletScreen.java @@ -56,6 +56,7 @@ public class NewGauntletScreen extends LaunchScreen { Forge.getLocalizer().getMessage("lblQuickGauntlet"), Forge.getLocalizer().getMessage("lblCustomGauntlet"), Forge.getLocalizer().getMessage("lblGauntletContest"), + Forge.getLocalizer().getMessage("lblCommanderGauntlet"), }, new Callback() { @Override public void run(String result) { @@ -65,6 +66,8 @@ public class NewGauntletScreen extends LaunchScreen { createQuickGauntlet(); } else if(Forge.getLocalizer().getMessage("lblCustomGauntlet").equals(result)) { createCustomGauntlet(); + } else if(Forge.getLocalizer().getMessage("lblCommanderGauntlet").equals(result)) { + createCommandGauntlet(); } else { createGauntletContest(); } @@ -72,6 +75,40 @@ public class NewGauntletScreen extends LaunchScreen { }); } + private void createCommandGauntlet() { + GuiChoose.getInteger(Forge.getLocalizer().getMessage("lblHowManyOpponents"), 3, 50, new Callback() { + @Override + public void run(final Integer numOpponents) { + if (numOpponents == null) { return; } + + ListChooser chooser = new ListChooser<>( + Forge.getLocalizer().getMessage("lblChooseAllowedDeckTypeOpponents"), 0, 11, Arrays.asList(DeckType.COMMANDER_DECK, + DeckType.PRECON_COMMANDER_DECK, + DeckType.RANDOM_COMMANDER_DECK), null, new Callback>() { + @Override + public void run(final List allowedDeckTypes) { + if (allowedDeckTypes == null || allowedDeckTypes.isEmpty()) { + return; + } + + FDeckChooser.promptForDeck(Forge.getLocalizer().getMessage("lblSelectYourDeck"), GameType.Commander, false, new Callback() { + @Override + public void run(Deck userDeck) { + if (userDeck == null) { + return; + } + + GauntletData gauntlet = GauntletUtil.createCommanderGauntlet(userDeck, numOpponents, allowedDeckTypes, null); + launchGauntlet(gauntlet); + } + }); + } + }); + chooser.show(null, false); /*setting selectMax to true will select all available option*/ + } + }); + } + private void createQuickGauntlet() { GuiChoose.getInteger(Forge.getLocalizer().getMessage("lblHowManyOpponents"), 3, 50, new Callback() { @Override @@ -196,11 +233,16 @@ public class NewGauntletScreen extends LaunchScreen { if (gauntlet == null) { return; } FModel.setGauntletData(gauntlet); gauntlet.reset(); - - RegisteredPlayer humanPlayer = new RegisteredPlayer(gauntlet.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()); List players = new ArrayList<>(); + RegisteredPlayer humanPlayer; + if (gauntlet.isCommanderGauntlet()) { + humanPlayer = RegisteredPlayer.forCommander(gauntlet.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()); + players.add(RegisteredPlayer.forCommander(gauntlet.getDecks().get(gauntlet.getCompleted())).setPlayer(GamePlayerUtil.createAiPlayer())); + } else { + humanPlayer = new RegisteredPlayer(gauntlet.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()); + players.add(new RegisteredPlayer(gauntlet.getDecks().get(gauntlet.getCompleted())).setPlayer(GamePlayerUtil.createAiPlayer())); + } players.add(humanPlayer); - players.add(new RegisteredPlayer(gauntlet.getDecks().get(gauntlet.getCompleted())).setPlayer(GamePlayerUtil.createAiPlayer())); gauntlet.startRound(players, humanPlayer); } } diff --git a/forge-gui-mobile/src/forge/screens/match/winlose/ViewWinLose.java b/forge-gui-mobile/src/forge/screens/match/winlose/ViewWinLose.java index 600631e2ae5..5d7cc6b1fa8 100644 --- a/forge-gui-mobile/src/forge/screens/match/winlose/ViewWinLose.java +++ b/forge-gui-mobile/src/forge/screens/match/winlose/ViewWinLose.java @@ -77,6 +77,7 @@ public class ViewWinLose extends FOverlay implements IWinLoseView { control = new LimitedWinLose(this, game0); break; case Gauntlet: + case CommanderGauntlet: case DeckManager: control = new GauntletWinLose(this, game0); break; diff --git a/forge-gui/res/languages/de-DE.properties b/forge-gui/res/languages/de-DE.properties index e08503cc49b..d5bd781d0c2 100644 --- a/forge-gui/res/languages/de-DE.properties +++ b/forge-gui/res/languages/de-DE.properties @@ -1446,6 +1446,8 @@ lblGauntletText2=Wähle die Anzahl der Gegner und welche Art Deck sie spielen so lblGauntletText3=Dann versuche alle Gegner zu besiegen ohne auch nur ein Spiel zu verlieren. lblSelectGauntletType=Wähle die Art des Spießrutenlaufs lblCustomGauntlet=angepaßter Spießrutenlauf +lblCommanderGauntlet=Generäle Spießrutenlauf +lblCommanderGauntletBuilder=Generäle Spießrutenlauf Erbauer lblGauntletContest=Wettbewerb lblSelectYourDeck=Wähle dein Deck lblSelectDeckForOpponent=Wähle Deck für Gegner diff --git a/forge-gui/res/languages/en-US.properties b/forge-gui/res/languages/en-US.properties index dcad4e7b7b4..47ca3f71d12 100644 --- a/forge-gui/res/languages/en-US.properties +++ b/forge-gui/res/languages/en-US.properties @@ -1451,6 +1451,8 @@ lblGauntletText2=Configure how many opponents you wish to face and what decks or lblGauntletText3=Then, try to beat all AI opponents without losing a match. lblSelectGauntletType=Select a Gauntlet Type lblCustomGauntlet=Custom Gauntlet +lblCommanderGauntlet=Commander Gauntlet +lblCommanderGauntletBuilder=Commander Gauntlet Builder lblGauntletContest=Gauntlet Contest lblSelectYourDeck=Select Your Deck lblSelectDeckForOpponent=Select Deck for Opponent diff --git a/forge-gui/res/languages/es-ES.properties b/forge-gui/res/languages/es-ES.properties index 676a9b3e567..b270df20c78 100644 --- a/forge-gui/res/languages/es-ES.properties +++ b/forge-gui/res/languages/es-ES.properties @@ -1447,6 +1447,8 @@ lblGauntletText2=Configura a cuántos oponentes quieres enfrentarte y qué mazos lblGauntletText3=Luego, intenta derrotar a todos los oponentes de la IA sin perder una partida. lblSelectGauntletType=Selecciona el tipo de desafío lblCustomGauntlet=Desafío personalizado +lblCommanderGauntlet=Comandante de desafío +lblCommanderGauntletBuilder=Constructor de desafío comandante lblGauntletContest=Concurso de desafío lblSelectYourDeck=Seleccciona tu mazo lblSelectDeckForOpponent=Seleccionar mazo para el oponente diff --git a/forge-gui/res/languages/fr-FR.properties b/forge-gui/res/languages/fr-FR.properties index b305516cac3..4355593455e 100644 --- a/forge-gui/res/languages/fr-FR.properties +++ b/forge-gui/res/languages/fr-FR.properties @@ -1448,6 +1448,8 @@ lblGauntletText2=Configurez le nombre d''adversaires que vous souhaitez affronte lblGauntletText3=Ensuite, essayez de battre tous les adversaires IA sans perdre de match. lblSelectGauntletType=Sélectionner un type de gantelet lblCustomGauntlet=Gantelet personnalisé +lblCommanderGauntlet=Commandant Gantelet +lblCommanderGauntletBuilder=Commandant Gantelet Constructeur lblGauntletContest=Concours de gant lblSelectYourDeck=Sélectionnez votre deck lblSelectDeckForOpponent=Sélectionner le deck pour l''adversaire diff --git a/forge-gui/res/languages/it-IT.properties b/forge-gui/res/languages/it-IT.properties index 4b72506fbee..790b12a34bd 100644 --- a/forge-gui/res/languages/it-IT.properties +++ b/forge-gui/res/languages/it-IT.properties @@ -1447,6 +1447,8 @@ lblGauntletText2=Configura quanti avversari vuoi affrontare e quali mazzi o tipi lblGauntletText3=Quindi, prova a battere tutti gli avversari IA senza perdere una partita. lblSelectGauntletType=Seleziona un tipo di sfida lblCustomGauntlet=Sfida personalizzata +lblCommanderGauntlet=Commander Sfida +lblCommanderGauntletBuilder=Commander Sfida Costruttore lblGauntletContest=Competizione delle sfide lblSelectYourDeck=Seleziona il tuo mazzo lblSelectDeckForOpponent=Seleziona il mazzo per l''avversario diff --git a/forge-gui/res/languages/ja-JP.properties b/forge-gui/res/languages/ja-JP.properties index 343d2216176..5434d87af69 100644 --- a/forge-gui/res/languages/ja-JP.properties +++ b/forge-gui/res/languages/ja-JP.properties @@ -1448,6 +1448,8 @@ lblGauntletText2=対戦したい対戦相手の数と、対戦相手のデッキ lblGauntletText3=次に、試合に負けずにすべての AI 対戦相手を倒すようにしてください。 lblSelectGauntletType=ガントレットタイプを選択 lblCustomGauntlet=カスタムガントレット +lblCommanderGauntlet=司令官ガントレット +lblCommanderGauntletBuilder=司令官ガントレットビルダー lblGauntletContest=ガントレットコンテスト lblSelectYourDeck=デッキを選択 lblSelectDeckForOpponent=相手のデッキを選択 diff --git a/forge-gui/res/languages/pt-BR.properties b/forge-gui/res/languages/pt-BR.properties index a3a3554104f..e44c580df34 100644 --- a/forge-gui/res/languages/pt-BR.properties +++ b/forge-gui/res/languages/pt-BR.properties @@ -1483,6 +1483,8 @@ lblGauntletText2=Configure quantos adversários você deseja encarar e quais dec lblGauntletText3=Então, tente vencer todos os adversários IA sem perder uma partida. lblSelectGauntletType=Escolha o Tipo de Desafio lblCustomGauntlet=Desafio Personalizado +lblCommanderGauntlet=Comandante Desafio +lblCommanderGauntletBuilder=Comandante Desafio Construtor lblGauntletContest=Campeonato Desafio lblSelectYourDeck=Escolha seu Deck lblSelectDeckForOpponent=Escolha o Deck do Adversário diff --git a/forge-gui/res/languages/zh-CN.properties b/forge-gui/res/languages/zh-CN.properties index 4587d96a58a..58715feb978 100644 --- a/forge-gui/res/languages/zh-CN.properties +++ b/forge-gui/res/languages/zh-CN.properties @@ -1449,6 +1449,8 @@ lblGauntletText2=设置你想面对的对手数量以及他们所使用的套牌 lblGauntletText3=然后,尝试击败所有AI对手而不输掉一场比赛。 lblSelectGauntletType=选择一个决斗类型 lblCustomGauntlet=自定义决斗 +lblCommanderGauntlet=决斗指挥官 +lblCommanderGauntletBuilder=决斗指挥官建筑商 lblGauntletContest=决斗竞赛 lblSelectYourDeck=选择你的套牌 lblSelectDeckForOpponent=选择对手的套牌 diff --git a/forge-gui/src/main/java/forge/deck/DeckgenUtil.java b/forge-gui/src/main/java/forge/deck/DeckgenUtil.java index dea7566b239..bab4f9c9cb4 100644 --- a/forge-gui/src/main/java/forge/deck/DeckgenUtil.java +++ b/forge-gui/src/main/java/forge/deck/DeckgenUtil.java @@ -432,6 +432,16 @@ public class DeckgenUtil { return allDecks.get(name); } + /** @return {@link forge.deck.Deck} */ + public static Deck getCommanderDeck() { + final IStorage allDecks = FModel.getDecks().getCommander(); + // in case user has not created any yet + if (allDecks.size() == 0) { return null; } + final int rand = (int) (Math.floor(MyRandom.getRandom().nextDouble() * allDecks.size())); + final String name = allDecks.getItemNames().toArray(new String[0])[rand]; + return allDecks.get(name); + } + /** @return {@link forge.deck.Deck} */ public static Deck getRandomOrPreconOrThemeDeck(String colors, boolean forAi, boolean isTheme, boolean useGeneticAI) { final List selection = new ArrayList<>(); @@ -494,6 +504,12 @@ public class DeckgenUtil { return allDecks.get(rand).getDeck(); } + /** @return {@link forge.deck.Deck} */ + public static Deck getRandomCommanderPreconDeck() { + final Iterable allDecks = DeckProxy.getAllCommanderPreconDecks(); + return Aggregates.random(allDecks).getDeck(); + } + /** @return {@link forge.deck.Deck} */ public static Deck getRandomThemeDeck() { final List allDecks = DeckProxy.getAllThemeDecks(); diff --git a/forge-gui/src/main/java/forge/deck/RandomDeckGenerator.java b/forge-gui/src/main/java/forge/deck/RandomDeckGenerator.java index 7ef275ebded..68d7035dd4a 100644 --- a/forge-gui/src/main/java/forge/deck/RandomDeckGenerator.java +++ b/forge-gui/src/main/java/forge/deck/RandomDeckGenerator.java @@ -65,75 +65,76 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable colors = new ArrayList<>(); - int count = Aggregates.randomInt(1, 3); - for (int i = 1; i <= count; i++) { - colors.add("Random " + i); + case CommanderGauntlet: + case Commander: + return DeckgenUtil.generateCommanderDeck(isAi, GameType.Commander); + case Oathbreaker: + return DeckgenUtil.generateCommanderDeck(isAi, GameType.Oathbreaker); + case TinyLeaders: + return DeckgenUtil.generateCommanderDeck(isAi, GameType.TinyLeaders); + case Brawl: + return DeckgenUtil.generateCommanderDeck(isAi, GameType.Brawl); + case Archenemy: + return DeckgenUtil.generateSchemeDeck(); + case Planechase: + return DeckgenUtil.generatePlanarDeck(); + default: + while (true) { + switch (Aggregates.random(DeckType.ConstructedOptions)) { + case PRECONSTRUCTED_DECK: + return Aggregates.random(DeckProxy.getAllPreconstructedDecks(QuestController.getPrecons())).getDeck(); + case QUEST_OPPONENT_DECK: + return Aggregates.random(DeckProxy.getAllQuestEventAndChallenges()).getDeck(); + case COLOR_DECK: + List colors = new ArrayList<>(); + int count = Aggregates.randomInt(1, 3); + for (int i = 1; i <= count; i++) { + colors.add("Random " + i); + } + return DeckgenUtil.buildColorDeck(colors, null, isAi); + case STANDARD_CARDGEN_DECK: + return DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getStandard(), isAi); + case PIONEER_CARDGEN_DECK: + return DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getPioneer(), isAi); + case HISTORIC_CARDGEN_DECK: + return DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getHistoric(), isAi); + case MODERN_CARDGEN_DECK: + return DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getModern(), isAi); + case LEGACY_CARDGEN_DECK: + return DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().get("Legacy"), isAi); + case VINTAGE_CARDGEN_DECK: + return DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().get("Vintage"), isAi); + case STANDARD_COLOR_DECK: + colors = new ArrayList<>(); + count = Aggregates.randomInt(1, 3); + for (int i = 1; i <= count; i++) { + colors.add("Random " + i); + } + return DeckgenUtil.buildColorDeck(colors, FModel.getFormats().getStandard().getFilterPrinted(), isAi); + case MODERN_COLOR_DECK: + colors = new ArrayList<>(); + count = Aggregates.randomInt(1, 3); + for (int i = 1; i <= count; i++) { + colors.add("Random " + i); + } + return DeckgenUtil.buildColorDeck(colors, FModel.getFormats().getModern().getFilterPrinted(), isAi); + case THEME_DECK: + return Aggregates.random(DeckProxy.getAllThemeDecks()).getDeck(); + default: + continue; } - return DeckgenUtil.buildColorDeck(colors, null, isAi); - case STANDARD_CARDGEN_DECK: - return DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getStandard(),isAi); - case PIONEER_CARDGEN_DECK: - return DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getPioneer(),isAi); - case HISTORIC_CARDGEN_DECK: - return DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getHistoric(),isAi); - case MODERN_CARDGEN_DECK: - return DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().getModern(),isAi); - case LEGACY_CARDGEN_DECK: - return DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().get("Legacy"),isAi); - case VINTAGE_CARDGEN_DECK: - return DeckgenUtil.buildLDACArchetypeDeck(FModel.getFormats().get("Vintage"),isAi); - case STANDARD_COLOR_DECK: - colors = new ArrayList<>(); - count = Aggregates.randomInt(1, 3); - for (int i = 1; i <= count; i++) { - colors.add("Random " + i); - } - return DeckgenUtil.buildColorDeck(colors, FModel.getFormats().getStandard().getFilterPrinted(), isAi); - case MODERN_COLOR_DECK: - colors = new ArrayList<>(); - count = Aggregates.randomInt(1, 3); - for (int i = 1; i <= count; i++) { - colors.add("Random " + i); - } - return DeckgenUtil.buildColorDeck(colors, FModel.getFormats().getModern().getFilterPrinted(), isAi); - case THEME_DECK: - return Aggregates.random(DeckProxy.getAllThemeDecks()).getDeck(); - default: - continue; } - } } } @@ -141,27 +142,28 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable decks; final GameType gameType = lstDecks.getGameType(); switch (gameType) { - case Commander: - decks = DeckProxy.getAllCommanderDecks(DeckFormat.Commander.isLegalDeckPredicate()); - break; - case Oathbreaker: - decks = DeckProxy.getAllOathbreakerDecks(DeckFormat.Oathbreaker.isLegalDeckPredicate()); - break; - case TinyLeaders: - decks = DeckProxy.getAllTinyLeadersDecks(DeckFormat.TinyLeaders.isLegalDeckPredicate()); - break; - case Brawl: - decks = DeckProxy.getAllBrawlDecks(DeckFormat.Brawl.isLegalDeckPredicate()); - break; - case Archenemy: - decks = DeckProxy.getAllSchemeDecks(DeckFormat.Archenemy.isLegalDeckPredicate()); - break; - case Planechase: - decks = DeckProxy.getAllPlanarDecks(DeckFormat.Planechase.isLegalDeckPredicate()); - break; - default: - decks = DeckProxy.getAllConstructedDecks(gameType.getDeckFormat().isLegalDeckPredicate()); - break; + case CommanderGauntlet: + case Commander: + decks = DeckProxy.getAllCommanderDecks(DeckFormat.Commander.isLegalDeckPredicate()); + break; + case Oathbreaker: + decks = DeckProxy.getAllOathbreakerDecks(DeckFormat.Oathbreaker.isLegalDeckPredicate()); + break; + case TinyLeaders: + decks = DeckProxy.getAllTinyLeadersDecks(DeckFormat.TinyLeaders.isLegalDeckPredicate()); + break; + case Brawl: + decks = DeckProxy.getAllBrawlDecks(DeckFormat.Brawl.isLegalDeckPredicate()); + break; + case Archenemy: + decks = DeckProxy.getAllSchemeDecks(DeckFormat.Archenemy.isLegalDeckPredicate()); + break; + case Planechase: + decks = DeckProxy.getAllPlanarDecks(DeckFormat.Planechase.isLegalDeckPredicate()); + break; + default: + decks = DeckProxy.getAllConstructedDecks(gameType.getDeckFormat().isLegalDeckPredicate()); + break; } if (Iterables.isEmpty(decks)) { return getGeneratedDeck(); //fall back to generated deck if no decks in filtered list @@ -175,27 +177,29 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable decks; switch (lstDecks.getGameType()) { - case Commander: - decks = DeckProxy.getAllCommanderDecks(); - break; - case Oathbreaker: - decks = DeckProxy.getAllOathbreakerDecks(); - break; - case TinyLeaders: - decks = DeckProxy.getAllTinyLeadersDecks(); - break; - case Archenemy: - decks = DeckProxy.getAllSchemeDecks(); - break; - case Planechase: - decks = DeckProxy.getAllPlanarDecks(); - break; - default: - decks = DeckProxy.getAllConstructedDecks(); - break; + case CommanderGauntlet: + case Commander: + decks = DeckProxy.getAllCommanderDecks(); + break; + case Oathbreaker: + decks = DeckProxy.getAllOathbreakerDecks(); + break; + case TinyLeaders: + decks = DeckProxy.getAllTinyLeadersDecks(); + break; + case Archenemy: + decks = DeckProxy.getAllSchemeDecks(); + break; + case Planechase: + decks = DeckProxy.getAllPlanarDecks(); + break; + default: + decks = DeckProxy.getAllConstructedDecks(); + break; } decks = Iterables.filter(decks, new Predicate() { - @Override public boolean apply(final DeckProxy deck) { + @Override + public boolean apply(final DeckProxy deck) { return deck.isFavoriteDeck(); } }); diff --git a/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletData.java b/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletData.java index ef81dba50f9..20c0b6d3725 100644 --- a/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletData.java +++ b/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletData.java @@ -4,6 +4,7 @@ import java.io.File; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.List; @@ -34,8 +35,18 @@ public final class GauntletData { private List eventNames = new ArrayList<>(); private Deck userDeck; private List decks; + private boolean isCommanderGauntlet = false; + + public GauntletData(boolean isCommander) { + isCommanderGauntlet = isCommander; + } public GauntletData() { + this(false); + } + + public boolean isCommanderGauntlet() { + return isCommanderGauntlet; } public void setName(String name0) { @@ -132,7 +143,7 @@ public final class GauntletData { public void startRound(final List players, final RegisteredPlayer human) { hostedMatch = GuiBase.getInterface().hostMatch(); - hostedMatch.startMatch(GameType.Gauntlet, null, players, human, GuiBase.getInterface().getNewGuiGame()); + hostedMatch.startMatch(isCommanderGauntlet ? GameType.CommanderGauntlet : GameType.Gauntlet, isCommanderGauntlet ? Collections.singleton(GameType.Commander) : null , players, human, GuiBase.getInterface().getNewGuiGame()); } public void nextRound(final List players, final RegisteredPlayer human) { diff --git a/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletIO.java b/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletIO.java index 66817b55afd..40ffba901c0 100644 --- a/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletIO.java +++ b/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletIO.java @@ -47,6 +47,8 @@ public class GauntletIO { public static final String PREFIX_QUICK = "Quick_"; /** Prefix for custom gauntlet save files. */ public static final String PREFIX_CUSTOM = "Custom_"; + /** Prefix for commander gauntlet save files. */ + public static final String PREFIX_COMMANDER = "Commander_"; /** Regex for locked gauntlet save files. */ public static final String PREFIX_LOCKED = "LOCKED_"; diff --git a/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletUtil.java b/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletUtil.java index 504304f3a57..58ab25885e7 100644 --- a/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletUtil.java +++ b/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletUtil.java @@ -10,6 +10,7 @@ import forge.deck.Deck; import forge.deck.DeckType; import forge.deck.DeckgenUtil; import forge.deck.NetDeckCategory; +import forge.game.GameType; import forge.model.FModel; import forge.util.MyRandom; @@ -94,6 +95,47 @@ public class GauntletUtil { gauntlet.reset(); return gauntlet; } + public static GauntletData createCommanderGauntlet(final Deck userDeck, final int numOpponents, final List allowedDeckTypes, NetDeckCategory netDecks) { + GauntletData gauntlet = new GauntletData(true); + setDefaultGauntletName(gauntlet, GauntletIO.PREFIX_COMMANDER); + FModel.setGauntletData(gauntlet); + + // Generate gauntlet decks + Deck deck; + final List eventNames = new ArrayList<>(); + final List decks = new ArrayList<>(); + + final Object[] netDeckNames = netDecks != null ? netDecks.getItemNames().toArray() : null; + + for (int i = 0; i < numOpponents; i++) { + int randType = (int)Math.floor(MyRandom.getRandom().nextDouble() * allowedDeckTypes.size()); + switch (allowedDeckTypes.get(randType)) { + case RANDOM_COMMANDER_DECK: + deck = DeckgenUtil.generateCommanderDeck(true, GameType.Commander); + eventNames.add(deck.getName()); + break; + case PRECON_COMMANDER_DECK: + deck = DeckgenUtil.getRandomCommanderPreconDeck(); + eventNames.add(deck.getName()); + break; + case COMMANDER_DECK: + deck = DeckgenUtil.getCommanderDeck(); + eventNames.add(deck.getName()); + break; + default: + continue; + } + decks.add(deck); + } + + gauntlet.setDecks(decks); + gauntlet.setEventNames(eventNames); + gauntlet.setUserDeck(userDeck); + + // Reset all variable fields to 0, stamps and saves automatically. + gauntlet.reset(); + return gauntlet; + } public static void setDefaultGauntletName(GauntletData gauntlet, String prefix) { final File[] arrFiles = GauntletIO.getGauntletFilesUnlocked(prefix); diff --git a/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletWinLoseController.java b/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletWinLoseController.java index e4994a694c5..a3c5554a3ab 100644 --- a/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletWinLoseController.java +++ b/forge-gui/src/main/java/forge/gamemodes/gauntlet/GauntletWinLoseController.java @@ -117,11 +117,15 @@ public abstract class GauntletWinLoseController { if (lastGame.isMatchOver()) { // To change the AI deck, we have to create a new match. final GauntletData gd = FModel.getGauntletData(); - final RegisteredPlayer human = new RegisteredPlayer(gd.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()); + final RegisteredPlayer human = gd.isCommanderGauntlet() + ? RegisteredPlayer.forCommander(gd.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()) + : new RegisteredPlayer(gd.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()); final Deck aiDeck = gd.getDecks().get(gd.getCompleted()); final List players = Lists.newArrayList(); players.add(human); - players.add(new RegisteredPlayer(aiDeck).setPlayer(GamePlayerUtil.createAiPlayer())); + players.add(gd.isCommanderGauntlet() + ? RegisteredPlayer.forCommander(aiDeck).setPlayer(GamePlayerUtil.createAiPlayer()) + : new RegisteredPlayer(aiDeck).setPlayer(GamePlayerUtil.createAiPlayer())); view.hide(); saveOptions();