diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.form b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.form index f94d135401..9013c01ff4 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.form +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.form @@ -1,4 +1,4 @@ - +
@@ -24,69 +24,73 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -95,7 +99,7 @@ - + @@ -118,6 +122,10 @@ + + + + @@ -153,7 +161,7 @@ - + @@ -167,13 +175,30 @@ - + + + + + + + + + + + + + + + + + + @@ -184,35 +209,12 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - + @@ -222,12 +224,10 @@ - - - - - - + + + + @@ -237,6 +237,13 @@ + + + + + + + @@ -252,35 +259,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -294,15 +272,52 @@ - + - + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java index 5922e71336..e4e0b73c63 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java @@ -27,6 +27,13 @@ */ package mage.client.dialog; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import javax.swing.*; import mage.Constants.MultiplayerAttackOption; import mage.Constants.RangeOfInfluence; import mage.cards.decks.importer.DeckImporterUtil; @@ -41,13 +48,6 @@ import mage.view.GameTypeView; import mage.view.TableView; import org.apache.log4j.Logger; -import javax.swing.*; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - /** * * @author BetaSteward_at_googlemail.com @@ -69,6 +69,7 @@ public class NewTableDialog extends MageDialog { initComponents(); player1Panel.showLevel(false); this.spnNumWins.setModel(new SpinnerNumberModel(1, 1, 5, 1)); + this.spnFreeMulligans.setModel(new SpinnerNumberModel(0, 0, 5, 1)); } /** This method is called from within the constructor to @@ -80,32 +81,39 @@ public class NewTableDialog extends MageDialog { // //GEN-BEGIN:initComponents private void initComponents() { - lblGameType = new javax.swing.JLabel(); - cbGameType = new javax.swing.JComboBox(); + lblName = new javax.swing.JLabel(); + txtName = new javax.swing.JTextField(); lbDeckType = new javax.swing.JLabel(); cbDeckType = new javax.swing.JComboBox(); - btnOK = new javax.swing.JButton(); - btnCancel = new javax.swing.JButton(); - player1Panel = new mage.client.table.NewPlayerPanel(); - spnNumPlayers = new javax.swing.JSpinner(); + lblGameType = new javax.swing.JLabel(); + cbGameType = new javax.swing.JComboBox(); + lblFreeMulligans = new javax.swing.JLabel(); + spnFreeMulligans = new javax.swing.JSpinner(); lblNumPlayers = new javax.swing.JLabel(); - cbRange = new javax.swing.JComboBox(); + spnNumPlayers = new javax.swing.JSpinner(); lblRange = new javax.swing.JLabel(); + cbRange = new javax.swing.JComboBox(); lblAttack = new javax.swing.JLabel(); cbAttackOption = new javax.swing.JComboBox(); - pnlOtherPlayers = new javax.swing.JPanel(); - jSeparator1 = new javax.swing.JSeparator(); - jSeparator2 = new javax.swing.JSeparator(); - jLabel1 = new javax.swing.JLabel(); - jSeparator3 = new javax.swing.JSeparator(); - jLabel2 = new javax.swing.JLabel(); lblNumWins = new javax.swing.JLabel(); spnNumWins = new javax.swing.JSpinner(); - txtName = new javax.swing.JTextField(); - lblName = new javax.swing.JLabel(); + jSeparator2 = new javax.swing.JSeparator(); + jLabel1 = new javax.swing.JLabel(); + player1Panel = new mage.client.table.NewPlayerPanel(); + jSeparator3 = new javax.swing.JSeparator(); + jLabel2 = new javax.swing.JLabel(); + pnlOtherPlayers = new javax.swing.JPanel(); + jSeparator1 = new javax.swing.JSeparator(); + btnOK = new javax.swing.JButton(); + btnCancel = new javax.swing.JButton(); setTitle("New Table"); + lblName.setLabelFor(txtName); + lblName.setText("Name:"); + + lbDeckType.setText("Deck Type:"); + lblGameType.setText("Game Type:"); cbGameType.addActionListener(new java.awt.event.ActionListener() { @@ -114,7 +122,39 @@ public class NewTableDialog extends MageDialog { } }); - lbDeckType.setText("Deck Type:"); + lblFreeMulligans.setText("Free Mulligans:"); + + lblNumPlayers.setLabelFor(spnNumPlayers); + lblNumPlayers.setText("Players"); + + spnNumPlayers.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + numPlayersChanged(evt); + } + }); + + lblRange.setLabelFor(cbRange); + lblRange.setText("Range of Influence"); + + lblAttack.setLabelFor(cbAttackOption); + lblAttack.setText("Attack Option"); + + lblNumWins.setLabelFor(spnNumWins); + lblNumWins.setText("Wins"); + + spnNumWins.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spnNumWinsnumPlayersChanged(evt); + } + }); + + jLabel1.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N + jLabel1.setText("Player 1 (You)"); + + jLabel2.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N + jLabel2.setText("Other Players"); + + pnlOtherPlayers.setLayout(new java.awt.GridLayout(0, 1)); btnOK.setText("OK"); btnOK.addActionListener(new java.awt.event.ActionListener() { @@ -130,102 +170,70 @@ public class NewTableDialog extends MageDialog { } }); - spnNumPlayers.addChangeListener(new javax.swing.event.ChangeListener() { - public void stateChanged(javax.swing.event.ChangeEvent evt) { - numPlayersChanged(evt); - } - }); - - lblNumPlayers.setLabelFor(spnNumPlayers); - lblNumPlayers.setText("Players"); - - lblRange.setLabelFor(cbRange); - lblRange.setText("Range of Influence"); - - lblAttack.setLabelFor(cbAttackOption); - lblAttack.setText("Attack Option"); - - pnlOtherPlayers.setLayout(new java.awt.GridLayout(0, 1)); - - jLabel1.setFont(new java.awt.Font("Tahoma", 1, 11)); - jLabel1.setText("Player 1 (You)"); - - jLabel2.setFont(new java.awt.Font("Tahoma", 1, 11)); - jLabel2.setText("Other Players"); - - lblNumWins.setLabelFor(spnNumWins); - lblNumWins.setText("Wins"); - - spnNumWins.addChangeListener(new javax.swing.event.ChangeListener() { - public void stateChanged(javax.swing.event.ChangeEvent evt) { - spnNumWinsnumPlayersChanged(evt); - } - }); - - lblName.setLabelFor(txtName); - lblName.setText("Name:"); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(btnOK) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnCancel)) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(lblNumPlayers) - .addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 57, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(lblRange) - .addComponent(cbRange, javax.swing.GroupLayout.PREFERRED_SIZE, 143, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(lblAttack) - .addComponent(cbAttackOption, 0, 287, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblNumWins))) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jSeparator2, javax.swing.GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel1)) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() - .addContainerGap() - .addComponent(player1Panel, javax.swing.GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel2)) - .addGroup(layout.createSequentialGroup() - .addGap(16, 16, 16) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(lbDeckType) - .addComponent(lblGameType) - .addComponent(lblName)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(cbDeckType, javax.swing.GroupLayout.Alignment.LEADING, 0, 487, Short.MAX_VALUE) - .addComponent(cbGameType, 0, 487, Short.MAX_VALUE) - .addComponent(txtName, javax.swing.GroupLayout.DEFAULT_SIZE, 487, Short.MAX_VALUE))) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel2)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addGap(16, 16, 16) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(lbDeckType) + .addComponent(lblGameType) + .addComponent(lblName)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(cbDeckType, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(cbGameType, javax.swing.GroupLayout.PREFERRED_SIZE, 398, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblFreeMulligans) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnFreeMulligans, javax.swing.GroupLayout.DEFAULT_SIZE, 50, Short.MAX_VALUE)) + .addComponent(txtName)))) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE) - .addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)))) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(btnOK) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnCancel)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(lblNumPlayers) + .addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 57, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(lblRange) + .addComponent(cbRange, javax.swing.GroupLayout.PREFERRED_SIZE, 143, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(lblAttack) + .addComponent(cbAttackOption, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblNumWins))) + .addComponent(jSeparator2) + .addComponent(player1Panel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.LEADING)))) .addContainerGap()) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(jSeparator3, javax.swing.GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE) + .addComponent(jSeparator3, javax.swing.GroupLayout.DEFAULT_SIZE, 625, Short.MAX_VALUE) .addContainerGap())) ); layout.setVerticalGroup( @@ -242,7 +250,10 @@ public class NewTableDialog extends MageDialog { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(cbGameType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblGameType)) + .addComponent(lblGameType) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(spnFreeMulligans, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblFreeMulligans))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) @@ -271,7 +282,7 @@ public class NewTableDialog extends MageDialog { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, 136, Short.MAX_VALUE) + .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -283,7 +294,7 @@ public class NewTableDialog extends MageDialog { .addGroup(layout.createSequentialGroup() .addGap(201, 201, 201) .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(207, Short.MAX_VALUE))) + .addContainerGap(240, Short.MAX_VALUE))) ); pack(); @@ -307,6 +318,7 @@ public class NewTableDialog extends MageDialog { options.setAttackOption((MultiplayerAttackOption) this.cbAttackOption.getSelectedItem()); options.setRange((RangeOfInfluence) this.cbRange.getSelectedItem()); options.setWinsNeeded((Integer)this.spnNumWins.getValue()); + options.setFreeMulligans((Integer)this.spnFreeMulligans.getValue()); saveGameSettingsToPrefs(options, this.player1Panel.getDeckFile()); table = session.createTable(roomId, options); @@ -458,6 +470,7 @@ public class NewTableDialog extends MageDialog { this.player1Panel.setDeckFile(deckFile); } this.spnNumWins.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_NUMBER_OF_WINS, "2"))); + this.spnFreeMulligans.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_NUMBER_OF_FREE_MULLIGANS, "0"))); this.spnNumPlayers.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_NUMBER_PLAYERS, "2"))); int range = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_RANGE, "1")); for (RangeOfInfluence roi :RangeOfInfluence.values()) { @@ -486,6 +499,7 @@ public class NewTableDialog extends MageDialog { PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_DECK_TYPE, options.getDeckType()); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_GAME_TYPE, options.getGameType()); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_NUMBER_OF_WINS, Integer.toString(options.getWinsNeeded())); + PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_NUMBER_OF_FREE_MULLIGANS, Integer.toString(options.getFreeMulligans())); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_DECK_FILE, deckFile); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_NUMBER_PLAYERS, spnNumPlayers.getValue().toString()); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_RANGE, Integer.toString(options.getRange().getRange())); @@ -506,6 +520,7 @@ public class NewTableDialog extends MageDialog { private javax.swing.JSeparator jSeparator3; private javax.swing.JLabel lbDeckType; private javax.swing.JLabel lblAttack; + private javax.swing.JLabel lblFreeMulligans; private javax.swing.JLabel lblGameType; private javax.swing.JLabel lblName; private javax.swing.JLabel lblNumPlayers; @@ -513,6 +528,7 @@ public class NewTableDialog extends MageDialog { private javax.swing.JLabel lblRange; private mage.client.table.NewPlayerPanel player1Panel; private javax.swing.JPanel pnlOtherPlayers; + private javax.swing.JSpinner spnFreeMulligans; private javax.swing.JSpinner spnNumPlayers; private javax.swing.JSpinner spnNumWins; private javax.swing.JTextField txtName; diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form index d405d6b5ae..a11795a921 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form @@ -27,14 +27,6 @@ - - - - - - - - @@ -43,19 +35,47 @@ - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -78,18 +98,26 @@ - - - + + + + + + + + + + + - + - + @@ -105,6 +133,20 @@ + + + + + + + + + + + + + + @@ -125,16 +167,41 @@ - + + + + + + + + + + + + + - + + + + + + + + + + + + + + @@ -151,14 +218,6 @@ - - - - - - - - @@ -174,7 +233,7 @@ - + @@ -233,13 +292,6 @@
- - - - - - - @@ -283,15 +335,5 @@ - - - - - - - - - - diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java index cd92ee7e6a..09dc92fd4e 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java @@ -34,9 +34,17 @@ package mage.client.dialog; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JComboBox; +import javax.swing.JOptionPane; +import javax.swing.SpinnerNumberModel; import mage.Constants.MultiplayerAttackOption; import mage.Constants.RangeOfInfluence; import mage.cards.ExpansionSet; +import mage.cards.Sets; import mage.client.MageFrame; import mage.client.table.TournamentPlayerPanel; import mage.game.draft.DraftOptions; @@ -44,15 +52,10 @@ import mage.game.draft.DraftOptions.TimingOption; import mage.game.tournament.LimitedOptions; import mage.game.tournament.TournamentOptions; import mage.remote.Session; -import mage.cards.Sets; import mage.view.TableView; import mage.view.TournamentTypeView; import org.apache.log4j.Logger; -import javax.swing.*; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; /** * @@ -74,6 +77,8 @@ public class NewTournamentDialog extends MageDialog { initComponents(); txtName.setText("Tournament"); this.spnNumWins.setModel(new SpinnerNumberModel(2, 1, 5, 1)); + this.spnFreeMulligans.setModel(new SpinnerNumberModel(0, 0, 5, 1)); + this.spnConstructTime.setModel(new SpinnerNumberModel(10, 10, 30, 5)); } public void showDialog(UUID roomId) { @@ -97,29 +102,37 @@ public class NewTournamentDialog extends MageDialog { // //GEN-BEGIN:initComponents private void initComponents() { + lblName = new javax.swing.JLabel(); + txtName = new javax.swing.JTextField(); + lblConstructionTime = new javax.swing.JLabel(); + spnConstructTime = new javax.swing.JSpinner(); jLabel1 = new javax.swing.JLabel(); cbTournamentType = new javax.swing.JComboBox(); - spnNumPlayers = new javax.swing.JSpinner(); + lblFreeMulligans = new javax.swing.JLabel(); + spnFreeMulligans = new javax.swing.JSpinner(); + lblNumWins = new javax.swing.JLabel(); + spnNumWins = new javax.swing.JSpinner(); + pnlPacks = new javax.swing.JPanel(); jLabel2 = new javax.swing.JLabel(); + spnNumPlayers = new javax.swing.JSpinner(); btnOk = new javax.swing.JButton(); btnCancel = new javax.swing.JButton(); - pnlPacks = new javax.swing.JPanel(); jPanel1 = new javax.swing.JPanel(); jLabel3 = new javax.swing.JLabel(); jLabel4 = new javax.swing.JLabel(); txtPlayer1Name = new javax.swing.JTextField(); pnlOtherPlayers = new javax.swing.JPanel(); jLabel5 = new javax.swing.JLabel(); - txtName = new javax.swing.JTextField(); - lblName = new javax.swing.JLabel(); pnlDraftOptions = new javax.swing.JPanel(); jLabel6 = new javax.swing.JLabel(); cbDraftTiming = new javax.swing.JComboBox(); - lblNumWins = new javax.swing.JLabel(); - spnNumWins = new javax.swing.JSpinner(); setTitle("New Tournament"); + lblName.setText("Name:"); + + lblConstructionTime.setText("Construction Time (Minutes):"); + jLabel1.setText("Tournament Type:"); cbTournamentType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); @@ -129,14 +142,26 @@ public class NewTournamentDialog extends MageDialog { } }); + lblFreeMulligans.setText("Free Mulligans:"); + + lblNumWins.setText("Wins:"); + + spnNumWins.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spnNumWinsnumPlayersChanged(evt); + } + }); + + pnlPacks.setLayout(new java.awt.GridLayout(0, 1, 2, 0)); + + jLabel2.setText("Players:"); + spnNumPlayers.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { spnNumPlayersStateChanged(evt); } }); - jLabel2.setText("Players:"); - btnOk.setText("OK"); btnOk.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -151,8 +176,6 @@ public class NewTournamentDialog extends MageDialog { } }); - pnlPacks.setLayout(new java.awt.GridLayout(0, 1, 2, 0)); - jLabel3.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel3.setText("Player 1 (You)"); @@ -175,7 +198,7 @@ public class NewTournamentDialog extends MageDialog { .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() .addComponent(jLabel4) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtPlayer1Name))) + .addComponent(txtPlayer1Name, javax.swing.GroupLayout.DEFAULT_SIZE, 638, Short.MAX_VALUE))) .addContainerGap()) ); jPanel1Layout.setVerticalGroup( @@ -193,8 +216,6 @@ public class NewTournamentDialog extends MageDialog { jLabel5.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel5.setText("Packs"); - lblName.setText("Name:"); - jLabel6.setText("Timing:"); cbDraftTiming.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); @@ -217,14 +238,6 @@ public class NewTournamentDialog extends MageDialog { .addComponent(jLabel6)) ); - lblNumWins.setText("Wins"); - - spnNumWins.addChangeListener(new javax.swing.event.ChangeListener() { - public void stateChanged(javax.swing.event.ChangeEvent evt) { - spnNumWinsnumPlayersChanged(evt); - } - }); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( @@ -234,13 +247,6 @@ public class NewTournamentDialog extends MageDialog { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(pnlPacks, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() - .addComponent(jLabel2) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pnlDraftOptions, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(jLabel5, javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(lblName) @@ -248,15 +254,37 @@ public class NewTournamentDialog extends MageDialog { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(txtName) - .addComponent(cbTournamentType, 0, 420, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(cbTournamentType, 0, 330, Short.MAX_VALUE)) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblNumWins))) + .addGroup(layout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(lblFreeMulligans) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnFreeMulligans) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(lblNumWins)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(19, 19, 19) + .addComponent(lblConstructionTime))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(spnConstructTime, javax.swing.GroupLayout.DEFAULT_SIZE, 48, Short.MAX_VALUE) + .addComponent(spnNumWins))) .addGroup(layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) .addComponent(btnOk) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnCancel))) + .addComponent(btnCancel)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pnlDraftOptions, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel5, javax.swing.GroupLayout.Alignment.LEADING)) + .addGap(0, 0, Short.MAX_VALUE))) .addContainerGap()) ); layout.setVerticalGroup( @@ -273,16 +301,22 @@ public class NewTournamentDialog extends MageDialog { .addComponent(jLabel1) .addComponent(cbTournamentType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addGroup(layout.createSequentialGroup() - .addComponent(lblNumWins) - .addGap(0, 0, 0) - .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(lblConstructionTime) + .addComponent(spnConstructTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblNumWins) + .addComponent(spnFreeMulligans, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblFreeMulligans)))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel5) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pnlPacks, javax.swing.GroupLayout.DEFAULT_SIZE, 63, Short.MAX_VALUE) + .addComponent(pnlPacks, javax.swing.GroupLayout.DEFAULT_SIZE, 65, Short.MAX_VALUE) .addGap(11, 11, 11) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(spnNumPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, 26, Short.MAX_VALUE) + .addComponent(spnNumPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, 28, Short.MAX_VALUE) .addComponent(pnlDraftOptions, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel2)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -315,14 +349,17 @@ public class NewTournamentDialog extends MageDialog { tOptions.setLimitedOptions(options); } if (tournamentType.isLimited()) { - if (tOptions.getLimitedOptions() == null) + if (tOptions.getLimitedOptions() == null) { tOptions.setLimitedOptions(new LimitedOptions()); + tOptions.getLimitedOptions().setConstructionTime((Integer)this.spnConstructTime.getValue()); + } for (JComboBox pack: packs) { tOptions.getLimitedOptions().getSetCodes().add(((ExpansionSet) pack.getSelectedItem()).getCode()); } } tOptions.getMatchOptions().setDeckType("Limited"); tOptions.getMatchOptions().setWinsNeeded((Integer)this.spnNumWins.getValue()); + tOptions.getMatchOptions().setFreeMulligans((Integer)this.spnFreeMulligans.getValue()); tOptions.getMatchOptions().setAttackOption(MultiplayerAttackOption.LEFT); tOptions.getMatchOptions().setRange(RangeOfInfluence.ALL); tOptions.getMatchOptions().setLimited(true); @@ -483,11 +520,15 @@ public class NewTournamentDialog extends MageDialog { private javax.swing.JLabel jLabel5; private javax.swing.JLabel jLabel6; private javax.swing.JPanel jPanel1; + private javax.swing.JLabel lblConstructionTime; + private javax.swing.JLabel lblFreeMulligans; private javax.swing.JLabel lblName; private javax.swing.JLabel lblNumWins; private javax.swing.JPanel pnlDraftOptions; private javax.swing.JPanel pnlOtherPlayers; private javax.swing.JPanel pnlPacks; + private javax.swing.JSpinner spnConstructTime; + private javax.swing.JSpinner spnFreeMulligans; private javax.swing.JSpinner spnNumPlayers; private javax.swing.JSpinner spnNumWins; private javax.swing.JTextField txtName; diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java index a42facf23c..f836ad8f5c 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java @@ -87,6 +87,7 @@ public class PreferencesDialog extends javax.swing.JDialog { public static final String KEY_NEW_TABLE_DECK_TYPE = "newTableDeckType"; public static final String KEY_NEW_TABLE_GAME_TYPE = "newTableGameType"; public static final String KEY_NEW_TABLE_NUMBER_OF_WINS = "newTableNumberOfWins"; + public static final String KEY_NEW_TABLE_NUMBER_OF_FREE_MULLIGANS = "newTableNumberOfFreeMulligans"; public static final String KEY_NEW_TABLE_DECK_FILE = "newTableDeckFile"; public static final String KEY_NEW_TABLE_RANGE = "newTableRange"; public static final String KEY_NEW_TABLE_ATTACK_OPTION = "newTableAttackOption"; 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 82d040bf39..f9b9ab7d43 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -606,9 +606,9 @@ private void chkShowCompletedActionPerformed(java.awt.event.ActionEvent evt) {// class TableTableModel extends AbstractTableModel { - public static int ACTION_COLUMN = 8; // column the action is located (starting with 0) + public static int ACTION_COLUMN = 9; // column the action is located (starting with 0) - private String[] columnNames = new String[]{"Match Name", "Owner / Players", "Game Type", "Wins", "Deck Type", "Info", "Status", "Created", "Action"}; + private String[] columnNames = new String[]{"Match Name", "Owner / Players", "Game Type", "Wins", "Free Mulligans", "Deck Type", "Info", "Status", "Created", "Action"}; private TableView[] tables = new TableView[0]; private static final DateFormat timeFormatter = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); @@ -645,14 +645,16 @@ class TableTableModel extends AbstractTableModel { case 3: return Integer.toString(tables[arg0].getWins()); case 4: - return tables[arg0].getDeckType(); + return Integer.toString(tables[arg0].getFreeMulligans()); case 5: - return tables[arg0].getAdditionalInfo(); + return tables[arg0].getDeckType(); case 6: - return tables[arg0].getTableState().toString(); + return tables[arg0].getAdditionalInfo(); case 7: - return timeFormatter.format(tables[arg0].getCreateTime()); + return tables[arg0].getTableState().toString(); case 8: + return timeFormatter.format(tables[arg0].getCreateTime()); + case 9: switch (tables[arg0].getTableState()) { case WAITING: String owner = tables[arg0].getControllerName(); @@ -680,14 +682,14 @@ class TableTableModel extends AbstractTableModel { default: return ""; } - case 9: - return tables[arg0].isTournament(); case 10: + return tables[arg0].isTournament(); + case 11: if (!tables[arg0].getGames().isEmpty()) { return tables[arg0].getGames().get(0); } return null; - case 11: + case 12: return tables[arg0].getTableId(); } return ""; diff --git a/Mage.Common/src/mage/view/TableView.java b/Mage.Common/src/mage/view/TableView.java index 5d9ebdf686..4d184c301b 100644 --- a/Mage.Common/src/mage/view/TableView.java +++ b/Mage.Common/src/mage/view/TableView.java @@ -50,6 +50,7 @@ public class TableView implements Serializable { private UUID tableId; private String gameType; private int wins; + private int freeMulligans; private String deckType; private String tableName; private String controllerName; @@ -73,11 +74,12 @@ public class TableView implements Serializable { } if (!table.isTournament()) { this.wins = table.getMatch().getWinsNeeded(); + this.freeMulligans = table.getMatch().getFreeMulligans(); for (Game game: table.getMatch().getGames()) { games.add(game.getId()); } StringBuilder sb = new StringBuilder(); - StringBuilder sbScore = new StringBuilder("Score: "); + StringBuilder sbScore = new StringBuilder(); for(MatchPlayer matchPlayer: table.getMatch().getPlayers()) { if (!matchPlayer.getPlayer().getName().equals(table.getControllerName())) { sb.append(", ").append(matchPlayer.getPlayer().getName()); @@ -96,6 +98,7 @@ public class TableView implements Serializable { } else { this.wins = table.getTournament().getOptions().getMatchOptions().getWinsNeeded(); + this.freeMulligans = table.getTournament().getOptions().getMatchOptions().getFreeMulligans(); StringBuilder sb1 = new StringBuilder(); for (TournamentPlayer tp: table.getTournament().getPlayers()) { if (!tp.getPlayer().getName().equals(table.getControllerName())) { @@ -104,8 +107,15 @@ public class TableView implements Serializable { } this.controllerName += sb1.toString(); StringBuilder sb = new StringBuilder("Seats: ").append(table.getTournament().getPlayers().size()).append("/").append(table.getNumberOfSeats()); - if (table.getState().equals(TableState.DUELING)) { - sb.append(" - Running round: ").append(table.getTournament().getRounds().size()); + switch (table.getState()) { + case WAITING: + case STARTING: + sb.append(" Constr. Time: ").append(table.getTournament().getOptions().getLimitedOptions().getConstructionTime()/60).append(" Min."); + break; + case DUELING: + sb.append(" - Running round: ").append(table.getTournament().getRounds().size()); + break; + default: } this.additionalInfo = sb.toString(); this.deckType = new StringBuilder(table.getDeckType()).append(" ").append(table.getTournament().getSetsFormatedShort()).toString(); @@ -132,6 +142,10 @@ public class TableView implements Serializable { return wins; } + public int getFreeMulligans() { + return freeMulligans; + } + public String getDeckType() { return deckType; } diff --git a/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuel.java b/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuel.java index 9e8fb5af53..fba3eedfa0 100644 --- a/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuel.java +++ b/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuel.java @@ -39,8 +39,8 @@ import mage.game.turn.TurnMod; public class CommanderDuel extends GameImpl { - public CommanderDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range) { - super(attackOption, range); + public CommanderDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, int freeMulligans) { + super(attackOption, range, freeMulligans); } public CommanderDuel(final CommanderDuel game) { diff --git a/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuelMatch.java b/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuelMatch.java index 4817c023c1..c9c9d88e69 100644 --- a/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuelMatch.java +++ b/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuelMatch.java @@ -43,7 +43,7 @@ public class CommanderDuelMatch extends MatchImpl { @Override public void startGame() throws GameException { - CommanderDuel game = new CommanderDuel(options.getAttackOption(), options.getRange()); + CommanderDuel game = new CommanderDuel(options.getAttackOption(), options.getRange(), options.getFreeMulligans()); game.setStartMessage(this.createGameStartMessage()); initGame(game); games.add(game); diff --git a/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java index 68a1baf5cb..3c271cf889 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java +++ b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java @@ -28,15 +28,12 @@ package mage.game; -import java.util.ArrayList; import java.util.HashSet; -import java.util.List; import java.util.Set; import java.util.UUID; import mage.Constants.MultiplayerAttackOption; import mage.Constants.RangeOfInfluence; import mage.game.match.MatchType; -import mage.players.Player; /** * @@ -45,18 +42,14 @@ import mage.players.Player; public class FreeForAll extends GameImpl { private int numPlayers; - private List mulliganed = new ArrayList(); - public FreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range) { - super(attackOption, range); + public FreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, int freeMulligans) { + super(attackOption, range, freeMulligans); } public FreeForAll(final FreeForAll game) { super(game); this.numPlayers = game.numPlayers; - for (UUID playerId: game.mulliganed) { - mulliganed.add(playerId); - } } @Override @@ -89,32 +82,6 @@ public class FreeForAll extends GameImpl { return opponents; } - @Override - public int mulliganDownTo(UUID playerId) { - Player player = getPlayer(playerId); - int numCards = player.getHand().size(); - if (!mulliganed.contains(playerId)) { - numCards += 1; - } - return numCards -1; - } - - @Override - public void mulligan(UUID playerId) { - Player player = getPlayer(playerId); - int numCards = player.getHand().size(); - //record first mulligan and increment card count - if (!mulliganed.contains(playerId)) { - numCards += 1; - mulliganed.add(playerId); - } - player.getLibrary().addAll(player.getHand().getCards(this), this); - player.getHand().clear(); - player.shuffleLibrary(this); - fireInformEvent(player.getName() + " mulligans down to " + Integer.toString(numCards - 1) + " cards"); - player.drawCards(numCards - 1, this); - } - @Override public FreeForAll copy() { return new FreeForAll(this); diff --git a/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAllMatch.java b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAllMatch.java index e40e41a0c8..c043b3168f 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAllMatch.java +++ b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAllMatch.java @@ -43,7 +43,7 @@ public class FreeForAllMatch extends MatchImpl { @Override public void startGame() throws GameException { - FreeForAll game = new FreeForAll(options.getAttackOption(), options.getRange()); + FreeForAll game = new FreeForAll(options.getAttackOption(), options.getRange(), options.getFreeMulligans()); game.setStartMessage(this.createGameStartMessage()); initGame(game); games.add(game); diff --git a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java index ee182f090d..9ffb138a7b 100644 --- a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java +++ b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java @@ -28,19 +28,19 @@ package mage.game; -import mage.game.match.MatchType; import java.util.HashSet; import java.util.Set; import java.util.UUID; import mage.Constants.MultiplayerAttackOption; import mage.Constants.PhaseStep; import mage.Constants.RangeOfInfluence; +import mage.game.match.MatchType; import mage.game.turn.TurnMod; public class TwoPlayerDuel extends GameImpl { - public TwoPlayerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range) { - super(attackOption, range); + public TwoPlayerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, int freeMulligans) { + super(attackOption, range, freeMulligans); } public TwoPlayerDuel(final TwoPlayerDuel game) { @@ -78,8 +78,9 @@ public class TwoPlayerDuel extends GameImpl { public Set getOpponents(UUID playerId) { Set opponents = new HashSet(); for (UUID opponentId: this.getPlayer(playerId).getInRange()) { - if (!opponentId.equals(playerId)) + if (!opponentId.equals(playerId)) { opponents.add(opponentId); + } } return opponents; } diff --git a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java index a1c10f8a16..ac9f63546a 100644 --- a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java +++ b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java @@ -43,7 +43,7 @@ public class TwoPlayerMatch extends MatchImpl { @Override public void startGame() throws GameException { - TwoPlayerDuel game = new TwoPlayerDuel(options.getAttackOption(), options.getRange()); + TwoPlayerDuel game = new TwoPlayerDuel(options.getAttackOption(), options.getRange(), options.getFreeMulligans()); // Sets a start message about the match score game.setStartMessage(this.createGameStartMessage()); initGame(game); diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index fa0a2806fd..dceba348ca 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -142,8 +142,8 @@ public class HumanPlayer extends PlayerImpl { updateGameStatePriority("chooseMulligan", game); int nextHandSize = game.mulliganDownTo(playerId); game.fireAskPlayerEvent(playerId, new StringBuilder("Mulligan ") - .append(getHand().size() > nextHandSize?"down":"") - .append(" to ").append(nextHandSize) + .append(getHand().size() > nextHandSize?"down to ":"for free, draw ") + .append(nextHandSize) .append(nextHandSize == 1?" card?":" cards?").toString()); waitForBooleanResponse(); if (!abort) { diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/BoosterDraftEliminationTournament.java b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/BoosterDraftEliminationTournament.java index d541f4537d..92f8ee92e3 100644 --- a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/BoosterDraftEliminationTournament.java +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/BoosterDraftEliminationTournament.java @@ -50,6 +50,7 @@ public class BoosterDraftEliminationTournament extends TournamentSingleEliminati public BoosterDraftEliminationTournament(TournamentOptions options) { super(options); + this.getOptions().getLimitedOptions().setConstructionTime(600); currentStep = TournamentStep.START; } diff --git a/Mage.Server.Plugins/Mage.Tournament.Sealed/src/mage/tournament/SealedEliminationTournament.java b/Mage.Server.Plugins/Mage.Tournament.Sealed/src/mage/tournament/SealedEliminationTournament.java index 7f8689f954..702ab4630f 100644 --- a/Mage.Server.Plugins/Mage.Tournament.Sealed/src/mage/tournament/SealedEliminationTournament.java +++ b/Mage.Server.Plugins/Mage.Tournament.Sealed/src/mage/tournament/SealedEliminationTournament.java @@ -45,6 +45,7 @@ public class SealedEliminationTournament extends TournamentSingleElimination { public SealedEliminationTournament(TournamentOptions options) { super(options); + this.getOptions().getLimitedOptions().setConstructionTime(1200); currentStep = TournamentStep.START; } diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/PlayGameTest.java b/Mage.Tests/src/test/java/org/mage/test/serverside/PlayGameTest.java index 03e76eee30..34908bdc3e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/PlayGameTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/PlayGameTest.java @@ -31,7 +31,7 @@ public class PlayGameTest extends MageTestBase { @Ignore @Test public void playOneGame() throws GameException, FileNotFoundException, IllegalArgumentException { - Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ALL); + Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ALL, 0); Player computerA = createPlayer("ComputerA", "Computer - minimax hybrid"); // Player playerA = createPlayer("ComputerA", "Computer - mad"); diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/TestPlayRandomGame.java b/Mage.Tests/src/test/java/org/mage/test/serverside/TestPlayRandomGame.java index 8842ee1353..05a2daf6fa 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/TestPlayRandomGame.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/TestPlayRandomGame.java @@ -38,7 +38,7 @@ public class TestPlayRandomGame extends MageTestBase { } private void playOneGame() throws GameException, FileNotFoundException, IllegalArgumentException { - Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ALL); + Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ALL, 0); Player computerA = createRandomPlayer("ComputerA"); Deck deck = generateRandomDeck(); diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/CardTestMultiPlayerBase.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/CardTestMultiPlayerBase.java index c9e50741a8..1334263ae6 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/CardTestMultiPlayerBase.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/CardTestMultiPlayerBase.java @@ -44,7 +44,7 @@ public abstract class CardTestMultiPlayerBase extends CardTestPlayerAPIImpl { System.gc(); } - Game game = new FreeForAll(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ONE); + Game game = new FreeForAll(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ONE, 0); playerA = createPlayer(game, playerA, "PlayerA"); playerB = createPlayer(game, playerB, "PlayerB"); @@ -85,7 +85,7 @@ public abstract class CardTestMultiPlayerBase extends CardTestPlayerAPIImpl { System.gc(); } - Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ALL); + Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ALL, 0); playerA = createNewPlayer("ComputerA"); playerA.setTestMode(true); diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/CardTestPlayerBase.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/CardTestPlayerBase.java index f658dc686e..6abbe6eea1 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/CardTestPlayerBase.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/CardTestPlayerBase.java @@ -53,7 +53,7 @@ public abstract class CardTestPlayerBase extends CardTestPlayerAPIImpl { System.gc(); } - Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ONE); + Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ONE, 0); playerA = createNewPlayer("PlayerA"); playerA.setTestMode(true); @@ -108,7 +108,7 @@ public abstract class CardTestPlayerBase extends CardTestPlayerAPIImpl { System.gc(); } - Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ALL); + Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ALL, 0); playerA = createNewPlayer("ComputerA"); playerA.setTestMode(true); diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index a514606708..5a9627f369 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -137,6 +137,8 @@ public abstract class GameImpl> implements Game, Serializa protected transient GameStates gameStates = new GameStates(); protected RangeOfInfluence range; + protected int freeMulligans; + protected Map usedFreeMulligans = new LinkedHashMap(); protected MultiplayerAttackOption attackOption; protected GameOptions gameOptions; protected String startMessage; @@ -156,9 +158,10 @@ public abstract class GameImpl> implements Game, Serializa @Override public abstract T copy(); - public GameImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range) { + public GameImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, int freeMulligans) { this.id = UUID.randomUUID(); this.range = range; + this.freeMulligans = freeMulligans; this.attackOption = attackOption; this.state = new GameState(); this.actions = new LinkedList(); @@ -174,6 +177,7 @@ public abstract class GameImpl> implements Game, Serializa this.startingPlayerId = game.startingPlayerId; this.winnerId = game.winnerId; this.range = game.range; + this.freeMulligans = game.freeMulligans; this.attackOption = game.attackOption; this.state = game.state.copy(); // Issue 350 @@ -740,7 +744,18 @@ public abstract class GameImpl> implements Game, Serializa @Override public int mulliganDownTo(UUID playerId) { Player player = getPlayer(playerId); - return player.getHand().size() -1; + int deduction = 1; + if (freeMulligans > 0) { + if (usedFreeMulligans != null && usedFreeMulligans.containsKey(player.getId())) { + int used = usedFreeMulligans.get(player.getId()).intValue(); + if (used < freeMulligans ) { + deduction = 0; + } + } else { + deduction = 0; + } + } + return player.getHand().size() - deduction; } @@ -751,8 +766,25 @@ public abstract class GameImpl> implements Game, Serializa player.getLibrary().addAll(player.getHand().getCards(this), this); player.getHand().clear(); player.shuffleLibrary(this); - fireInformEvent(player.getName() + " mulligans down to " + Integer.toString(numCards - 1) + " cards"); - player.drawCards(numCards - 1, this); + int deduction = 1; + if (freeMulligans > 0) { + if (usedFreeMulligans != null && usedFreeMulligans.containsKey(player.getId())) { + int used = usedFreeMulligans.get(player.getId()).intValue(); + if (used < freeMulligans ) { + deduction = 0; + usedFreeMulligans.put(player.getId(), new Integer(used+1)); + } + } else { + deduction = 0; + usedFreeMulligans.put(player.getId(), new Integer(1)); + } + } + fireInformEvent(new StringBuilder(player.getName()) + .append(" mulligans") + .append(deduction == 0 ? " for free and draws ":" down to ") + .append(Integer.toString(numCards - deduction)) + .append(numCards - deduction == 1? " card":" cards").toString()); + player.drawCards(numCards - deduction, this); } @Override diff --git a/Mage/src/mage/game/match/Match.java b/Mage/src/mage/game/match/Match.java index 5fb3df7258..5722bb983f 100644 --- a/Mage/src/mage/game/match/Match.java +++ b/Mage/src/mage/game/match/Match.java @@ -64,6 +64,7 @@ public interface Match { Game getGame(); List getGames(); int getWinsNeeded(); + int getFreeMulligans(); int getNumGames(); boolean isDoneSideboarding(); UUID getChooser(); diff --git a/Mage/src/mage/game/match/MatchImpl.java b/Mage/src/mage/game/match/MatchImpl.java index 15a6a4c788..4d11d3e349 100644 --- a/Mage/src/mage/game/match/MatchImpl.java +++ b/Mage/src/mage/game/match/MatchImpl.java @@ -149,6 +149,11 @@ public abstract class MatchImpl implements Match { return options.getWinsNeeded(); } + @Override + public int getFreeMulligans() { + return options.getFreeMulligans(); + } + protected void initGame(Game game) throws GameException { shufflePlayers(); for (MatchPlayer matchPlayer: this.players) { diff --git a/Mage/src/mage/game/match/MatchOptions.java b/Mage/src/mage/game/match/MatchOptions.java index aedeb8647c..cfd5a66d8b 100644 --- a/Mage/src/mage/game/match/MatchOptions.java +++ b/Mage/src/mage/game/match/MatchOptions.java @@ -44,6 +44,7 @@ public class MatchOptions implements Serializable { protected MultiplayerAttackOption attackOption; protected RangeOfInfluence range; protected int winsNeeded; + protected int freeMulligans; protected String gameType; protected String deckType; protected boolean limited; @@ -82,6 +83,13 @@ public class MatchOptions implements Serializable { this.winsNeeded = winsNeeded; } + public int getFreeMulligans() { + return freeMulligans; + } + + public void setFreeMulligans(int freeMulligans) { + this.freeMulligans = freeMulligans; + } public String getGameType() { return gameType; } diff --git a/Mage/src/mage/game/tournament/LimitedOptions.java b/Mage/src/mage/game/tournament/LimitedOptions.java index 9983f3f2ed..dbe3abc543 100644 --- a/Mage/src/mage/game/tournament/LimitedOptions.java +++ b/Mage/src/mage/game/tournament/LimitedOptions.java @@ -39,9 +39,18 @@ import java.util.List; public class LimitedOptions implements Serializable { protected List sets = new ArrayList(); + protected int constructionTime; public List getSetCodes() { return sets; } + public int getConstructionTime() { + return constructionTime; + } + + public void setConstructionTime(int constructionTime) { + this.constructionTime = constructionTime; + } + } diff --git a/Mage/src/mage/game/tournament/TournamentImpl.java b/Mage/src/mage/game/tournament/TournamentImpl.java index a25ab5b7a4..5f4aeb42c7 100644 --- a/Mage/src/mage/game/tournament/TournamentImpl.java +++ b/Mage/src/mage/game/tournament/TournamentImpl.java @@ -28,6 +28,8 @@ package mage.game.tournament; +import java.util.*; +import java.util.concurrent.CopyOnWriteArrayList; import mage.cards.Card; import mage.cards.ExpansionSet; import mage.cards.decks.Deck; @@ -37,8 +39,6 @@ import mage.game.match.Match; import mage.players.Player; import org.apache.log4j.Logger; -import java.util.*; -import java.util.concurrent.CopyOnWriteArrayList; /** * @@ -61,8 +61,6 @@ public abstract class TournamentImpl implements Tournament { protected Date startTime; protected Date endTime; - private static final int CONSTRUCT_TIME = 600; - public TournamentImpl(TournamentOptions options) { this.options = options; startTime = new Date(); @@ -227,8 +225,9 @@ public abstract class TournamentImpl implements Tournament { @Override public boolean isDoneConstructing() { for (TournamentPlayer player: this.players.values()) { - if (!player.isDoneConstructing()) + if (!player.isDoneConstructing()) { return false; + } } return true; } @@ -236,8 +235,9 @@ public abstract class TournamentImpl implements Tournament { @Override public boolean allJoined() { for (TournamentPlayer player: this.players.values()) { - if (!player.isJoined()) + if (!player.isJoined()) { return false; + } } return true; } @@ -254,8 +254,7 @@ public abstract class TournamentImpl implements Tournament { @Override public void fireConstructEvent(UUID playerId) { - TournamentPlayer player = players.get(playerId); - playerQueryEventSource.construct(playerId, "Construct", CONSTRUCT_TIME); + playerQueryEventSource.construct(playerId, "Construct", getOptions().getLimitedOptions().getConstructionTime()); } public void construct() { diff --git a/Mage/src/mage/game/tournament/TournamentOptions.java b/Mage/src/mage/game/tournament/TournamentOptions.java index 70a23ab7f1..5667bfe232 100644 --- a/Mage/src/mage/game/tournament/TournamentOptions.java +++ b/Mage/src/mage/game/tournament/TournamentOptions.java @@ -39,6 +39,7 @@ import mage.game.match.MatchOptions; */ public class TournamentOptions implements Serializable { + protected String name; protected String tournamentType; protected List playerTypes = new ArrayList();