add Commander Gauntlet

This commit is contained in:
Anthony Calosa
2023-03-17 08:18:52 +08:00
parent b03e99288a
commit 81efb2737f
25 changed files with 650 additions and 172 deletions

View File

@@ -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),

View File

@@ -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<T extends DeckBase> {
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<T extends DeckBase> {
VSubmenuGauntletBuild.SINGLETON_INSTANCE.updateDeckPanel();
VSubmenuGauntletQuick.SINGLETON_INSTANCE.updateDeckPanel();
VSubmenuGauntletContests.SINGLETON_INSTANCE.updateDeckPanel();
VSubmenuGauntletCommander.SINGLETON_INSTANCE.updateDeckPanel();
}
/**

View File

@@ -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);

View File

@@ -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.
*
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
*
*/
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<DeckType> 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<RegisteredPlayer> 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();
}
});
}
}

View File

@@ -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<RegisteredPlayer> 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);

View File

@@ -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.
*
* <br><br><i>(V at beginning of class name denotes a view class.)</i>
*
*/
public enum VSubmenuGauntletCommander implements IVSubmenu<CSubmenuGauntletCommander> {
/** */
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;
}
}

View File

@@ -49,7 +49,9 @@ public class ViewWinLose implements IWinLoseView<FButton> {
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<FButton> {
// 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<FButton> {
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<FButton> {
}
}
/** @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<FButton> {
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);
}
}