From 8448afc709a73ab6d8cf54b2cb094ff4911d9cdc Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 13 May 2019 13:20:41 +0400 Subject: [PATCH] Test framework: added commander games support (quick start button, "commander" command to put card as commander); --- .../java/mage/client/table/TablesPanel.form | 34 ++++++++--- .../java/mage/client/table/TablesPanel.java | 59 +++++++++++++------ .../java/mage/server/util/SystemUtil.java | 25 +++++++- .../common/CastCommanderAbility.java | 5 +- .../java/mage/game/GameCommanderImpl.java | 10 ++-- .../java/mage/game/GameTinyLeadersImpl.java | 13 ++-- 6 files changed, 104 insertions(+), 42 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.form b/Mage.Client/src/main/java/mage/client/table/TablesPanel.form index 52b892737d..70f04d7ec3 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.form +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.form @@ -43,8 +43,11 @@ - - + + + + + @@ -60,10 +63,16 @@ - + - + + + + + + + @@ -506,15 +515,26 @@ - + - + - + + + + + + + + + + + + diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index 00b5775fb4..da43f35273 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -688,7 +688,7 @@ public class TablesPanel extends javax.swing.JPanel { this.roomId = roomId; UUID chatRoomId = null; if (SessionHandler.getSession() != null) { - btnQuickStart.setVisible(SessionHandler.isTestMode()); + btnQuickStartDuel.setVisible(SessionHandler.isTestMode()); gameChooser.init(); chatRoomId = SessionHandler.getRoomChatId(roomId).orElse(null); } @@ -973,7 +973,8 @@ public class TablesPanel extends javax.swing.JPanel { jSeparator5 = new javax.swing.JToolBar.Separator(); btnOpen = new javax.swing.JToggleButton(); btnPassword = new javax.swing.JToggleButton(); - btnQuickStart = new javax.swing.JButton(); + btnQuickStartDuel = new javax.swing.JButton(); + btnQuickStartCommander = new javax.swing.JButton(); jSplitPane1 = new javax.swing.JSplitPane(); jPanelTables = new javax.swing.JPanel(); jSplitPaneTables = new javax.swing.JSplitPane(); @@ -1393,13 +1394,23 @@ public class TablesPanel extends javax.swing.JPanel { }); filterBar2.add(btnPassword); - btnQuickStart.setText("Quick Start"); - btnQuickStart.setFocusable(false); - btnQuickStart.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnQuickStart.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnQuickStart.addActionListener(new java.awt.event.ActionListener() { + btnQuickStartDuel.setText("Quick start duel"); + btnQuickStartDuel.setFocusable(false); + btnQuickStartDuel.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnQuickStartDuel.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnQuickStartDuel.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - btnQuickStartActionPerformed(evt); + btnQuickStartDuelActionPerformed(evt); + } + }); + + btnQuickStartCommander.setText("Quick start commander"); + btnQuickStartCommander.setFocusable(false); + btnQuickStartCommander.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnQuickStartCommander.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnQuickStartCommander.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnQuickStartCommanderActionPerformed(evt); } }); @@ -1417,8 +1428,10 @@ public class TablesPanel extends javax.swing.JPanel { .addComponent(filterBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(filterBar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnQuickStart) - .addContainerGap(792, Short.MAX_VALUE)) + .addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(btnQuickStartDuel) + .addComponent(btnQuickStartCommander)) + .addContainerGap(734, Short.MAX_VALUE)) ); jPanelTopLayout.setVerticalGroup( jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -1431,9 +1444,13 @@ public class TablesPanel extends javax.swing.JPanel { .addGroup(jPanelTopLayout.createSequentialGroup() .addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(filterBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnQuickStart)) + .addComponent(btnQuickStartDuel)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(filterBar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGroup(jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(filterBar2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanelTopLayout.createSequentialGroup() + .addComponent(btnQuickStartCommander) + .addGap(0, 0, Short.MAX_VALUE))))) .addContainerGap()) ); @@ -1537,7 +1554,7 @@ public class TablesPanel extends javax.swing.JPanel { newTournamentDialog.showDialog(roomId); }//GEN-LAST:event_btnNewTournamentActionPerformed - private void btnQuickStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartActionPerformed + private void createTestGame(String gameName, String gameType) { TableView table; try { String testDeckFile = "test.dck"; @@ -1551,10 +1568,9 @@ public class TablesPanel extends javax.swing.JPanel { + "5 Mountain" + System.lineSeparator() + "5 Plains"); } - DeckCardLists testDeck = DeckImporter.importDeckFromFile(testDeckFile); - MatchOptions options = new MatchOptions("1", "Two Player Duel", false, 2); + MatchOptions options = new MatchOptions(gameName, gameType, false, 2); options.getPlayerTypes().add(PlayerType.HUMAN); options.getPlayerTypes().add(PlayerType.COMPUTER_MAD); options.setDeckType("Limited"); @@ -1577,7 +1593,11 @@ public class TablesPanel extends javax.swing.JPanel { } catch (HeadlessException ex) { handleError(ex); } - }//GEN-LAST:event_btnQuickStartActionPerformed + } + + private void btnQuickStartDuelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartDuelActionPerformed + createTestGame("Test duel", "Two Player Duel"); + }//GEN-LAST:event_btnQuickStartDuelActionPerformed private void btnNewTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewTableActionPerformed newTableDialog.showDialog(roomId); @@ -1630,6 +1650,10 @@ public class TablesPanel extends javax.swing.JPanel { MageFrame.getInstance().showWhatsNewDialog(true); }//GEN-LAST:event_buttonWhatsNewActionPerformed + private void btnQuickStartCommanderActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartCommanderActionPerformed + createTestGame("Test commander", "Commander Two Player Duel"); + }//GEN-LAST:event_btnQuickStartCommanderActionPerformed + private void handleError(Exception ex) { LOGGER.fatal("Error loading deck: ", ex); JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Error loading deck.", "Error", JOptionPane.ERROR_MESSAGE); @@ -1650,7 +1674,8 @@ public class TablesPanel extends javax.swing.JPanel { private javax.swing.JButton btnNewTournament; private javax.swing.JToggleButton btnOpen; private javax.swing.JToggleButton btnPassword; - private javax.swing.JButton btnQuickStart; + private javax.swing.JButton btnQuickStartCommander; + private javax.swing.JButton btnQuickStartDuel; private javax.swing.JToggleButton btnRated; private javax.swing.JToggleButton btnSkillBeginner; private javax.swing.JToggleButton btnSkillCasual; diff --git a/Mage.Server/src/main/java/mage/server/util/SystemUtil.java b/Mage.Server/src/main/java/mage/server/util/SystemUtil.java index 382021e4cf..ae2a758128 100644 --- a/Mage.Server/src/main/java/mage/server/util/SystemUtil.java +++ b/Mage.Server/src/main/java/mage/server/util/SystemUtil.java @@ -12,6 +12,7 @@ import mage.constants.Outcome; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; +import mage.game.GameCommanderImpl; import mage.game.permanent.Permanent; import mage.players.Player; import mage.util.RandomUtil; @@ -31,7 +32,8 @@ import java.util.stream.Collectors; */ public final class SystemUtil { - private SystemUtil(){} + private SystemUtil() { + } public static final DateFormat dateFormat = new SimpleDateFormat("yy-M-dd HH:mm:ss"); @@ -485,6 +487,8 @@ public final class SystemUtil { gameZone = Zone.COMMAND; } else if ("plane".equalsIgnoreCase(command.zone)) { gameZone = Zone.COMMAND; + } else if ("commander".equalsIgnoreCase(command.zone)) { + gameZone = Zone.COMMAND; } else { logger.warn("Unknown zone [" + command.zone + "]: " + line); continue; @@ -513,8 +517,23 @@ public final class SystemUtil { } } game.loadCards(cardsToLoad, player.getId()); - for (Card card : cardsToLoad) { - swapWithAnyCard(game, player, card, gameZone); + + if ("commander".equalsIgnoreCase(command.zone) && cardsToLoad.size() > 0) { + // as commander (only commander games, look at init code in GameCommanderImpl) + if (game instanceof GameCommanderImpl) { + GameCommanderImpl gameCommander = (GameCommanderImpl) game; + for (Card card : cardsToLoad) { + player.addCommanderId(card.getId()); + gameCommander.initCommander(card, player); + } + } else { + logger.fatal("Commander card can be used in commander game only: " + command.cardName); + } + } else { + // as other card + for (Card card : cardsToLoad) { + swapWithAnyCard(game, player, card, gameZone); + } } } } catch (Exception e) { diff --git a/Mage/src/main/java/mage/abilities/common/CastCommanderAbility.java b/Mage/src/main/java/mage/abilities/common/CastCommanderAbility.java index be7896e11b..a549a72310 100644 --- a/Mage/src/main/java/mage/abilities/common/CastCommanderAbility.java +++ b/Mage/src/main/java/mage/abilities/common/CastCommanderAbility.java @@ -1,7 +1,7 @@ - package mage.abilities.common; import mage.abilities.SpellAbility; +import mage.abilities.costs.CostsImpl; import mage.cards.Card; import mage.constants.SpellAbilityType; import mage.constants.TimingRule; @@ -9,14 +9,13 @@ import mage.constants.Zone; import mage.game.Game; /** - * * @author Plopman */ public class CastCommanderAbility extends SpellAbility { public CastCommanderAbility(Card card) { super(card.getManaCost(), card.getName(), Zone.COMMAND, SpellAbilityType.BASE); - this.costs = card.getSpellAbility().getCosts().copy(); + this.costs = card.getSpellAbility() != null ? card.getSpellAbility().getCosts().copy() : new CostsImpl<>(); this.timing = TimingRule.SORCERY; this.usesStack = true; this.controllerId = card.getOwnerId(); diff --git a/Mage/src/main/java/mage/game/GameCommanderImpl.java b/Mage/src/main/java/mage/game/GameCommanderImpl.java index 96de6b8306..47a6ee79a4 100644 --- a/Mage/src/main/java/mage/game/GameCommanderImpl.java +++ b/Mage/src/main/java/mage/game/GameCommanderImpl.java @@ -40,7 +40,6 @@ public abstract class GameCommanderImpl extends GameImpl { @Override protected void init(UUID choosingPlayerId) { - Ability ability = new SimpleStaticAbility(Zone.COMMAND, new InfoEffect("Commander effects")); //Move commander to command zone for (UUID playerId : state.getPlayerList(startingPlayerId)) { Player player = getPlayer(playerId); @@ -49,7 +48,7 @@ public abstract class GameCommanderImpl extends GameImpl { for (UUID commanderId : player.getCommandersIds()) { Card commander = this.getCard(commanderId); if (commander != null) { - initCommander(commander, ability, player); + initCommander(commander, player); } } } else { @@ -57,20 +56,20 @@ public abstract class GameCommanderImpl extends GameImpl { Card commander = this.getCard(player.getSideboard().iterator().next()); if (commander != null) { player.addCommanderId(commander.getId()); - initCommander(commander, ability, player); + initCommander(commander, player); } } } } } - this.getState().addAbility(ability, null); super.init(choosingPlayerId); if (startingPlayerSkipsDraw) { state.getTurnMods().add(new TurnMod(startingPlayerId, PhaseStep.DRAW)); } } - private void initCommander(Card commander, Ability ability, Player player) { + public void initCommander(Card commander, Player player) { + Ability ability = new SimpleStaticAbility(Zone.COMMAND, new InfoEffect("Commander effects")); commander.moveToZone(Zone.COMMAND, null, this, true); commander.getAbilities().setControllerId(player.getId()); ability.addEffect(new CommanderReplacementEffect(commander.getId(), alsoHand, alsoLibrary)); @@ -79,6 +78,7 @@ public abstract class GameCommanderImpl extends GameImpl { CommanderInfoWatcher watcher = new CommanderInfoWatcher(commander.getId(), checkCommanderDamage); getState().addWatcher(watcher); watcher.addCardInfoToCommander(this); + this.getState().addAbility(ability, null); } //20130711 diff --git a/Mage/src/main/java/mage/game/GameTinyLeadersImpl.java b/Mage/src/main/java/mage/game/GameTinyLeadersImpl.java index 78c7fdb0ec..48e1efa89f 100644 --- a/Mage/src/main/java/mage/game/GameTinyLeadersImpl.java +++ b/Mage/src/main/java/mage/game/GameTinyLeadersImpl.java @@ -1,9 +1,5 @@ - package mage.game; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -21,8 +17,11 @@ import mage.game.turn.TurnMod; import mage.players.Player; import mage.watchers.common.CommanderInfoWatcher; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** - * * @author JRHerlehy */ public abstract class GameTinyLeadersImpl extends GameImpl { @@ -43,7 +42,6 @@ public abstract class GameTinyLeadersImpl extends GameImpl { @Override protected void init(UUID choosingPlayerId) { - Ability ability = new SimpleStaticAbility(Zone.COMMAND, new InfoEffect("Commander effects")); //Move tiny leader to command zone for (UUID playerId : state.getPlayerList(startingPlayerId)) { Player player = getPlayer(playerId); @@ -55,6 +53,7 @@ public abstract class GameTinyLeadersImpl extends GameImpl { this.loadCards(cards, playerId); player.addCommanderId(commander.getId()); commander.moveToZone(Zone.COMMAND, null, this, true); + Ability ability = new SimpleStaticAbility(Zone.COMMAND, new InfoEffect("Commander effects")); ability.addEffect(new CommanderReplacementEffect(commander.getId(), alsoHand, alsoLibrary)); ability.addEffect(new CommanderCostModification(commander.getId())); // Commander rule #4 was removed Jan. 18, 2016 @@ -63,13 +62,13 @@ public abstract class GameTinyLeadersImpl extends GameImpl { CommanderInfoWatcher watcher = new CommanderInfoWatcher(commander.getId(), false); getState().addWatcher(watcher); watcher.addCardInfoToCommander(this); + this.getState().addAbility(ability, null); } else { throw new UnknownError("Commander card could not be created. Name: [" + player.getMatchPlayer().getDeck().getName() + ']'); } } } - this.getState().addAbility(ability, null); super.init(choosingPlayerId); if (startingPlayerSkipsDraw) { state.getTurnMods().add(new TurnMod(startingPlayerId, PhaseStep.DRAW));