Add custom options for starting life total and starting hand size (#11259)

* add startHandSize / startLife to the custom option panel

* use the custom startLife/startHandsize in all Game Modes
This commit is contained in:
Susucre 2023-10-07 05:22:48 +02:00 committed by GitHub
parent 3e6097b70e
commit f14479c53c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
76 changed files with 1230 additions and 929 deletions

View file

@ -52,6 +52,8 @@
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="spnFreeMulligans" max="32767" attributes="0"/> <Component id="spnFreeMulligans" max="32767" attributes="0"/>
</Group> </Group>
<Component id="planechaseDescriptionLabel" alignment="0" max="32767" attributes="0"/>
<Component id="emblemCardsDescriptionLabel" alignment="0" max="32767" attributes="0"/>
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="lblVariantOptions" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="lblVariantOptions" alignment="0" min="-2" max="-2" attributes="0"/>
@ -63,8 +65,15 @@
</Group> </Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/> <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group> </Group>
<Component id="planechaseDescriptionLabel" alignment="0" max="32767" attributes="0"/> <Group type="102" alignment="0" attributes="0">
<Component id="emblemCardsDescriptionLabel" alignment="0" max="32767" attributes="0"/> <Component id="checkStartingLife" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="spnCustomLifeTotal" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="checkStartingHandSize" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="spnCustomStartingHand" min="-2" pref="46" max="-2" attributes="0"/>
</Group>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
@ -86,6 +95,17 @@
<Component id="lblFreeMulligans" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="lblFreeMulligans" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" alignment="0" groupAlignment="3" attributes="0">
<Component id="spnCustomStartingHand" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="checkStartingHandSize" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="spnCustomLifeTotal" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="checkStartingLife" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="jSeparator2" min="-2" max="-2" attributes="0"/> <Component id="jSeparator2" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="lblVariantOptions" min="-2" max="-2" attributes="0"/> <Component id="lblVariantOptions" min="-2" max="-2" attributes="0"/>
@ -321,5 +341,47 @@
<Property name="AccessibleContext.accessibleDescription" type="java.lang.String" value="Give players emblems with the abilities of cards.&#xa;Note that some abilities may not function correctly from the command zone.&#xa;If anything breaks, please report it on GitHub."/> <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" value="Give players emblems with the abilities of cards.&#xa;Note that some abilities may not function correctly from the command zone.&#xa;If anything breaks, please report it on GitHub."/>
</AccessibilityProperties> </AccessibilityProperties>
</Component> </Component>
<Component class="javax.swing.JSpinner" name="spnCustomLifeTotal">
<Properties>
<Property name="toolTipText" type="java.lang.String" value="Custom starting life total"/>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" value="Custom starting life total"/>
<Property name="AccessibleContext.accessibleDescription" type="java.lang.String" value="Set a custom starting life total"/>
</AccessibilityProperties>
<Events>
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="spnCustomLifeTotalStateChanged"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="checkStartingLife">
<Properties>
<Property name="toolTipText" type="java.lang.String" value="Check to use a specific starting life total"/>
<Property name="actionCommand" type="java.lang.String" value="checkCustomLife"/>
<Property name="horizontalTextPosition" type="int" value="10"/>
<Property name="label" type="java.lang.String" value="Custom Starting Life"/>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" value="Custom starting life"/>
</AccessibilityProperties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="checkStartingLifeActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="checkStartingHandSize">
<Properties>
<Property name="text" type="java.lang.String" value="Custom Starting Hand"/>
<Property name="toolTipText" type="java.lang.String" value="Check to use a specific starting hand size"/>
<Property name="actionCommand" type="java.lang.String" value="checkCustomHandSize"/>
<Property name="horizontalTextPosition" type="int" value="10"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="checkStartingHandSizeActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JSpinner" name="spnCustomStartingHand">
<Events>
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="spnCustomStartingHandStateChanged"/>
</Events>
</Component>
</SubComponents> </SubComponents>
</Form> </Form>

View file

@ -4,8 +4,6 @@ import mage.cards.decks.Deck;
import mage.cards.decks.DeckFileFilter; import mage.cards.decks.DeckFileFilter;
import mage.cards.decks.importer.DeckImporter; import mage.cards.decks.importer.DeckImporter;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence;
import mage.game.GameException; import mage.game.GameException;
import mage.game.match.MatchOptions; import mage.game.match.MatchOptions;
import mage.game.mulligan.MulliganType; import mage.game.mulligan.MulliganType;
@ -15,7 +13,6 @@ import javax.swing.*;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
/** /**
* App GUI: custom options for match/tournament * App GUI: custom options for match/tournament
@ -28,6 +25,10 @@ public class CustomOptionsDialog extends MageDialog {
TABLE( TABLE(
PreferencesDialog.KEY_NEW_TABLE_NUMBER_OF_FREE_MULLIGANS, PreferencesDialog.KEY_NEW_TABLE_NUMBER_OF_FREE_MULLIGANS,
PreferencesDialog.KEY_NEW_TABLE_MULLIGAN_TYPE, PreferencesDialog.KEY_NEW_TABLE_MULLIGAN_TYPE,
PreferencesDialog.KEY_NEW_TABLE_CUSTOM_STARTING_LIFE,
PreferencesDialog.KEY_NEW_TABLE_NUMBER_OF_LIFE_AT_START,
PreferencesDialog.KEY_NEW_TABLE_CUSTOM_STARTING_HAND_SIZE,
PreferencesDialog.KEY_NEW_TABLE_NUMBER_OF_HAND_SIZE_AT_START,
PreferencesDialog.KEY_NEW_TABLE_PLANECHASE, PreferencesDialog.KEY_NEW_TABLE_PLANECHASE,
PreferencesDialog.KEY_NEW_TABLE_EMBLEM_CARDS_ENABLED, PreferencesDialog.KEY_NEW_TABLE_EMBLEM_CARDS_ENABLED,
PreferencesDialog.KEY_NEW_TABLE_EMBLEM_CARDS_PER_PLAYER_FILE, PreferencesDialog.KEY_NEW_TABLE_EMBLEM_CARDS_PER_PLAYER_FILE,
@ -37,6 +38,10 @@ public class CustomOptionsDialog extends MageDialog {
TOURNEY( TOURNEY(
PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_FREE_MULLIGANS, PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_FREE_MULLIGANS,
PreferencesDialog.KEY_NEW_TOURNAMENT_MULLIGUN_TYPE, PreferencesDialog.KEY_NEW_TOURNAMENT_MULLIGUN_TYPE,
PreferencesDialog.KEY_NEW_TOURNAMENT_CUSTOM_STARTING_LIFE,
PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_LIFE_AT_START,
PreferencesDialog.KEY_NEW_TOURNAMENT_CUSTOM_STARTING_HAND_SIZE,
PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_HAND_SIZE_AT_START,
PreferencesDialog.KEY_NEW_TOURNAMENT_PLANE_CHASE, PreferencesDialog.KEY_NEW_TOURNAMENT_PLANE_CHASE,
PreferencesDialog.KEY_NEW_TOURNAMENT_EMBLEM_CARDS_ENABLED, PreferencesDialog.KEY_NEW_TOURNAMENT_EMBLEM_CARDS_ENABLED,
PreferencesDialog.KEY_NEW_TOURNAMENT_EMBLEM_CARDS_PER_PLAYER_FILE, PreferencesDialog.KEY_NEW_TOURNAMENT_EMBLEM_CARDS_PER_PLAYER_FILE,
@ -44,6 +49,10 @@ public class CustomOptionsDialog extends MageDialog {
); );
public final String NUMBER_OF_FREE_MULLIGANS; public final String NUMBER_OF_FREE_MULLIGANS;
public final String MULLIGAN_TYPE; public final String MULLIGAN_TYPE;
public final String BOOL_CUSTOM_STARTING_LIFE;
public final String NUMBER_OF_LIFE_AT_START;
public final String BOOL_CUSTOM_STARTING_HAND_SIZE;
public final String NUMBER_OF_HAND_SIZE_AT_START;
public final String PLANECHASE; public final String PLANECHASE;
public final String EMBLEM_CARDS_ENABLED; public final String EMBLEM_CARDS_ENABLED;
public final String EMBLEM_CARDS_PER_PLAYER_FILE; public final String EMBLEM_CARDS_PER_PLAYER_FILE;
@ -52,6 +61,10 @@ public class CustomOptionsDialog extends MageDialog {
SaveLoadKeys( SaveLoadKeys(
String numberOfFreeMulligans, String numberOfFreeMulligans,
String mulliganType, String mulliganType,
String customStartLife,
String valueStartLife,
String customStartHandSize,
String valueStartHandSize,
String planechase, String planechase,
String emblemCardsEnabled, String emblemCardsEnabled,
String emblemCardsPerPlayerFile, String emblemCardsPerPlayerFile,
@ -59,6 +72,10 @@ public class CustomOptionsDialog extends MageDialog {
) { ) {
NUMBER_OF_FREE_MULLIGANS = numberOfFreeMulligans; NUMBER_OF_FREE_MULLIGANS = numberOfFreeMulligans;
MULLIGAN_TYPE = mulliganType; MULLIGAN_TYPE = mulliganType;
BOOL_CUSTOM_STARTING_LIFE = customStartLife;
NUMBER_OF_LIFE_AT_START = valueStartLife;
BOOL_CUSTOM_STARTING_HAND_SIZE = customStartHandSize;
NUMBER_OF_HAND_SIZE_AT_START = valueStartHandSize;
PLANECHASE = planechase; PLANECHASE = planechase;
EMBLEM_CARDS_ENABLED = emblemCardsEnabled; EMBLEM_CARDS_ENABLED = emblemCardsEnabled;
EMBLEM_CARDS_PER_PLAYER_FILE = emblemCardsPerPlayerFile; EMBLEM_CARDS_PER_PLAYER_FILE = emblemCardsPerPlayerFile;
@ -81,6 +98,10 @@ public class CustomOptionsDialog extends MageDialog {
initComponents(); initComponents();
this.spnFreeMulligans.setModel(new SpinnerNumberModel(0, 0, 5, 1)); this.spnFreeMulligans.setModel(new SpinnerNumberModel(0, 0, 5, 1));
cbMulliganType.setModel(new DefaultComboBoxModel(MulliganType.values())); cbMulliganType.setModel(new DefaultComboBoxModel(MulliganType.values()));
this.spnCustomLifeTotal.setModel(new SpinnerNumberModel(20, 1, 100, 1));
this.spnCustomLifeTotal.setEnabled(false);
this.spnCustomStartingHand.setModel(new SpinnerNumberModel(7, 0, 20, 1));
this.spnCustomStartingHand.setEnabled(false);
this.setModal(true); this.setModal(true);
fcSelectEmblemCardsPerPlayer = new JFileChooser(); fcSelectEmblemCardsPerPlayer = new JFileChooser();
fcSelectEmblemCardsPerPlayer.setAcceptAllFileFilterUsed(false); fcSelectEmblemCardsPerPlayer.setAcceptAllFileFilterUsed(false);
@ -119,6 +140,10 @@ public class CustomOptionsDialog extends MageDialog {
txtEmblemCardsStartingPlayer = new javax.swing.JTextField(); txtEmblemCardsStartingPlayer = new javax.swing.JTextField();
lblEmblemCardsStartingPlayer = new javax.swing.JLabel(); lblEmblemCardsStartingPlayer = new javax.swing.JLabel();
emblemCardsDescriptionLabel = new javax.swing.JLabel(); emblemCardsDescriptionLabel = new javax.swing.JLabel();
spnCustomLifeTotal = new javax.swing.JSpinner();
checkStartingLife = new javax.swing.JCheckBox();
checkStartingHandSize = new javax.swing.JCheckBox();
spnCustomStartingHand = new javax.swing.JSpinner();
setTitle("Custom Options"); setTitle("Custom Options");
@ -211,6 +236,39 @@ public class CustomOptionsDialog extends MageDialog {
emblemCardsDescriptionLabel.setText("<html>Give players emblems with the abilities of cards.<br>Note that some abilities may not function correctly from the command zone.<br>If anything breaks, please report it on GitHub."); emblemCardsDescriptionLabel.setText("<html>Give players emblems with the abilities of cards.<br>Note that some abilities may not function correctly from the command zone.<br>If anything breaks, please report it on GitHub.");
emblemCardsDescriptionLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP); emblemCardsDescriptionLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP);
spnCustomLifeTotal.setToolTipText("Custom starting life total");
spnCustomLifeTotal.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
spnCustomLifeTotalStateChanged(evt);
}
});
checkStartingLife.setToolTipText("Check to use a specific starting life total");
checkStartingLife.setActionCommand("checkCustomLife");
checkStartingLife.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
checkStartingLife.setLabel("Custom Starting Life");
checkStartingLife.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
checkStartingLifeActionPerformed(evt);
}
});
checkStartingHandSize.setText("Custom Starting Hand");
checkStartingHandSize.setToolTipText("Check to use a specific starting hand size");
checkStartingHandSize.setActionCommand("checkCustomHandSize");
checkStartingHandSize.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
checkStartingHandSize.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
checkStartingHandSizeActionPerformed(evt);
}
});
spnCustomStartingHand.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
spnCustomStartingHandStateChanged(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout); getContentPane().setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
@ -240,6 +298,8 @@ public class CustomOptionsDialog extends MageDialog {
.addComponent(lblFreeMulligans) .addComponent(lblFreeMulligans)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(spnFreeMulligans)) .addComponent(spnFreeMulligans))
.addComponent(planechaseDescriptionLabel)
.addComponent(emblemCardsDescriptionLabel)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblVariantOptions) .addComponent(lblVariantOptions)
@ -249,8 +309,14 @@ public class CustomOptionsDialog extends MageDialog {
.addComponent(lblEmblemCardsStartingPlayer) .addComponent(lblEmblemCardsStartingPlayer)
.addComponent(lblGeneralOptions)) .addComponent(lblGeneralOptions))
.addGap(0, 0, Short.MAX_VALUE)) .addGap(0, 0, Short.MAX_VALUE))
.addComponent(planechaseDescriptionLabel) .addGroup(layout.createSequentialGroup()
.addComponent(emblemCardsDescriptionLabel)) .addComponent(checkStartingLife)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(spnCustomLifeTotal)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(checkStartingHandSize)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(spnCustomStartingHand, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap()) .addContainerGap())
); );
layout.setVerticalGroup( layout.setVerticalGroup(
@ -267,6 +333,14 @@ public class CustomOptionsDialog extends MageDialog {
.addComponent(spnFreeMulligans, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(spnFreeMulligans, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblFreeMulligans)) .addComponent(lblFreeMulligans))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(spnCustomStartingHand, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(checkStartingHandSize))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(spnCustomLifeTotal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(checkStartingLife)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lblVariantOptions) .addComponent(lblVariantOptions)
@ -317,6 +391,9 @@ public class CustomOptionsDialog extends MageDialog {
lblEmblemCardsStartingPlayer.getAccessibleContext().setAccessibleParent(chkEmblemCards); lblEmblemCardsStartingPlayer.getAccessibleContext().setAccessibleParent(chkEmblemCards);
emblemCardsDescriptionLabel.getAccessibleContext().setAccessibleName("Emblem Cards description"); emblemCardsDescriptionLabel.getAccessibleContext().setAccessibleName("Emblem Cards description");
emblemCardsDescriptionLabel.getAccessibleContext().setAccessibleDescription("Give players emblems with the abilities of cards.\nNote that some abilities may not function correctly from the command zone.\nIf anything breaks, please report it on GitHub."); emblemCardsDescriptionLabel.getAccessibleContext().setAccessibleDescription("Give players emblems with the abilities of cards.\nNote that some abilities may not function correctly from the command zone.\nIf anything breaks, please report it on GitHub.");
spnCustomLifeTotal.getAccessibleContext().setAccessibleName("Custom starting life total");
spnCustomLifeTotal.getAccessibleContext().setAccessibleDescription("Set a custom starting life total");
checkStartingLife.getAccessibleContext().setAccessibleName("Custom starting life");
pack(); pack();
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
@ -360,10 +437,27 @@ public class CustomOptionsDialog extends MageDialog {
}//GEN-LAST:event_txtEmblemCardsStartingPlayerActionPerformed }//GEN-LAST:event_txtEmblemCardsStartingPlayerActionPerformed
private void spnCustomLifeTotalStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnCustomLifeTotalStateChanged
updateActiveCount();
}//GEN-LAST:event_spnCustomLifeTotalStateChanged
private void spnCustomStartingHandStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnCustomStartingHandStateChanged
updateActiveCount();
}//GEN-LAST:event_spnCustomStartingHandStateChanged
private void checkStartingLifeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkStartingLifeActionPerformed
updateActiveCount();
}//GEN-LAST:event_checkStartingLifeActionPerformed
private void checkStartingHandSizeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkStartingHandSizeActionPerformed
updateActiveCount();
}//GEN-LAST:event_checkStartingHandSizeActionPerformed
public void showDialog() { public void showDialog() {
this.setLocation(150, 100); this.setLocation(150, 100);
this.setVisible(true); this.setVisible(true);
} }
private void loadEmblemCardFile(boolean isStartingPlayer) { private void loadEmblemCardFile(boolean isStartingPlayer) {
JFileChooser fileChooser = isStartingPlayer ? fcSelectEmblemCardsStartingPlayer : fcSelectEmblemCardsPerPlayer; JFileChooser fileChooser = isStartingPlayer ? fcSelectEmblemCardsStartingPlayer : fcSelectEmblemCardsPerPlayer;
JTextField textField = isStartingPlayer ? txtEmblemCardsStartingPlayer : txtEmblemCardsPerPlayer; JTextField textField = isStartingPlayer ? txtEmblemCardsStartingPlayer : txtEmblemCardsPerPlayer;
@ -406,6 +500,10 @@ public class CustomOptionsDialog extends MageDialog {
this.chkPlaneChase.setSelected(PreferencesDialog.getCachedValue(saveLoadKeys.PLANECHASE + versionStr, "No").equals("Yes")); this.chkPlaneChase.setSelected(PreferencesDialog.getCachedValue(saveLoadKeys.PLANECHASE + versionStr, "No").equals("Yes"));
this.spnFreeMulligans.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(saveLoadKeys.NUMBER_OF_FREE_MULLIGANS + versionStr, "0"))); this.spnFreeMulligans.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(saveLoadKeys.NUMBER_OF_FREE_MULLIGANS + versionStr, "0")));
this.cbMulliganType.setSelectedItem(MulliganType.valueByName(PreferencesDialog.getCachedValue(saveLoadKeys.MULLIGAN_TYPE + versionStr, MulliganType.GAME_DEFAULT.toString()))); this.cbMulliganType.setSelectedItem(MulliganType.valueByName(PreferencesDialog.getCachedValue(saveLoadKeys.MULLIGAN_TYPE + versionStr, MulliganType.GAME_DEFAULT.toString())));
this.checkStartingLife.setSelected(PreferencesDialog.getCachedValue(saveLoadKeys.BOOL_CUSTOM_STARTING_LIFE + versionStr, "No").equals("Yes"));
this.spnCustomLifeTotal.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(saveLoadKeys.NUMBER_OF_LIFE_AT_START + versionStr, "20")));
this.checkStartingHandSize.setSelected(PreferencesDialog.getCachedValue(saveLoadKeys.BOOL_CUSTOM_STARTING_HAND_SIZE + versionStr, "No").equals("Yes"));
this.spnCustomStartingHand.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(saveLoadKeys.NUMBER_OF_HAND_SIZE_AT_START + versionStr, "7")));
this.chkEmblemCards.setSelected(PreferencesDialog.getCachedValue(saveLoadKeys.EMBLEM_CARDS_ENABLED + versionStr, "No").equals("Yes")); this.chkEmblemCards.setSelected(PreferencesDialog.getCachedValue(saveLoadKeys.EMBLEM_CARDS_ENABLED + versionStr, "No").equals("Yes"));
this.txtEmblemCardsPerPlayer.setText(PreferencesDialog.getCachedValue(saveLoadKeys.EMBLEM_CARDS_PER_PLAYER_FILE, "")); this.txtEmblemCardsPerPlayer.setText(PreferencesDialog.getCachedValue(saveLoadKeys.EMBLEM_CARDS_PER_PLAYER_FILE, ""));
this.txtEmblemCardsStartingPlayer.setText(PreferencesDialog.getCachedValue(saveLoadKeys.EMBLEM_CARDS_STARTING_PLAYER_FILE, "")); this.txtEmblemCardsStartingPlayer.setText(PreferencesDialog.getCachedValue(saveLoadKeys.EMBLEM_CARDS_STARTING_PLAYER_FILE, ""));
@ -427,6 +525,10 @@ public class CustomOptionsDialog extends MageDialog {
} }
PreferencesDialog.saveValue(saveLoadKeys.NUMBER_OF_FREE_MULLIGANS + versionStr, Integer.toString(options.getFreeMulligans())); PreferencesDialog.saveValue(saveLoadKeys.NUMBER_OF_FREE_MULLIGANS + versionStr, Integer.toString(options.getFreeMulligans()));
PreferencesDialog.saveValue(saveLoadKeys.MULLIGAN_TYPE + versionStr, options.getMulliganType().toString()); PreferencesDialog.saveValue(saveLoadKeys.MULLIGAN_TYPE + versionStr, options.getMulliganType().toString());
PreferencesDialog.saveValue(saveLoadKeys.BOOL_CUSTOM_STARTING_LIFE + versionStr, options.isCustomStartLifeEnabled() ? "Yes" : "No");
PreferencesDialog.saveValue(saveLoadKeys.NUMBER_OF_LIFE_AT_START + versionStr, Integer.toString(options.getCustomStartLife()));
PreferencesDialog.saveValue(saveLoadKeys.BOOL_CUSTOM_STARTING_HAND_SIZE + versionStr, options.isCustomStartHandSizeEnabled() ? "Yes" : "No");
PreferencesDialog.saveValue(saveLoadKeys.NUMBER_OF_HAND_SIZE_AT_START + versionStr, Integer.toString(options.getCustomStartHandSize()));
PreferencesDialog.saveValue(saveLoadKeys.PLANECHASE + versionStr, options.isPlaneChase() ? "Yes" : "No"); PreferencesDialog.saveValue(saveLoadKeys.PLANECHASE + versionStr, options.isPlaneChase() ? "Yes" : "No");
PreferencesDialog.saveValue(saveLoadKeys.EMBLEM_CARDS_ENABLED + versionStr, PreferencesDialog.saveValue(saveLoadKeys.EMBLEM_CARDS_ENABLED + versionStr,
!(options.getGlobalEmblemCards().isEmpty() && options.getPerPlayerEmblemCards().isEmpty()) ? "Yes" : "No"); !(options.getGlobalEmblemCards().isEmpty() && options.getPerPlayerEmblemCards().isEmpty()) ? "Yes" : "No");
@ -440,6 +542,10 @@ public class CustomOptionsDialog extends MageDialog {
public void writeMatchOptionsTo(MatchOptions options) { public void writeMatchOptionsTo(MatchOptions options) {
options.setFreeMulligans((Integer) spnFreeMulligans.getValue()); options.setFreeMulligans((Integer) spnFreeMulligans.getValue());
options.setMullgianType((MulliganType) cbMulliganType.getSelectedItem()); options.setMullgianType((MulliganType) cbMulliganType.getSelectedItem());
options.setCustomStartLifeEnabled(checkStartingLife.isSelected());
options.setCustomStartLife((Integer) spnCustomLifeTotal.getValue());
options.setCustomStartHandSizeEnabled(checkStartingHandSize.isSelected());
options.setCustomStartHandSize((Integer) spnCustomStartingHand.getValue());
options.setPlaneChase(chkPlaneChase.isSelected()); options.setPlaneChase(chkPlaneChase.isSelected());
if (chkEmblemCards.isSelected()) { if (chkEmblemCards.isSelected()) {
if (!txtEmblemCardsPerPlayer.getText().isEmpty()) { if (!txtEmblemCardsPerPlayer.getText().isEmpty()) {
@ -452,8 +558,7 @@ public class CustomOptionsDialog extends MageDialog {
if (perPlayerEmblemDeck != null) { if (perPlayerEmblemDeck != null) {
perPlayerEmblemDeck.clearLayouts(); perPlayerEmblemDeck.clearLayouts();
options.setPerPlayerEmblemCards(perPlayerEmblemDeck.getDeckCardLists().getCards()); options.setPerPlayerEmblemCards(perPlayerEmblemDeck.getDeckCardLists().getCards());
} } else {
else {
options.setPerPlayerEmblemCards(Collections.emptySet()); options.setPerPlayerEmblemCards(Collections.emptySet());
} }
} }
@ -467,13 +572,11 @@ public class CustomOptionsDialog extends MageDialog {
if (startingPlayerEmblemDeck != null) { if (startingPlayerEmblemDeck != null) {
startingPlayerEmblemDeck.clearLayouts(); startingPlayerEmblemDeck.clearLayouts();
options.setGlobalEmblemCards(startingPlayerEmblemDeck.getDeckCardLists().getCards()); options.setGlobalEmblemCards(startingPlayerEmblemDeck.getDeckCardLists().getCards());
} } else {
else {
options.setGlobalEmblemCards(Collections.emptySet()); options.setGlobalEmblemCards(Collections.emptySet());
} }
} }
} } else {
else {
options.setPerPlayerEmblemCards(Collections.emptySet()); options.setPerPlayerEmblemCards(Collections.emptySet());
options.setGlobalEmblemCards(Collections.emptySet()); options.setGlobalEmblemCards(Collections.emptySet());
} }
@ -481,14 +584,17 @@ public class CustomOptionsDialog extends MageDialog {
public void updateActiveCount() { public void updateActiveCount() {
int activeCount = 0; int activeCount = 0;
if ((Integer)spnFreeMulligans.getValue() > 0) activeCount++; if ((Integer) spnFreeMulligans.getValue() > 0) activeCount++;
if (checkStartingLife.isSelected()) activeCount++;
spnCustomLifeTotal.setEnabled(checkStartingLife.isSelected());
if (checkStartingHandSize.isSelected()) activeCount++;
spnCustomStartingHand.setEnabled(checkStartingHandSize.isSelected());
if (!cbMulliganType.getSelectedItem().toString().equals(MulliganType.GAME_DEFAULT.toString())) activeCount++; if (!cbMulliganType.getSelectedItem().toString().equals(MulliganType.GAME_DEFAULT.toString())) activeCount++;
if (chkPlaneChase.isSelected()) activeCount++; if (chkPlaneChase.isSelected()) activeCount++;
if (chkEmblemCards.isSelected()) activeCount++; if (chkEmblemCards.isSelected()) activeCount++;
if (activeCount == 0) { if (activeCount == 0) {
openButton.setText("Custom Options..."); openButton.setText("Custom Options...");
} } else {
else {
openButton.setText("Custom Options (" + activeCount + ")"); openButton.setText("Custom Options (" + activeCount + ")");
} }
} }
@ -498,6 +604,8 @@ public class CustomOptionsDialog extends MageDialog {
private javax.swing.JButton btnEmblemCardsStartingPlayer; private javax.swing.JButton btnEmblemCardsStartingPlayer;
private javax.swing.JButton btnOK; private javax.swing.JButton btnOK;
private javax.swing.JComboBox<String> cbMulliganType; private javax.swing.JComboBox<String> cbMulliganType;
private javax.swing.JCheckBox checkStartingHandSize;
private javax.swing.JCheckBox checkStartingLife;
private javax.swing.JCheckBox chkEmblemCards; private javax.swing.JCheckBox chkEmblemCards;
private javax.swing.JCheckBox chkPlaneChase; private javax.swing.JCheckBox chkPlaneChase;
private javax.swing.JLabel emblemCardsDescriptionLabel; private javax.swing.JLabel emblemCardsDescriptionLabel;
@ -511,6 +619,8 @@ public class CustomOptionsDialog extends MageDialog {
private javax.swing.JLabel lblMulliganType; private javax.swing.JLabel lblMulliganType;
private javax.swing.JLabel lblVariantOptions; private javax.swing.JLabel lblVariantOptions;
private javax.swing.JLabel planechaseDescriptionLabel; private javax.swing.JLabel planechaseDescriptionLabel;
private javax.swing.JSpinner spnCustomLifeTotal;
private javax.swing.JSpinner spnCustomStartingHand;
private javax.swing.JSpinner spnFreeMulligans; private javax.swing.JSpinner spnFreeMulligans;
private javax.swing.JTextField txtEmblemCardsPerPlayer; private javax.swing.JTextField txtEmblemCardsPerPlayer;
private javax.swing.JTextField txtEmblemCardsStartingPlayer; private javax.swing.JTextField txtEmblemCardsStartingPlayer;

View file

@ -288,7 +288,7 @@ public class TestCardRenderDialog extends MageDialog {
cardsPanel.addCardEventListener(this.cardListener); cardsPanel.addCardEventListener(this.cardListener);
} }
game = new TestGame(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20); game = new TestGame(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20, 7);
Deck deck = new Deck(); Deck deck = new Deck();
Player playerYou = new StubPlayer("player1", RangeOfInfluence.ALL); Player playerYou = new StubPlayer("player1", RangeOfInfluence.ALL);
game.addPlayer(playerYou, deck); game.addPlayer(playerYou, deck);
@ -750,8 +750,8 @@ class TestGame extends GameImpl {
private int numPlayers; private int numPlayers;
public TestGame(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public TestGame(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, startLife, 60, 7); super(attackOption, range, mulligan, 60, startLife, startHandSize);
} }
public TestGame(final TestGame game) { public TestGame(final TestGame game) {

View file

@ -101,12 +101,18 @@ public class TableView implements Serializable {
addInfo.append("Wins:").append(table.getMatch().getWinsNeeded()); addInfo.append("Wins:").append(table.getMatch().getWinsNeeded());
addInfo.append(" Time: ").append(table.getMatch().getOptions().getMatchTimeLimit().toString()); addInfo.append(" Time: ").append(table.getMatch().getOptions().getMatchTimeLimit().toString());
addInfo.append(" Buffer: ").append(table.getMatch().getOptions().getMatchBufferTime().toString()); addInfo.append(" Buffer: ").append(table.getMatch().getOptions().getMatchBufferTime().toString());
if (table.getMatch().getOptions().getMulliganType() != MulliganType.GAME_DEFAULT){ if (table.getMatch().getOptions().getMulliganType() != MulliganType.GAME_DEFAULT) {
addInfo.append(" Mulligan: \"").append(table.getMatch().getOptions().getMulliganType().toString()).append("\""); addInfo.append(" Mulligan: \"").append(table.getMatch().getOptions().getMulliganType().toString()).append("\"");
} }
if (table.getMatch().getFreeMulligans() > 0) { if (table.getMatch().getFreeMulligans() > 0) {
addInfo.append(" FM: ").append(table.getMatch().getFreeMulligans()); addInfo.append(" FM: ").append(table.getMatch().getFreeMulligans());
} }
if (table.getMatch().getOptions().isCustomStartLifeEnabled()) {
addInfo.append(" StartLife: ").append(table.getMatch().getOptions().getCustomStartLife());
}
if (table.getMatch().getOptions().isCustomStartHandSizeEnabled()) {
addInfo.append(" StartHandSize: ").append(table.getMatch().getOptions().getCustomStartHandSize());
}
} else { } else {
addInfo.append("Wins:").append(table.getMatch().getWinsNeeded()); addInfo.append("Wins:").append(table.getMatch().getWinsNeeded());
addInfo.append(sbScore.toString()); addInfo.append(sbScore.toString());
@ -118,7 +124,7 @@ public class TableView implements Serializable {
addInfo.append(" PC"); addInfo.append(" PC");
} }
if (!(table.getMatch().getOptions().getPerPlayerEmblemCards().isEmpty()) if (!(table.getMatch().getOptions().getPerPlayerEmblemCards().isEmpty())
|| !(table.getMatch().getOptions().getGlobalEmblemCards().isEmpty())) { || !(table.getMatch().getOptions().getGlobalEmblemCards().isEmpty())) {
addInfo.append(" EC"); addInfo.append(" EC");
} }
if (table.getMatch().getOptions().isSpectatorsAllowed()) { if (table.getMatch().getOptions().isSpectatorsAllowed()) {
@ -162,12 +168,18 @@ public class TableView implements Serializable {
MatchOptions tourneyMatchOptions = table.getTournament().getOptions().getMatchOptions(); MatchOptions tourneyMatchOptions = table.getTournament().getOptions().getMatchOptions();
infoText.append(" Time: ").append(tourneyMatchOptions.getMatchTimeLimit().toString()); infoText.append(" Time: ").append(tourneyMatchOptions.getMatchTimeLimit().toString());
infoText.append(" Buffer: ").append(tourneyMatchOptions.getMatchBufferTime().toString()); infoText.append(" Buffer: ").append(tourneyMatchOptions.getMatchBufferTime().toString());
if (tourneyMatchOptions.getMulliganType() != MulliganType.GAME_DEFAULT){ if (tourneyMatchOptions.getMulliganType() != MulliganType.GAME_DEFAULT) {
infoText.append(" Mulligan: \"").append(tourneyMatchOptions.getMulliganType().toString()).append("\""); infoText.append(" Mulligan: \"").append(tourneyMatchOptions.getMulliganType().toString()).append("\"");
} }
if (tourneyMatchOptions.getFreeMulligans() > 0) { if (tourneyMatchOptions.getFreeMulligans() > 0) {
infoText.append(" FM: ").append(tourneyMatchOptions.getFreeMulligans()); infoText.append(" FM: ").append(tourneyMatchOptions.getFreeMulligans());
} }
if (table.getMatch().getOptions().isCustomStartLifeEnabled()) {
infoText.append(" StartLife: ").append(table.getMatch().getOptions().getCustomStartLife());
}
if (table.getMatch().getOptions().isCustomStartHandSizeEnabled()) {
infoText.append(" StartHandSize: ").append(table.getMatch().getOptions().getCustomStartHandSize());
}
if (table.getTournament().getTournamentType().isLimited()) { if (table.getTournament().getTournamentType().isLimited()) {
infoText.append(" Constr.: ").append(table.getTournament().getOptions().getLimitedOptions().getConstructionTime() / 60).append(" Min."); infoText.append(" Constr.: ").append(table.getTournament().getOptions().getLimitedOptions().getConstructionTime() / 60).append(" Min.");
} }
@ -188,7 +200,7 @@ public class TableView implements Serializable {
if (table.getTournament().getOptions().isWatchingAllowed()) { if (table.getTournament().getOptions().isWatchingAllowed()) {
infoText.append(" SP"); infoText.append(" SP");
} }
break; break;
case DUELING: case DUELING:
stateText.append(" Round: ").append(table.getTournament().getRounds().size()); stateText.append(" Round: ").append(table.getTournament().getRounds().size());

View file

@ -8,9 +8,9 @@ import mage.game.match.MatchType;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
public class BrawlDuel extends GameCommanderImpl { public class BrawlDuel extends GameCommanderImpl {
public BrawlDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public BrawlDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, startLife, 60); super(attackOption, range, mulligan, 60, startLife, startHandSize);
} }
public BrawlDuel(final BrawlDuel game) { public BrawlDuel(final BrawlDuel game) {

View file

@ -17,7 +17,12 @@ public class BrawlDuelMatch extends MatchImpl {
public void startGame() throws GameException { public void startGame() throws GameException {
int startLife = 25; int startLife = 25;
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
BrawlDuel game = new BrawlDuel(options.getAttackOption(), options.getRange(), mulligan, startLife); startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : startLife;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
BrawlDuel game = new BrawlDuel(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setCheckCommanderDamage(false); game.setCheckCommanderDamage(false);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
initGame(game); initGame(game);

View file

@ -2,22 +2,22 @@
package mage.game; package mage.game;
import java.util.UUID;
import mage.constants.MultiplayerAttackOption; import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence; import mage.constants.RangeOfInfluence;
import mage.game.match.MatchType; import mage.game.match.MatchType;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
import java.util.UUID;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public class BrawlFreeForAll extends GameCommanderImpl { public class BrawlFreeForAll extends GameCommanderImpl {
private int numPlayers; private int numPlayers;
public BrawlFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public BrawlFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, startLife, 60); super(attackOption, range, mulligan, 60, startLife, startHandSize);
} }
public BrawlFreeForAll(final BrawlFreeForAll game) { public BrawlFreeForAll(final BrawlFreeForAll game) {
@ -28,7 +28,7 @@ public class BrawlFreeForAll extends GameCommanderImpl {
@Override @Override
protected void init(UUID choosingPlayerId) { protected void init(UUID choosingPlayerId) {
startingPlayerSkipsDraw = false; startingPlayerSkipsDraw = false;
super.init(choosingPlayerId); super.init(choosingPlayerId);
} }
@Override @Override

View file

@ -17,7 +17,12 @@ public class BrawlFreeForAllMatch extends MatchImpl {
public void startGame() throws GameException { public void startGame() throws GameException {
int startLife = 30; int startLife = 30;
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
BrawlFreeForAll game = new BrawlFreeForAll(options.getAttackOption(), options.getRange(), mulligan, startLife); startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : startLife;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
BrawlFreeForAll game = new BrawlFreeForAll(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
game.setCheckCommanderDamage(false); game.setCheckCommanderDamage(false);
initGame(game); initGame(game);

View file

@ -8,9 +8,9 @@ import mage.game.match.MatchType;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
public class CanadianHighlanderDuel extends GameCanadianHighlanderImpl { public class CanadianHighlanderDuel extends GameCanadianHighlanderImpl {
public CanadianHighlanderDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public CanadianHighlanderDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, startHandSize);
} }
public CanadianHighlanderDuel(final CanadianHighlanderDuel game) { public CanadianHighlanderDuel(final CanadianHighlanderDuel game) {

View file

@ -7,7 +7,6 @@ import mage.game.mulligan.Mulligan;
import mage.game.mulligan.MulliganType; import mage.game.mulligan.MulliganType;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public class CanadianHighlanderDuelMatch extends MatchImpl { public class CanadianHighlanderDuelMatch extends MatchImpl {
@ -20,7 +19,12 @@ public class CanadianHighlanderDuelMatch extends MatchImpl {
public void startGame() throws GameException { public void startGame() throws GameException {
int startLife = 20; int startLife = 20;
Mulligan mulligan = options.getMulliganType().orDefault(MulliganType.CANADIAN_HIGHLANDER).getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().orDefault(MulliganType.CANADIAN_HIGHLANDER).getMulligan(options.getFreeMulligans());
CanadianHighlanderDuel game = new CanadianHighlanderDuel(options.getAttackOption(), options.getRange(), mulligan, startLife); startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : startLife;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
CanadianHighlanderDuel game = new CanadianHighlanderDuel(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
initGame(game); initGame(game);
games.add(game); games.add(game);

View file

@ -8,9 +8,9 @@ import mage.game.match.MatchType;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
public class CommanderDuel extends GameCommanderImpl { public class CommanderDuel extends GameCommanderImpl {
public CommanderDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public CommanderDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, startLife, 100); super(attackOption, range, mulligan, 100, startLife, startHandSize);
} }
public CommanderDuel(final CommanderDuel game) { public CommanderDuel(final CommanderDuel game) {

View file

@ -29,7 +29,12 @@ public class CommanderDuelMatch extends MatchImpl {
startLife = 25; startLife = 25;
} }
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
CommanderDuel game = new CommanderDuel(options.getAttackOption(), options.getRange(), mulligan, startLife); startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : startLife;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
CommanderDuel game = new CommanderDuel(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setCheckCommanderDamage(checkCommanderDamage); game.setCheckCommanderDamage(checkCommanderDamage);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
initGame(game); initGame(game);

View file

@ -16,8 +16,8 @@ public class CommanderFreeForAll extends GameCommanderImpl {
private int numPlayers; private int numPlayers;
public CommanderFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public CommanderFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, startLife, 100); super(attackOption, range, mulligan, 100, startLife, startHandSize);
} }
public CommanderFreeForAll(final CommanderFreeForAll game) { public CommanderFreeForAll(final CommanderFreeForAll game) {

View file

@ -20,7 +20,12 @@ public class CommanderFreeForAllMatch extends MatchImpl {
startLife = 30; startLife = 30;
} }
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
CommanderFreeForAll game = new CommanderFreeForAll(options.getAttackOption(), options.getRange(), mulligan, startLife); startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : startLife;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
CommanderFreeForAll game = new CommanderFreeForAll(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
initGame(game); initGame(game);
games.add(game); games.add(game);

View file

@ -49,8 +49,8 @@ import java.util.UUID;
*/ */
public class CustomPillarOfTheParunsDuel extends GameImpl { public class CustomPillarOfTheParunsDuel extends GameImpl {
public CustomPillarOfTheParunsDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan) { public CustomPillarOfTheParunsDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, 25, 40, 6); super(attackOption, range, mulligan, 40, startLife, startHandSize);
} }
@Override @Override
@ -58,10 +58,10 @@ public class CustomPillarOfTheParunsDuel extends GameImpl {
super.init(choosingPlayerId); super.init(choosingPlayerId);
getPlayers().forEach((playerId, p) -> { getPlayers().forEach((playerId, p) -> {
addDelayedTriggeredAbility( addDelayedTriggeredAbility(
new AtTheBeginOfPlayerFirstMainPhase(playerId, "C-Pillar of the Paruns"), new AtTheBeginOfPlayerFirstMainPhase(playerId, "C-Pillar of the Paruns"),
null // TODO: Not sure how to mock something to be displayed instead. null // TODO: Not sure how to mock something to be displayed instead.
); );
}); });
state.getTurnMods().add(new TurnMod(startingPlayerId).withSkipStep(PhaseStep.DRAW)); state.getTurnMods().add(new TurnMod(startingPlayerId).withSkipStep(PhaseStep.DRAW));

View file

@ -16,7 +16,12 @@ public class CustomPillarOfTheParunsDuelMatch extends MatchImpl {
@Override @Override
public void startGame() throws GameException { public void startGame() throws GameException {
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
CustomPillarOfTheParunsDuel game = new CustomPillarOfTheParunsDuel(options.getAttackOption(), options.getRange(), mulligan); int startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : 25;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 6;
CustomPillarOfTheParunsDuel game = new CustomPillarOfTheParunsDuel(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
initGame(game); initGame(game);

View file

@ -7,15 +7,15 @@ import mage.game.match.MatchType;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class FreeForAll extends GameImpl { public class FreeForAll extends GameImpl {
private int numPlayers; private int numPlayers;
public FreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public FreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range,
super(attackOption, range, mulligan, startLife, 60, 7); Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, 60, startLife, startHandSize);
} }
public FreeForAll(final FreeForAll game) { public FreeForAll(final FreeForAll game) {

View file

@ -7,7 +7,6 @@ import mage.game.match.MatchOptions;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class FreeForAllMatch extends MatchImpl { public class FreeForAllMatch extends MatchImpl {
@ -19,7 +18,12 @@ public class FreeForAllMatch extends MatchImpl {
@Override @Override
public void startGame() throws GameException { public void startGame() throws GameException {
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
FreeForAll game = new FreeForAll(options.getAttackOption(), options.getRange(), mulligan, 20); int startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : 20;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
FreeForAll game = new FreeForAll(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
initGame(game); initGame(game);
games.add(game); games.add(game);

View file

@ -10,8 +10,9 @@ import mage.game.mulligan.Mulligan;
*/ */
public class FreeformCommanderDuel extends GameCommanderImpl { public class FreeformCommanderDuel extends GameCommanderImpl {
public FreeformCommanderDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public FreeformCommanderDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range,
super(attackOption, range, mulligan, startLife, 60); Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, 60, startLife, startHandSize);
} }
public FreeformCommanderDuel(final FreeformCommanderDuel game) { public FreeformCommanderDuel(final FreeformCommanderDuel game) {

View file

@ -18,7 +18,12 @@ public class FreeformCommanderDuelMatch extends MatchImpl {
int startLife = 40; int startLife = 40;
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
FreeformCommanderDuel game = new FreeformCommanderDuel(options.getAttackOption(), options.getRange(), mulligan, startLife); startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : startLife;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
FreeformCommanderDuel game = new FreeformCommanderDuel(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setCheckCommanderDamage(true); game.setCheckCommanderDamage(true);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
initGame(game); initGame(game);

View file

@ -2,22 +2,23 @@
package mage.game; package mage.game;
import java.util.UUID;
import mage.constants.MultiplayerAttackOption; import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence; import mage.constants.RangeOfInfluence;
import mage.game.match.MatchType; import mage.game.match.MatchType;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
import java.util.UUID;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public class FreeformCommanderFreeForAll extends GameCommanderImpl { public class FreeformCommanderFreeForAll extends GameCommanderImpl {
private int numPlayers; private int numPlayers;
public FreeformCommanderFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public FreeformCommanderFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range,
super(attackOption, range, mulligan, startLife, 60); Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, 60, startLife, startHandSize);
} }
public FreeformCommanderFreeForAll(final FreeformCommanderFreeForAll game) { public FreeformCommanderFreeForAll(final FreeformCommanderFreeForAll game) {
@ -28,7 +29,7 @@ public class FreeformCommanderFreeForAll extends GameCommanderImpl {
@Override @Override
protected void init(UUID choosingPlayerId) { protected void init(UUID choosingPlayerId) {
startingPlayerSkipsDraw = false; startingPlayerSkipsDraw = false;
super.init(choosingPlayerId); super.init(choosingPlayerId);
} }
@Override @Override

View file

@ -17,7 +17,12 @@ public class FreeformCommanderFreeForAllMatch extends MatchImpl {
public void startGame() throws GameException { public void startGame() throws GameException {
int startLife = 40; int startLife = 40;
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
FreeformCommanderFreeForAll game = new FreeformCommanderFreeForAll(options.getAttackOption(), options.getRange(), mulligan, startLife); startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : startLife;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
FreeformCommanderFreeForAll game = new FreeformCommanderFreeForAll(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
initGame(game); initGame(game);
games.add(game); games.add(game);

View file

@ -1,18 +1,20 @@
package mage.game; package mage.game;
import java.util.UUID;
import mage.constants.MultiplayerAttackOption; import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence; import mage.constants.RangeOfInfluence;
import mage.game.match.MatchType; import mage.game.match.MatchType;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
import java.util.UUID;
public class FreeformUnlimitedCommander extends GameCommanderImpl { public class FreeformUnlimitedCommander extends GameCommanderImpl {
private int numPlayers; private int numPlayers;
public FreeformUnlimitedCommander(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public FreeformUnlimitedCommander(MultiplayerAttackOption attackOption, RangeOfInfluence range,
super(attackOption, range, mulligan, startLife, 60); Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, 60, startLife, startHandSize);
} }
public FreeformUnlimitedCommander(final FreeformUnlimitedCommander game) { public FreeformUnlimitedCommander(final FreeformUnlimitedCommander game) {
@ -25,7 +27,7 @@ public class FreeformUnlimitedCommander extends GameCommanderImpl {
if (state.getPlayerList().size() > 2) { if (state.getPlayerList().size() > 2) {
startingPlayerSkipsDraw = false; startingPlayerSkipsDraw = false;
} }
super.init(choosingPlayerId); super.init(choosingPlayerId);
} }
@Override @Override

View file

@ -14,7 +14,12 @@ public class FreeformUnlimitedCommanderMatch extends MatchImpl {
public void startGame() throws GameException { public void startGame() throws GameException {
int startLife = 40; int startLife = 40;
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
FreeformUnlimitedCommander game = new FreeformUnlimitedCommander(options.getAttackOption(), options.getRange(), mulligan, startLife); startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : startLife;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
FreeformUnlimitedCommander game = new FreeformUnlimitedCommander(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
initGame(game); initGame(game);
games.add(game); games.add(game);

View file

@ -19,13 +19,13 @@ import mage.players.Player;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author nigelzor * @author nigelzor
*/ */
public class MomirDuel extends GameImpl { public class MomirDuel extends GameImpl {
public MomirDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public MomirDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range,
super(attackOption, range, mulligan, startLife, 60, 7); Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, 60, startLife, startHandSize);
} }
public MomirDuel(final MomirDuel game) { public MomirDuel(final MomirDuel game) {

View file

@ -6,7 +6,6 @@ import mage.game.match.MatchOptions;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
/** /**
*
* @author nigelzor * @author nigelzor
*/ */
public class MomirDuelMatch extends MatchImpl { public class MomirDuelMatch extends MatchImpl {
@ -21,7 +20,12 @@ public class MomirDuelMatch extends MatchImpl {
int startLife = 24; int startLife = 24;
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
MomirDuel game = new MomirDuel(options.getAttackOption(), options.getRange(), mulligan, startLife); startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : startLife;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
MomirDuel game = new MomirDuel(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
this.initGame(game); this.initGame(game);

View file

@ -6,7 +6,6 @@ import mage.game.match.MatchOptions;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
/** /**
*
* @author nigelzor * @author nigelzor
*/ */
public class MomirFreeForAllMatch extends MatchImpl { public class MomirFreeForAllMatch extends MatchImpl {
@ -21,7 +20,12 @@ public class MomirFreeForAllMatch extends MatchImpl {
int startLife = 24; int startLife = 24;
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
MomirGame game = new MomirGame(options.getAttackOption(), options.getRange(), mulligan, startLife); startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : startLife;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
MomirGame game = new MomirGame(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
this.initGame(game); this.initGame(game);

View file

@ -19,15 +19,15 @@ import mage.players.Player;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author nigelzor * @author nigelzor
*/ */
public class MomirGame extends GameImpl { public class MomirGame extends GameImpl {
private int numPlayers; private int numPlayers;
public MomirGame(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public MomirGame(MultiplayerAttackOption attackOption, RangeOfInfluence range,
super(attackOption, range, mulligan, startLife, 60, 7); Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, 60, startLife, startHandSize);
} }
public MomirGame(final MomirGame game) { public MomirGame(final MomirGame game) {

View file

@ -12,8 +12,8 @@ import java.util.UUID;
*/ */
public class OathbreakerDuel extends OathbreakerFreeForAll { public class OathbreakerDuel extends OathbreakerFreeForAll {
public OathbreakerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public OathbreakerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, startLife); super(attackOption, range, mulligan, startLife, startHandSize);
this.startingPlayerSkipsDraw = true; this.startingPlayerSkipsDraw = true;
} }

View file

@ -15,9 +15,13 @@ public class OathbreakerDuelMatch extends MatchImpl {
@Override @Override
public void startGame() throws GameException { public void startGame() throws GameException {
int startLife = 20;
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
OathbreakerDuel game = new OathbreakerDuel(options.getAttackOption(), options.getRange(), mulligan, startLife); int startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : 20;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
OathbreakerDuel game = new OathbreakerDuel(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setCheckCommanderDamage(false); game.setCheckCommanderDamage(false);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
initGame(game); initGame(game);

View file

@ -31,8 +31,9 @@ public class OathbreakerFreeForAll extends GameCommanderImpl {
private static final String COMMANDER_NAME_OATHBREAKER = "Oathbreaker"; private static final String COMMANDER_NAME_OATHBREAKER = "Oathbreaker";
private static final String COMMANDER_NAME_SIGNATURE_SPELL = "Signature Spell"; private static final String COMMANDER_NAME_SIGNATURE_SPELL = "Signature Spell";
public OathbreakerFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public OathbreakerFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range,
super(attackOption, range, mulligan, startLife, 100); Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, 100, startLife, startHandSize);
this.startingPlayerSkipsDraw = false; this.startingPlayerSkipsDraw = false;
} }

View file

@ -15,9 +15,13 @@ public class OathbreakerFreeForAllMatch extends MatchImpl {
@Override @Override
public void startGame() throws GameException { public void startGame() throws GameException {
int startLife = 20;
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
OathbreakerFreeForAll game = new OathbreakerFreeForAll(options.getAttackOption(), options.getRange(), mulligan, startLife); int startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : 20;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
OathbreakerFreeForAll game = new OathbreakerFreeForAll(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setCheckCommanderDamage(false); game.setCheckCommanderDamage(false);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
initGame(game); initGame(game);

View file

@ -2,22 +2,22 @@
package mage.game; package mage.game;
import java.util.UUID;
import mage.constants.MultiplayerAttackOption; import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence; import mage.constants.RangeOfInfluence;
import mage.game.match.MatchType; import mage.game.match.MatchType;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
import java.util.UUID;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public class PennyDreadfulCommanderFreeForAll extends GameCommanderImpl { public class PennyDreadfulCommanderFreeForAll extends GameCommanderImpl {
private int numPlayers; private int numPlayers;
public PennyDreadfulCommanderFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public PennyDreadfulCommanderFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, startLife, 60); super(attackOption, range, mulligan, 60, startLife, startHandSize);
} }
public PennyDreadfulCommanderFreeForAll(final PennyDreadfulCommanderFreeForAll game) { public PennyDreadfulCommanderFreeForAll(final PennyDreadfulCommanderFreeForAll game) {
@ -28,7 +28,7 @@ public class PennyDreadfulCommanderFreeForAll extends GameCommanderImpl {
@Override @Override
protected void init(UUID choosingPlayerId) { protected void init(UUID choosingPlayerId) {
startingPlayerSkipsDraw = false; startingPlayerSkipsDraw = false;
super.init(choosingPlayerId); super.init(choosingPlayerId);
} }
@Override @Override

View file

@ -20,7 +20,12 @@ public class PennyDreadfulCommanderFreeForAllMatch extends MatchImpl {
startLife = 30; startLife = 30;
} }
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
PennyDreadfulCommanderFreeForAll game = new PennyDreadfulCommanderFreeForAll(options.getAttackOption(), options.getRange(), mulligan, startLife); startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : startLife;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
PennyDreadfulCommanderFreeForAll game = new PennyDreadfulCommanderFreeForAll(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
initGame(game); initGame(game);
games.add(game); games.add(game);

View file

@ -8,13 +8,13 @@ import mage.game.match.MatchType;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
/** /**
*
* @author JRHerlehy * @author JRHerlehy
*/ */
public class TinyLeadersDuel extends GameTinyLeadersImpl { public class TinyLeadersDuel extends GameTinyLeadersImpl {
public TinyLeadersDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public TinyLeadersDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range,
super(attackOption, range, mulligan, startLife); Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, startLife, startHandSize);
} }
public TinyLeadersDuel(final TinyLeadersDuel game) { public TinyLeadersDuel(final TinyLeadersDuel game) {

View file

@ -7,7 +7,6 @@ import mage.game.match.MatchOptions;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
/** /**
*
* @author JRHerlehy * @author JRHerlehy
*/ */
public class TinyLeadersDuelMatch extends MatchImpl { public class TinyLeadersDuelMatch extends MatchImpl {
@ -22,9 +21,14 @@ public class TinyLeadersDuelMatch extends MatchImpl {
int startLife = 25; int startLife = 25;
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
TinyLeadersDuel game = new TinyLeadersDuel(options.getAttackOption(), options.getRange(), mulligan, startLife); startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : startLife;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
TinyLeadersDuel game = new TinyLeadersDuel(
options.getAttackOption(), options.getRange(),
mulligan, startLife, startHandSize
);
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
//Tucking a Tiny Leader is legal //Tucking a Tiny Leader is legal
game.setAlsoHand(false); game.setAlsoHand(false);
game.setAlsoLibrary(false); game.setAlsoLibrary(false);

View file

@ -11,16 +11,9 @@ import java.util.UUID;
public class TwoPlayerDuel extends GameImpl { public class TwoPlayerDuel extends GameImpl {
public TwoPlayerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public TwoPlayerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan,
this(attackOption, range, mulligan, startLife, 60); int minimumDeckSize, int startLife, int startHandSize) {
} super(attackOption, range, mulligan, minimumDeckSize, startLife, startHandSize);
public TwoPlayerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startingLife, int minimumDeckSize) {
this(attackOption, range, mulligan, startingLife, minimumDeckSize, 7);
}
public TwoPlayerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startingLife, int minimumDeckSize, int startingHandSize) {
super(attackOption, range, mulligan, startingLife, minimumDeckSize, startingHandSize);
} }
public TwoPlayerDuel(final TwoPlayerDuel game) { public TwoPlayerDuel(final TwoPlayerDuel game) {

View file

@ -21,7 +21,12 @@ public class TwoPlayerMatch extends MatchImpl {
// see comments from https://github.com/magefree/mage/commit/4874ad31c199ea573187ea2790268be3a4d4c95a // see comments from https://github.com/magefree/mage/commit/4874ad31c199ea573187ea2790268be3a4d4c95a
boolean isLimitedDeck = options.isLimited() || "Limited".equals(options.getDeckType()); boolean isLimitedDeck = options.isLimited() || "Limited".equals(options.getDeckType());
TwoPlayerDuel game = new TwoPlayerDuel(options.getAttackOption(), options.getRange(), mulligan, 20, isLimitedDeck ? 40 : 60); int startLife = options.isCustomStartLifeEnabled() ? options.getCustomStartLife() : 20;
int startHandSize = options.isCustomStartHandSizeEnabled() ? options.getCustomStartHandSize() : 7;
TwoPlayerDuel game = new TwoPlayerDuel(
options.getAttackOption(), options.getRange(), mulligan,
isLimitedDeck ? 40 : 60, startLife, startHandSize
);
// Sets a start message about the match score // Sets a start message about the match score
game.setStartMessage(this.createGameStartMessage()); game.setStartMessage(this.createGameStartMessage());
initGame(game); initGame(game);

View file

@ -34,7 +34,7 @@ public class GoadTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 40); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 40, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");
@ -65,8 +65,8 @@ public class GoadTest extends CardTestMultiPlayerBase {
/** /**
* Checks whether the given attacker is NOT goaded by the provided player(s). * Checks whether the given attacker is NOT goaded by the provided player(s).
* *
* @param attacker the name of the attacker * @param attacker the name of the attacker
* @param players the player(s) that the attacker is supposed to be goaded by. * @param players the player(s) that the attacker is supposed to be goaded by.
*/ */
private void assertNotGoaded(String attacker, TestPlayer... players) { private void assertNotGoaded(String attacker, TestPlayer... players) {
Assert.assertTrue("At least one player should be provided", players.length > 0); Assert.assertTrue("At least one player should be provided", players.length > 0);
@ -87,8 +87,8 @@ public class GoadTest extends CardTestMultiPlayerBase {
/** /**
* Checks whether the given attacker is goaded by the provided player(s). * Checks whether the given attacker is goaded by the provided player(s).
* *
* @param attacker the name of the attacker * @param attacker the name of the attacker
* @param players the player(s) that the attacker is supposed to be goaded by. * @param players the player(s) that the attacker is supposed to be goaded by.
*/ */
private void assertGoaded(String attacker, TestPlayer... players) { private void assertGoaded(String attacker, TestPlayer... players) {
Assert.assertTrue("At least one player should be provided", players.length > 0); Assert.assertTrue("At least one player should be provided", players.length > 0);
@ -220,10 +220,10 @@ public class GoadTest extends CardTestMultiPlayerBase {
/** /**
* Reported bug: https://github.com/magefree/mage/issues/9227 * Reported bug: https://github.com/magefree/mage/issues/9227
* Geode Rager (and other goad all effects) goad creatures that enter the battlefield after the effect resolved. * Geode Rager (and other goad all effects) goad creatures that enter the battlefield after the effect resolved.
* * <p>
* Ruling: * Ruling:
* Creatures that enter the battlefield or come under the target players control after Geode Ragers ability has resolved wont be goaded. * Creatures that enter the battlefield or come under the target players control after Geode Ragers ability has resolved wont be goaded.
* (2020-09-25) * (2020-09-25)
*/ */
@Test @Test
public void goadAllCorrectAffect() { public void goadAllCorrectAffect() {

View file

@ -16,7 +16,7 @@ import java.io.FileNotFoundException;
public class NaturesWillTest extends CardTestPlayerBase { public class NaturesWillTest extends CardTestPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20, 7);
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");
playerC = createPlayer(game, "PlayerC"); playerC = createPlayer(game, "PlayerC");

View file

@ -16,7 +16,7 @@ import java.io.FileNotFoundException;
public class StormTheVaultTest extends CardTestPlayerBase { public class StormTheVaultTest extends CardTestPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20, 7);
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");
playerC = createPlayer(game, "PlayerC"); playerC = createPlayer(game, "PlayerC");

View file

@ -23,7 +23,7 @@ public class BattleMultiplayerTest extends BattleBaseTest {
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new FreeForAll( Game game = new FreeForAll(
MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL,
MulliganType.GAME_DEFAULT.getMulligan(0), 20 MulliganType.GAME_DEFAULT.getMulligan(0), 20, 7
); );
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");

View file

@ -21,7 +21,7 @@ public class MonarchTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
// reason: must use MultiplayerAttackOption.MULTIPLE // reason: must use MultiplayerAttackOption.MULTIPLE
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -19,7 +19,7 @@ import java.io.FileNotFoundException;
public class RagsRichesTest extends CardTestMultiPlayerBase { public class RagsRichesTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new FreeForAll(MultiplayerAttackOption.LEFT, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20); Game game = new FreeForAll(MultiplayerAttackOption.LEFT, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -1,6 +1,5 @@
package org.mage.test.cards.single.c19; package org.mage.test.cards.single.c19;
import java.io.FileNotFoundException;
import mage.constants.MultiplayerAttackOption; import mage.constants.MultiplayerAttackOption;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
import mage.constants.RangeOfInfluence; import mage.constants.RangeOfInfluence;
@ -12,14 +11,15 @@ import mage.game.mulligan.MulliganType;
import org.junit.Test; import org.junit.Test;
import org.mage.test.serverside.base.CardTestMultiPlayerBase; import org.mage.test.serverside.base.CardTestMultiPlayerBase;
import java.io.FileNotFoundException;
/** /**
*
* @author azra1l <algee2005@gmail.com> * @author azra1l <algee2005@gmail.com>
*/ */
public class AeonEngineTest extends CardTestMultiPlayerBase { public class AeonEngineTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException { protected Game createNewGameAndPlayers() throws GameException {
Game game = new FreeForAll(MultiplayerAttackOption.LEFT, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20); Game game = new FreeForAll(MultiplayerAttackOption.LEFT, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");
@ -27,7 +27,7 @@ public class AeonEngineTest extends CardTestMultiPlayerBase {
playerD = createPlayer(game, "PlayerD"); playerD = createPlayer(game, "PlayerD");
return game; return game;
} }
@Test @Test
public void testEnterTappedNormalTurnOrder() { public void testEnterTappedNormalTurnOrder() {
// Aeon Engine - Artefact - {5} // Aeon Engine - Artefact - {5}
@ -47,7 +47,7 @@ public class AeonEngineTest extends CardTestMultiPlayerBase {
//check if aeon engine is tapped //check if aeon engine is tapped
assertTapped("Aeon Engine", true); assertTapped("Aeon Engine", true);
//check if turn was passed to correct player - should be D //check if turn was passed to correct player - should be D
assertActivePlayer(playerD); assertActivePlayer(playerD);
assertLife(playerA, 17); assertLife(playerA, 17);
@ -82,7 +82,7 @@ public class AeonEngineTest extends CardTestMultiPlayerBase {
//check if aeon engine has been exiled //check if aeon engine has been exiled
assertExileCount(playerA, "Aeon Engine", 1); assertExileCount(playerA, "Aeon Engine", 1);
//check if turn was passed to correct player each turn - should be B //check if turn was passed to correct player each turn - should be B
assertActivePlayer(playerB); assertActivePlayer(playerB);
assertLife(playerA, 8); assertLife(playerA, 8);
@ -93,7 +93,7 @@ public class AeonEngineTest extends CardTestMultiPlayerBase {
assertGraveyardCount(playerC, "Agonizing Syphon", 1); assertGraveyardCount(playerC, "Agonizing Syphon", 1);
assertGraveyardCount(playerD, "Agonizing Syphon", 1); assertGraveyardCount(playerD, "Agonizing Syphon", 1);
} }
@Test @Test
public void testExileCostReversedTurnOrderDouble() throws GameException, FileNotFoundException { public void testExileCostReversedTurnOrderDouble() throws GameException, FileNotFoundException {
// Aeon Engine - Artefact - {5} // Aeon Engine - Artefact - {5}
@ -119,7 +119,7 @@ public class AeonEngineTest extends CardTestMultiPlayerBase {
castSpell(7, PhaseStep.PRECOMBAT_MAIN, playerC, "Agonizing Syphon", playerA); castSpell(7, PhaseStep.PRECOMBAT_MAIN, playerC, "Agonizing Syphon", playerA);
activateAbility(8, PhaseStep.PRECOMBAT_MAIN, playerD, "{T}, Exile {this}:"); activateAbility(8, PhaseStep.PRECOMBAT_MAIN, playerD, "{T}, Exile {this}:");
castSpell(9, PhaseStep.PRECOMBAT_MAIN, playerC, "Agonizing Syphon", playerA); castSpell(9, PhaseStep.PRECOMBAT_MAIN, playerC, "Agonizing Syphon", playerA);
setStrictChooseMode(true); setStrictChooseMode(true);
setStopAt(9, PhaseStep.END_TURN); setStopAt(9, PhaseStep.END_TURN);
execute(); execute();
@ -127,7 +127,7 @@ public class AeonEngineTest extends CardTestMultiPlayerBase {
//check if aeon engine's have been exiled //check if aeon engine's have been exiled
assertExileCount(playerA, "Aeon Engine", 1); assertExileCount(playerA, "Aeon Engine", 1);
assertExileCount(playerD, "Aeon Engine", 1); assertExileCount(playerD, "Aeon Engine", 1);
//check if turn was passed to correct player each turn - should be C //check if turn was passed to correct player each turn - should be C
assertActivePlayer(playerC); assertActivePlayer(playerC);
assertLife(playerA, 5); assertLife(playerA, 5);

View file

@ -19,7 +19,7 @@ public class PramikonSkyRampartTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException { protected Game createNewGameAndPlayers() throws GameException {
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 20); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 20, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -1,7 +1,5 @@
package org.mage.test.cards.single.hou; package org.mage.test.cards.single.hou;
import java.io.FileNotFoundException;
import mage.constants.MultiplayerAttackOption; import mage.constants.MultiplayerAttackOption;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
import mage.constants.RangeOfInfluence; import mage.constants.RangeOfInfluence;
@ -14,8 +12,9 @@ import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mage.test.serverside.base.CardTestMultiPlayerBase; import org.mage.test.serverside.base.CardTestMultiPlayerBase;
import java.io.FileNotFoundException;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public class TormentOfHailfireTest extends CardTestMultiPlayerBase { public class TormentOfHailfireTest extends CardTestMultiPlayerBase {
@ -23,7 +22,7 @@ public class TormentOfHailfireTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
// Start Life = 2 // Start Life = 2
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 20); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 20, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");
@ -35,22 +34,22 @@ public class TormentOfHailfireTest extends CardTestMultiPlayerBase {
@Test @Test
public void test_Normal() { public void test_Normal() {
setStrictChooseMode(true); setStrictChooseMode(true);
// Repeat the following process X times. Each opponent loses 3 life unless they sacrifice a nonland permanent or discards a card. // Repeat the following process X times. Each opponent loses 3 life unless they sacrifice a nonland permanent or discards a card.
addCard(Zone.HAND, playerA, "Torment of Hailfire", 1); // Sorcery {X}{B}{B} addCard(Zone.HAND, playerA, "Torment of Hailfire", 1); // Sorcery {X}{B}{B}
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 12); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 12);
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 2); addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 2);
addCard(Zone.HAND, playerB, "Plains", 1); addCard(Zone.HAND, playerB, "Plains", 1);
addCard(Zone.BATTLEFIELD, playerC, "Silvercoat Lion", 3); addCard(Zone.BATTLEFIELD, playerC, "Silvercoat Lion", 3);
addCard(Zone.BATTLEFIELD, playerD, "Silvercoat Lion", 3); addCard(Zone.BATTLEFIELD, playerD, "Silvercoat Lion", 3);
addCard(Zone.HAND, playerD, "Plains", 1); addCard(Zone.HAND, playerD, "Plains", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Torment of Hailfire"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Torment of Hailfire");
setChoice(playerA, "X=10"); setChoice(playerA, "X=10");
setChoice(playerD, true);// Sacrifices a nonland permanent? setChoice(playerD, true);// Sacrifices a nonland permanent?
setChoice(playerD, "Silvercoat Lion"); setChoice(playerD, "Silvercoat Lion");
@ -65,22 +64,22 @@ public class TormentOfHailfireTest extends CardTestMultiPlayerBase {
setChoice(playerD, false);// Sacrifices a nonland permanent? setChoice(playerD, false);// Sacrifices a nonland permanent?
setChoice(playerD, true);// Discard a card? setChoice(playerD, true);// Discard a card?
setChoice(playerB, true);// Discard a card? setChoice(playerB, true);// Discard a card?
setChoice(playerD, true);// Sacrifices a nonland permanent? setChoice(playerD, true);// Sacrifices a nonland permanent?
setChoice(playerD, "Silvercoat Lion"); setChoice(playerD, "Silvercoat Lion");
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute(); execute();
assertGraveyardCount(playerA, "Torment of Hailfire", 1); assertGraveyardCount(playerA, "Torment of Hailfire", 1);
assertLife(playerA, 20); assertLife(playerA, 20);
assertLife(playerC, 20); assertLife(playerC, 20);
assertLife(playerD, 2); assertLife(playerD, 2);
assertLife(playerB, -1); assertLife(playerB, -1);
Assert.assertFalse("Player B is dead", playerB.isInGame()); Assert.assertFalse("Player B is dead", playerB.isInGame());
} }
} }

View file

@ -16,13 +16,15 @@ public class FreeformUnlimitedCommanderTest extends MageTestPlayerBase {
// Arrange // Arrange
Mulligan mulligan = new LondonMulligan(1); Mulligan mulligan = new LondonMulligan(1);
int startLife = 40; int startLife = 40;
int startHandSize = 7;
// Assert // Assert
FreeformUnlimitedCommander game = new FreeformUnlimitedCommander( FreeformUnlimitedCommander game = new FreeformUnlimitedCommander(
MultiplayerAttackOption.MULTIPLE, MultiplayerAttackOption.MULTIPLE,
RangeOfInfluence.ALL, RangeOfInfluence.ALL,
mulligan, mulligan,
startLife startLife,
startHandSize
); );
// Assert // Assert

View file

@ -1,10 +1,18 @@
package org.mage.test.mulligan; package org.mage.test.mulligan;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Iterables.getOnlyElement;
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableSet;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.cards.basiclands.Forest; import mage.cards.basiclands.Forest;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.cards.s.Squire; import mage.cards.s.Squire;
import static mage.constants.MultiplayerAttackOption.LEFT;
import mage.constants.RangeOfInfluence; import mage.constants.RangeOfInfluence;
import static mage.constants.RangeOfInfluence.ONE;
import static mage.constants.Rarity.LAND;
import mage.game.Game; import mage.game.Game;
import mage.game.GameOptions; import mage.game.GameOptions;
import mage.game.TwoPlayerDuel; import mage.game.TwoPlayerDuel;
@ -12,6 +20,7 @@ import mage.game.mulligan.Mulligan;
import mage.game.mulligan.MulliganType; import mage.game.mulligan.MulliganType;
import mage.players.StubPlayer; import mage.players.StubPlayer;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import static org.junit.Assert.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -19,16 +28,6 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Stream; import java.util.stream.Stream;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Iterables.getOnlyElement;
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableSet;
import static mage.constants.MultiplayerAttackOption.LEFT;
import static mage.constants.RangeOfInfluence.ONE;
import static mage.constants.Rarity.LAND;
import static org.junit.Assert.*;
public class MulliganTestBase { public class MulliganTestBase {
protected static Logger logger = Logger.getLogger(MulliganTestBase.class); protected static Logger logger = Logger.getLogger(MulliganTestBase.class);
@ -60,7 +59,7 @@ public class MulliganTestBase {
public void run(Runnable callback) { public void run(Runnable callback) {
Mulligan mulligan = mulliganType.getMulligan(freeMulligans); Mulligan mulligan = mulliganType.getMulligan(freeMulligans);
Game game = new TwoPlayerDuel(LEFT, ONE, mulligan, 20) { Game game = new TwoPlayerDuel(LEFT, ONE, mulligan, 60, 20, 7) {
@Override @Override
public void fireStatusEvent(String message, boolean withTime, boolean withTurnInfo) { public void fireStatusEvent(String message, boolean withTime, boolean withTurnInfo) {
super.fireStatusEvent(message, withTime, withTurnInfo); super.fireStatusEvent(message, withTime, withTurnInfo);
@ -142,10 +141,10 @@ public class MulliganTestBase {
public static Deck generateDeck(UUID playerId, int count) { public static Deck generateDeck(UUID playerId, int count) {
Deck deck = new Deck(); Deck deck = new Deck();
Stream.generate(() -> new Forest(playerId, new CardSetInfo("Forest", "TEST", "1", LAND))) Stream.generate(() -> new Forest(playerId, new CardSetInfo("Forest", "TEST", "1", LAND)))
.limit(count/2+(count & 1)) //If odd number of cards, add one extra forest .limit(count / 2 + (count & 1)) //If odd number of cards, add one extra forest
.forEach(deck.getCards()::add); .forEach(deck.getCards()::add);
Stream.generate(() -> new Squire(playerId, new CardSetInfo("Squire", "TEST", "2", LAND))) Stream.generate(() -> new Squire(playerId, new CardSetInfo("Squire", "TEST", "2", LAND)))
.limit(count/2) .limit(count / 2)
.forEach(deck.getCards()::add); .forEach(deck.getCards()::add);
return deck; return deck;
} }

View file

@ -18,7 +18,7 @@ public class AngelOfSerenityTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
// Start Life = 2 // Start Life = 2
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 2); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 2, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -20,7 +20,7 @@ public class BlatantThieveryTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -25,7 +25,7 @@ public class CreepingDreadTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 40); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 40, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -17,7 +17,7 @@ public class MultiplayerTriggerTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 40); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 40, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -20,7 +20,7 @@ public class MyriadTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 40); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 40, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -22,7 +22,7 @@ public class PlayerDiedStackTargetHandlingTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
// Start Life = 2 // Start Life = 2
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 3); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 3, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -9,7 +9,6 @@ import mage.game.FreeForAll;
import mage.game.Game; import mage.game.Game;
import mage.game.GameException; import mage.game.GameException;
import mage.game.mulligan.MulliganType; import mage.game.mulligan.MulliganType;
import mage.game.permanent.Permanent;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mage.test.serverside.base.CardTestMultiPlayerBase; import org.mage.test.serverside.base.CardTestMultiPlayerBase;
@ -24,7 +23,7 @@ public class PlayerLeftGameRange1Test extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
// Start Life = 2 // Start Life = 2
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 2); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 2, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -1,6 +1,5 @@
package org.mage.test.multiplayer; package org.mage.test.multiplayer;
import java.io.FileNotFoundException;
import mage.constants.MultiplayerAttackOption; import mage.constants.MultiplayerAttackOption;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
import mage.constants.RangeOfInfluence; import mage.constants.RangeOfInfluence;
@ -14,6 +13,8 @@ import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mage.test.serverside.base.CardTestMultiPlayerBase; import org.mage.test.serverside.base.CardTestMultiPlayerBase;
import java.io.FileNotFoundException;
/** /**
* @author LevelX2 * @author LevelX2
*/ */
@ -22,7 +23,7 @@ public class PlayerLeftGameRangeAllTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
// Start Life = 2 // Start Life = 2
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 2); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 2, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");
@ -419,14 +420,14 @@ public class PlayerLeftGameRangeAllTest extends CardTestMultiPlayerBase {
/** /**
* https://github.com/magefree/mage/issues/6997 * https://github.com/magefree/mage/issues/6997
Some continuous effects should stay in play even after the player that set them leaves the game. * Some continuous effects should stay in play even after the player that set them leaves the game.
Example: * Example:
* Player A: Casts Vorinclex, Voice of Hunger * Player A: Casts Vorinclex, Voice of Hunger
* Player D: Taps all lands and do stuff (lands shouldn't untap during his next untap step) * Player D: Taps all lands and do stuff (lands shouldn't untap during his next untap step)
* Player C: Kills Player A Player D: Lands untapped normally, though they shouldn't * Player C: Kills Player A Player D: Lands untapped normally, though they shouldn't
* * <p>
* This happened playing commander against 3 AIs. One of the AIs played Vorinclex, I tapped all my lands during my turn to do stuff. * This happened playing commander against 3 AIs. One of the AIs played Vorinclex, I tapped all my lands during my turn to do stuff.
* Next AI killed the one that had Vorinclex. When the game got to my turn, my lands untapped normally. * Next AI killed the one that had Vorinclex. When the game got to my turn, my lands untapped normally.
*/ */
@Test @Test
public void TestContinuousEffectStaysAfterCreatingPlayerLeft() { public void TestContinuousEffectStaysAfterCreatingPlayerLeft() {
@ -456,20 +457,20 @@ public class PlayerLeftGameRangeAllTest extends CardTestMultiPlayerBase {
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerC, "Lightning Bolt", playerA); castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerC, "Lightning Bolt", playerA);
setStopAt(5, PhaseStep.BEGIN_COMBAT); setStopAt(5, PhaseStep.BEGIN_COMBAT);
execute(); execute();
assertPermanentCount(playerD, "Silvercoat Lion", 1); assertPermanentCount(playerD, "Silvercoat Lion", 1);
assertGraveyardCount(playerC, "Lightning Bolt", 1); assertGraveyardCount(playerC, "Lightning Bolt", 1);
Assert.assertFalse("Player A is no longer in the game", playerA.isInGame()); Assert.assertFalse("Player A is no longer in the game", playerA.isInGame());
Assert.assertTrue("Player D is the active player",currentGame.getActivePlayerId().equals(playerD.getId())); Assert.assertTrue("Player D is the active player", currentGame.getActivePlayerId().equals(playerD.getId()));
assertTappedCount("Plains", true, 2); // Do not untap because of Vorinclex do not untap effect assertTappedCount("Plains", true, 2); // Do not untap because of Vorinclex do not untap effect
} }
} }

View file

@ -1,6 +1,5 @@
package org.mage.test.multiplayer; package org.mage.test.multiplayer;
import java.io.FileNotFoundException;
import mage.constants.MultiplayerAttackOption; import mage.constants.MultiplayerAttackOption;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
import mage.constants.RangeOfInfluence; import mage.constants.RangeOfInfluence;
@ -13,6 +12,8 @@ import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mage.test.serverside.base.CardTestMultiPlayerBase; import org.mage.test.serverside.base.CardTestMultiPlayerBase;
import java.io.FileNotFoundException;
/** /**
* @author LevelX2 * @author LevelX2
@ -21,7 +22,7 @@ public class PlayerWinsTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 40); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 40, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");
@ -33,9 +34,9 @@ public class PlayerWinsTest extends CardTestMultiPlayerBase {
/** /**
* Tests multiplayer effects Player order: A -> D -> C -> B * Tests multiplayer effects Player order: A -> D -> C -> B
*/ */
/** /**
* Test that players out of range do not lose the game if effect from Approach of the Seconnd Sun takes effect. * Test that players out of range do not lose the game if effect from Approach of the Seconnd Sun takes effect.
*/ */
@Test @Test
public void ApproachOfTheSecondSunTest() { public void ApproachOfTheSecondSunTest() {
@ -59,20 +60,20 @@ public class PlayerWinsTest extends CardTestMultiPlayerBase {
Assert.assertTrue("Player A is in the game", playerA.isInGame()); Assert.assertTrue("Player A is in the game", playerA.isInGame());
} }
/** /**
* Test that players out of range do not lose the game if effect from Laboratory Maniac takes effect. * Test that players out of range do not lose the game if effect from Laboratory Maniac takes effect.
*/ */
@Test @Test
public void LaboratoryManiacWinsTest() { public void LaboratoryManiacWinsTest() {
// If you would draw a card while your library has no cards in it, you win the game instead. // If you would draw a card while your library has no cards in it, you win the game instead.
addCard(Zone.HAND, playerA, "Laboratory Maniac", 1); // Creature {2}{U} addCard(Zone.HAND, playerA, "Laboratory Maniac", 1); // Creature {2}{U}
addCard(Zone.BATTLEFIELD, playerA, "Island", 3); addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Laboratory Maniac"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Laboratory Maniac");
removeAllCardsFromLibrary(playerA); removeAllCardsFromLibrary(playerA);
addCard(Zone.LIBRARY, playerA, "Mountain"); addCard(Zone.LIBRARY, playerA, "Mountain");
setStopAt(5, PhaseStep.POSTCOMBAT_MAIN); setStopAt(5, PhaseStep.POSTCOMBAT_MAIN);
execute(); execute();
@ -84,25 +85,25 @@ public class PlayerWinsTest extends CardTestMultiPlayerBase {
Assert.assertTrue("Player C should be in the game but has lost", playerC.isInGame()); Assert.assertTrue("Player C should be in the game but has lost", playerC.isInGame());
Assert.assertTrue("Player A should be in the game but has lost", playerA.isInGame()); Assert.assertTrue("Player A should be in the game but has lost", playerA.isInGame());
} }
/** /**
* Test that player can't win while Platinium Angel ist in range. * Test that player can't win while Platinium Angel ist in range.
*/ */
@Test @Test
public void LaboratoryManiacAndPlatinumAngelInRangeTest() { public void LaboratoryManiacAndPlatinumAngelInRangeTest() {
// If you would draw a card while your library has no cards in it, you win the game instead. // If you would draw a card while your library has no cards in it, you win the game instead.
addCard(Zone.HAND, playerA, "Laboratory Maniac", 1); // Creature {2}{U} addCard(Zone.HAND, playerA, "Laboratory Maniac", 1); // Creature {2}{U}
addCard(Zone.BATTLEFIELD, playerA, "Island", 3); addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
removeAllCardsFromLibrary(playerA); removeAllCardsFromLibrary(playerA);
// You can't lose the game and your opponents can't win the game. // You can't lose the game and your opponents can't win the game.
addCard(Zone.HAND, playerD, "Platinum Angel", 1); // Creature {2}{U} addCard(Zone.HAND, playerD, "Platinum Angel", 1); // Creature {2}{U}
addCard(Zone.BATTLEFIELD, playerD, "Island", 7); addCard(Zone.BATTLEFIELD, playerD, "Island", 7);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Laboratory Maniac"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Laboratory Maniac");
addCard(Zone.LIBRARY, playerA, "Mountain"); addCard(Zone.LIBRARY, playerA, "Mountain");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerD, "Platinum Angel"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerD, "Platinum Angel");
setStopAt(9, PhaseStep.POSTCOMBAT_MAIN); setStopAt(9, PhaseStep.POSTCOMBAT_MAIN);
execute(); execute();
@ -110,33 +111,33 @@ public class PlayerWinsTest extends CardTestMultiPlayerBase {
assertPermanentCount(playerA, "Laboratory Maniac", 1); assertPermanentCount(playerA, "Laboratory Maniac", 1);
assertHandCount(playerA, "Mountain", 1); assertHandCount(playerA, "Mountain", 1);
assertLibraryCount(playerA, 0); assertLibraryCount(playerA, 0);
assertPermanentCount(playerD, "Platinum Angel", 1); assertPermanentCount(playerD, "Platinum Angel", 1);
Assert.assertTrue("Player D should be in the game but has lost", playerD.isInGame()); Assert.assertTrue("Player D should be in the game but has lost", playerD.isInGame());
Assert.assertTrue("Player B should be in the game but has lost", playerB.isInGame()); Assert.assertTrue("Player B should be in the game but has lost", playerB.isInGame());
Assert.assertTrue("Player C should be in the game but has lost", playerC.isInGame()); Assert.assertTrue("Player C should be in the game but has lost", playerC.isInGame());
Assert.assertTrue("Player A should be in the game but has lost", playerA.isInGame()); Assert.assertTrue("Player A should be in the game but has lost", playerA.isInGame());
} }
/** /**
* Test that player can't win while Platinium Angel ist in range. * Test that player can't win while Platinium Angel ist in range.
*/ */
@Test @Test
public void LaboratoryManiacAndPlatinumAngelFirstOutOfRangeTest() { public void LaboratoryManiacAndPlatinumAngelFirstOutOfRangeTest() {
// If you would draw a card while your library has no cards in it, you win the game instead. // If you would draw a card while your library has no cards in it, you win the game instead.
addCard(Zone.HAND, playerA, "Laboratory Maniac", 1); // Creature {2}{U} addCard(Zone.HAND, playerA, "Laboratory Maniac", 1); // Creature {2}{U}
addCard(Zone.BATTLEFIELD, playerA, "Island", 3); addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
removeAllCardsFromLibrary(playerA); removeAllCardsFromLibrary(playerA);
// You can't lose the game and your opponents can't win the game. // You can't lose the game and your opponents can't win the game.
addCard(Zone.HAND, playerC, "Platinum Angel", 1); // Creature {2}{U} addCard(Zone.HAND, playerC, "Platinum Angel", 1); // Creature {2}{U}
addCard(Zone.BATTLEFIELD, playerC, "Island", 7); addCard(Zone.BATTLEFIELD, playerC, "Island", 7);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Laboratory Maniac"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Laboratory Maniac");
addCard(Zone.LIBRARY, playerA, "Mountain"); addCard(Zone.LIBRARY, playerA, "Mountain");
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerC, "Platinum Angel"); castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerC, "Platinum Angel");
setStopAt(9, PhaseStep.POSTCOMBAT_MAIN); setStopAt(9, PhaseStep.POSTCOMBAT_MAIN);
execute(); execute();
@ -144,9 +145,9 @@ public class PlayerWinsTest extends CardTestMultiPlayerBase {
assertPermanentCount(playerA, "Laboratory Maniac", 1); assertPermanentCount(playerA, "Laboratory Maniac", 1);
assertHandCount(playerA, "Mountain", 1); assertHandCount(playerA, "Mountain", 1);
assertLibraryCount(playerA, 0); assertLibraryCount(playerA, 0);
assertPermanentCount(playerC, "Platinum Angel", 1); assertPermanentCount(playerC, "Platinum Angel", 1);
Assert.assertTrue("Player D still alive but should have lost the gamet", !playerD.isInGame()); Assert.assertTrue("Player D still alive but should have lost the gamet", !playerD.isInGame());
Assert.assertTrue("Player B still alive but should have lost the game", !playerB.isInGame()); Assert.assertTrue("Player B still alive but should have lost the game", !playerB.isInGame());
Assert.assertTrue("Player C should be in the game but has lost", playerC.isInGame()); Assert.assertTrue("Player C should be in the game but has lost", playerC.isInGame());

View file

@ -22,7 +22,7 @@ public class PrivilegedPositionTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 40); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 40, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -20,7 +20,7 @@ public class VindictiveLichTest extends CardTestMultiPlayerBase {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 40); Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 40, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -36,7 +36,7 @@ public class PlayGameTest extends MageTestBase {
@Ignore @Ignore
@Test @Test
public void playOneGame() throws GameException, FileNotFoundException, IllegalArgumentException { public void playOneGame() throws GameException, FileNotFoundException, IllegalArgumentException {
Game game = new TwoPlayerDuel(MultiplayerAttackOption.LEFT, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20); Game game = new TwoPlayerDuel(MultiplayerAttackOption.LEFT, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 60, 20, 7);
Player computerA = createPlayer("ComputerA", PlayerType.COMPUTER_MINIMAX_HYBRID); Player computerA = createPlayer("ComputerA", PlayerType.COMPUTER_MINIMAX_HYBRID);
// Player playerA = createPlayer("ComputerA", "Computer - mad"); // Player playerA = createPlayer("ComputerA", "Computer - mad");

View file

@ -24,7 +24,7 @@ public abstract class CardTestCommander3PlayersFFA extends CardTestPlayerAPIImpl
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new CommanderFreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 40); Game game = new CommanderFreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 40, 7);
playerA = createPlayer(game, "PlayerA", deckNameA); playerA = createPlayer(game, "PlayerA", deckNameA);
playerB = createPlayer(game, "PlayerB", deckNameB); playerB = createPlayer(game, "PlayerB", deckNameB);
playerC = createPlayer(game, "PlayerC", deckNameC); playerC = createPlayer(game, "PlayerC", deckNameC);

View file

@ -17,7 +17,7 @@ public abstract class CardTestCommander4Players extends CardTestPlayerAPIImpl {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new CommanderFreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20); Game game = new CommanderFreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -23,7 +23,7 @@ public abstract class CardTestCommanderDuelBase extends CardTestPlayerAPIImpl {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new CommanderDuel(MultiplayerAttackOption.LEFT, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 40); Game game = new CommanderDuel(MultiplayerAttackOption.LEFT, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 40, 7);
playerA = createPlayer(game, "PlayerA", deckNameA); playerA = createPlayer(game, "PlayerA", deckNameA);
playerB = createPlayer(game, "PlayerB", deckNameB); playerB = createPlayer(game, "PlayerB", deckNameB);

View file

@ -21,7 +21,7 @@ public abstract class CardTestMultiPlayerBase extends CardTestPlayerAPIImpl {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new FreeForAll(MultiplayerAttackOption.LEFT, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 20); Game game = new FreeForAll(MultiplayerAttackOption.LEFT, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 20, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -17,7 +17,7 @@ public abstract class CardTestMultiPlayerBaseWithRangeAll extends CardTestPlayer
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new FreeForAll(MultiplayerAttackOption.LEFT, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20); Game game = new FreeForAll(MultiplayerAttackOption.LEFT, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20, 7);
// Player order: A -> D -> C -> B // Player order: A -> D -> C -> B
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -1,6 +1,5 @@
package org.mage.test.serverside.base; package org.mage.test.serverside.base;
import java.io.FileNotFoundException;
import mage.constants.MultiplayerAttackOption; import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence; import mage.constants.RangeOfInfluence;
import mage.game.Game; import mage.game.Game;
@ -9,6 +8,8 @@ import mage.game.OathbreakerFreeForAll;
import mage.game.mulligan.MulliganType; import mage.game.mulligan.MulliganType;
import org.mage.test.serverside.base.impl.CardTestPlayerAPIImpl; import org.mage.test.serverside.base.impl.CardTestPlayerAPIImpl;
import java.io.FileNotFoundException;
/** /**
* @author LevelX2 * @author LevelX2
*/ */
@ -23,7 +24,7 @@ public abstract class CardTestOathbreaker3PlayersFFA extends CardTestPlayerAPIIm
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new OathbreakerFreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 20); Game game = new OathbreakerFreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 20, 7);
playerA = createPlayer(game, "PlayerA", deckNameA); playerA = createPlayer(game, "PlayerA", deckNameA);
playerB = createPlayer(game, "PlayerB", deckNameB); playerB = createPlayer(game, "PlayerB", deckNameB);
playerC = createPlayer(game, "PlayerC", deckNameC); playerC = createPlayer(game, "PlayerC", deckNameC);

View file

@ -24,7 +24,7 @@ public abstract class CardTestPlayerBase extends CardTestPlayerAPIImpl {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new TwoPlayerDuel(MultiplayerAttackOption.LEFT, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 20); Game game = new TwoPlayerDuel(MultiplayerAttackOption.LEFT, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 60, 20, 7);
playerA = createPlayer(game, "PlayerA", deckNameA); playerA = createPlayer(game, "PlayerA", deckNameA);
playerB = createPlayer(game, "PlayerB", deckNameB); playerB = createPlayer(game, "PlayerB", deckNameB);

View file

@ -14,7 +14,7 @@ import java.io.FileNotFoundException;
/** /**
* PlayerA is full AI player and process all actions as AI logic. You don't need aiXXX commands in that tests. * PlayerA is full AI player and process all actions as AI logic. You don't need aiXXX commands in that tests.
* * <p>
* If you need custom AI tests then use CardTestPlayerBaseWithAIHelps with aiXXX commands * If you need custom AI tests then use CardTestPlayerBaseWithAIHelps with aiXXX commands
* *
* @author LevelX2 * @author LevelX2
@ -25,7 +25,7 @@ public abstract class CardTestPlayerBaseAI extends CardTestPlayerAPIImpl {
@Override @Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException { protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new TwoPlayerDuel(MultiplayerAttackOption.LEFT, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 20); Game game = new TwoPlayerDuel(MultiplayerAttackOption.LEFT, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 60, 20, 7);
playerA = createPlayer(game, "PlayerA"); playerA = createPlayer(game, "PlayerA");
playerB = createPlayer(game, "PlayerB"); playerB = createPlayer(game, "PlayerB");

View file

@ -94,7 +94,7 @@ public class RandomTest {
String dest = "f:/test/xmage/"; String dest = "f:/test/xmage/";
//RandomUtil.setSeed(123); //RandomUtil.setSeed(123);
Player player = new HumanPlayer("random", RangeOfInfluence.ALL, 1); Player player = new HumanPlayer("random", RangeOfInfluence.ALL, 1);
Game game = new TwoPlayerDuel(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 50); Game game = new TwoPlayerDuel(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 60, 50, 7);
int height = 512; int height = 512;
int weight = 512; int weight = 512;
@ -117,7 +117,7 @@ public class RandomTest {
String dest = "f:/test/xmage/"; String dest = "f:/test/xmage/";
//RandomUtil.setSeed(123); //RandomUtil.setSeed(123);
Player player = new HumanPlayer("random", RangeOfInfluence.ALL, 1); Player player = new HumanPlayer("random", RangeOfInfluence.ALL, 1);
Game game = new TwoPlayerDuel(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 50); Game game = new TwoPlayerDuel(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 60, 50, 7);
int height = 512; int height = 512;
int weight = 512; int weight = 512;
@ -142,7 +142,7 @@ public class RandomTest {
String dest = "f:/test/xmage/"; String dest = "f:/test/xmage/";
//RandomUtil.setSeed(123); //RandomUtil.setSeed(123);
Player player = new HumanPlayer("random", RangeOfInfluence.ALL, 1); Player player = new HumanPlayer("random", RangeOfInfluence.ALL, 1);
Game game = new TwoPlayerDuel(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 50); Game game = new TwoPlayerDuel(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 60, 50, 7);
Deck deck = DeckTestUtils.buildRandomDeck("WGUBR", false, "GRN"); Deck deck = DeckTestUtils.buildRandomDeck("WGUBR", false, "GRN");
player.getLibrary().addAll(deck.getMaindeckCards(), game); player.getLibrary().addAll(deck.getMaindeckCards(), game);

View file

@ -11,8 +11,8 @@ import java.util.UUID;
public abstract class GameCanadianHighlanderImpl extends GameImpl { public abstract class GameCanadianHighlanderImpl extends GameImpl {
public GameCanadianHighlanderImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public GameCanadianHighlanderImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, startLife, 100, 7); super(attackOption, range, mulligan, 100, startLife, startHandSize);
} }
protected GameCanadianHighlanderImpl(final GameCanadianHighlanderImpl game) { protected GameCanadianHighlanderImpl(final GameCanadianHighlanderImpl game) {

View file

@ -33,8 +33,8 @@ public abstract class GameCommanderImpl extends GameImpl {
// (see rule 504, "Draw Step") of his or her first turn. // (see rule 504, "Draw Step") of his or her first turn.
protected boolean startingPlayerSkipsDraw = true; protected boolean startingPlayerSkipsDraw = true;
public GameCommanderImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startingLife, int minimumDeckSize) { public GameCommanderImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int minimumDeckSize, int startLife, int startHandSize) {
super(attackOption, range, mulligan, startingLife, minimumDeckSize, 7); super(attackOption, range, mulligan, minimumDeckSize, startLife, startHandSize);
} }
protected GameCommanderImpl(final GameCommanderImpl game) { protected GameCommanderImpl(final GameCommanderImpl game) {

View file

@ -157,7 +157,7 @@ public abstract class GameImpl implements Game {
// temporary store for income concede commands, don't copy // temporary store for income concede commands, don't copy
private final LinkedList<UUID> concedingPlayers = new LinkedList<>(); private final LinkedList<UUID> concedingPlayers = new LinkedList<>();
public GameImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startingLife, int minimumDeckSize, int startingHandSize) { public GameImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int minimumDeckSize, int startingLife, int startingHandSize) {
this.id = UUID.randomUUID(); this.id = UUID.randomUUID();
this.range = range; this.range = range;
this.mulligan = mulligan; this.mulligan = mulligan;

View file

@ -34,8 +34,8 @@ public abstract class GameTinyLeadersImpl extends GameImpl {
// (see rule 504, "Draw Step") of his or her first turn. // (see rule 504, "Draw Step") of his or her first turn.
protected boolean startingPlayerSkipsDraw = true; protected boolean startingPlayerSkipsDraw = true;
public GameTinyLeadersImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { public GameTinyLeadersImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startHandSize) {
super(attackOption, range, mulligan, startLife, 50, 7); super(attackOption, range, mulligan, 50, startLife, startHandSize);
} }
protected GameTinyLeadersImpl(final GameTinyLeadersImpl game) { protected GameTinyLeadersImpl(final GameTinyLeadersImpl game) {

View file

@ -15,7 +15,6 @@ import java.io.Serializable;
import java.util.*; import java.util.*;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class MatchOptions implements Serializable { public class MatchOptions implements Serializable {
@ -25,6 +24,10 @@ public class MatchOptions implements Serializable {
protected RangeOfInfluence range; protected RangeOfInfluence range;
protected int winsNeeded; protected int winsNeeded;
protected int freeMulligans; protected int freeMulligans;
protected boolean customStartLifeEnabled;
protected int customStartLife; // Only use if customStartLifeEnabled is True
protected boolean customStartHandSizeEnabled;
protected int customStartHandSize; // Only use if customStartHandSizeEnabled is True
protected String gameType; protected String gameType;
protected String deckType; protected String deckType;
protected boolean limited; protected boolean limited;
@ -53,13 +56,6 @@ public class MatchOptions implements Serializable {
protected Collection<DeckCardInfo> perPlayerEmblemCards; protected Collection<DeckCardInfo> perPlayerEmblemCards;
protected Collection<DeckCardInfo> globalEmblemCards; protected Collection<DeckCardInfo> globalEmblemCards;
/*public MatchOptions(String name, String gameType) {
this.name = name;
this.gameType = gameType;
this.password = "";
this.multiPlayer = false;
this.numSeats = 2;
}*/
public MatchOptions(String name, String gameType, boolean multiPlayer, int numSeats) { public MatchOptions(String name, String gameType, boolean multiPlayer, int numSeats) {
this.name = name; this.name = name;
this.gameType = gameType; this.gameType = gameType;
@ -70,11 +66,11 @@ public class MatchOptions implements Serializable {
this.globalEmblemCards = Collections.emptySet(); this.globalEmblemCards = Collections.emptySet();
} }
public void setNumSeats (int numSeats) { public void setNumSeats(int numSeats) {
this.numSeats = numSeats; this.numSeats = numSeats;
} }
public int getNumSeats () { public int getNumSeats() {
return numSeats; return numSeats;
} }
@ -122,6 +118,38 @@ public class MatchOptions implements Serializable {
this.freeMulligans = freeMulligans; this.freeMulligans = freeMulligans;
} }
public boolean isCustomStartLifeEnabled() {
return customStartLifeEnabled;
}
public void setCustomStartLifeEnabled(boolean value) {
this.customStartLifeEnabled = value;
}
public int getCustomStartLife() {
return customStartLife;
}
public void setCustomStartLife(int startLife) {
this.customStartLife = startLife;
}
public boolean isCustomStartHandSizeEnabled() {
return customStartHandSizeEnabled;
}
public void setCustomStartHandSizeEnabled(boolean value) {
this.customStartHandSizeEnabled = value;
}
public int getCustomStartHandSize() {
return customStartHandSize;
}
public void setCustomStartHandSize(int startHandSize) {
this.customStartHandSize = startHandSize;
}
public String getGameType() { public String getGameType() {
return gameType; return gameType;
} }
@ -211,11 +239,11 @@ public class MatchOptions implements Serializable {
public void setSpectatorsAllowed(boolean spectatorsAllowed) { public void setSpectatorsAllowed(boolean spectatorsAllowed) {
this.spectatorsAllowed = spectatorsAllowed; this.spectatorsAllowed = spectatorsAllowed;
} }
public boolean isPlaneChase() { public boolean isPlaneChase() {
return planeChase; return planeChase;
} }
public void setPlaneChase(boolean planeChase) { public void setPlaneChase(boolean planeChase) {
this.planeChase = planeChase; this.planeChase = planeChase;
} }
@ -228,9 +256,13 @@ public class MatchOptions implements Serializable {
this.quitRatio = quitRatio; this.quitRatio = quitRatio;
} }
public int getMinimumRating() { return minimumRating; } public int getMinimumRating() {
return minimumRating;
}
public void setMinimumRating(int minimumRating) { this.minimumRating = minimumRating; } public void setMinimumRating(int minimumRating) {
this.minimumRating = minimumRating;
}
public int getEdhPowerLevel() { public int getEdhPowerLevel() {
return edhPowerLevel; return edhPowerLevel;