* GUI: added auto-choose for replacement effects (remember answer in dialog + reset answer in popup menu + new option in preferences; #4360, #328, #4219, #6676, #7914);

This commit is contained in:
Oleg Agafonov 2021-08-09 11:25:51 +04:00
parent c081d3fa33
commit c9ab896d24
11 changed files with 311 additions and 77 deletions

View file

@ -324,9 +324,9 @@ public class PickCheckBoxDialog extends MageDialog {
if (item != null) { if (item != null) {
if (choice.isKeyChoice()) { if (choice.isKeyChoice()) {
choice.setChoiceByKey(item.getKey()); choice.setChoiceByKey(item.getKey(), false);
} else { } else {
choice.setChoice(item.getKey()); choice.setChoice(item.getKey(), false);
} }
return true; return true;
} else { } else {

View file

@ -161,7 +161,8 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="cbSpecial" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
<Component id="btOK" linkSize="3" min="-2" max="-2" attributes="0"/> <Component id="btOK" linkSize="3" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
@ -177,6 +178,7 @@
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="btCancel" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="btCancel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btOK" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="btOK" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="cbSpecial" alignment="3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
@ -203,6 +205,11 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btCancelActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btCancelActionPerformed"/>
</Events> </Events>
</Component> </Component>
<Component class="javax.swing.JCheckBox" name="cbSpecial">
<Properties>
<Property name="text" type="java.lang.String" value="Remember choose"/>
</Properties>
</Component>
</SubComponents> </SubComponents>
</Container> </Container>
</SubComponents> </SubComponents>

View file

@ -18,10 +18,11 @@ import mage.client.util.gui.MageDialogState;
public class PickChoiceDialog extends MageDialog { public class PickChoiceDialog extends MageDialog {
Choice choice; Choice choice;
java.util.List<KeyValueItem> allItems = new ArrayList<>(); java.util.List<KeyValueItem> allItems = new ArrayList<>();
DefaultListModel<KeyValueItem> dataModel = new DefaultListModel<>(); DefaultListModel<KeyValueItem> dataModel = new DefaultListModel<>();
final private static String HTML_TEMPLATE = "<html><div style='text-align: center;'>%s</div></html>"; final private static String HTML_HEADERS_TEMPLATE = "<html><div style='text-align: center;'>%s</div></html>";
public void showDialog(Choice choice) { public void showDialog(Choice choice) {
showDialog(choice, null, null, null); showDialog(choice, null, null, null);
@ -40,9 +41,13 @@ public class PickChoiceDialog extends MageDialog {
setLabelText(this.labelMessage, choice.getMessage()); setLabelText(this.labelMessage, choice.getMessage());
setLabelText(this.labelSubMessage, choice.getSubMessage()); setLabelText(this.labelSubMessage, choice.getSubMessage());
btCancel.setEnabled(!choice.isRequired()); btCancel.setEnabled(!choice.isRequired());
// special choice (example: auto-choose answer next time)
cbSpecial.setVisible(choice.isSpecialEnabled());
cbSpecial.setText(choice.getSpecialText());
cbSpecial.setToolTipText(choice.getSpecialHint());
// 2 modes: string or key-values // 2 modes: string or key-values
// sore data in allItems for inremental filtering // sore data in allItems for inremental filtering
// http://logicbig.com/tutorials/core-java-tutorial/swing/list-filter/ // http://logicbig.com/tutorials/core-java-tutorial/swing/list-filter/
@ -199,7 +204,7 @@ public class PickChoiceDialog extends MageDialog {
private void setLabelText(JLabel label, String text) { private void setLabelText(JLabel label, String text) {
if ((text != null) && !text.equals("")) { if ((text != null) && !text.equals("")) {
label.setText(String.format(HTML_TEMPLATE, text)); label.setText(String.format(HTML_HEADERS_TEMPLATE, text));
label.setVisible(true); label.setVisible(true);
} else { } else {
label.setText(""); label.setText("");
@ -247,6 +252,7 @@ public class PickChoiceDialog extends MageDialog {
public boolean setChoice() { public boolean setChoice() {
KeyValueItem item = (KeyValueItem) this.listChoices.getSelectedValue(); KeyValueItem item = (KeyValueItem) this.listChoices.getSelectedValue();
boolean isSpecial = choice.isSpecialEnabled() && cbSpecial.isSelected();
// auto select one item (after incemental filtering) // auto select one item (after incemental filtering)
if ((item == null) && (this.listChoices.getModel().getSize() == 1)) { if ((item == null) && (this.listChoices.getModel().getSize() == 1)) {
@ -256,12 +262,23 @@ public class PickChoiceDialog extends MageDialog {
if (item != null) { if (item != null) {
if (choice.isKeyChoice()) { if (choice.isKeyChoice()) {
choice.setChoiceByKey(item.getKey()); choice.setChoiceByKey(item.getKey(), isSpecial);
} else { } else {
choice.setChoice(item.getKey()); choice.setChoice(item.getKey(), isSpecial);
} }
return true; return true;
} else { } else {
// special choice can be empty
if (choice.isSpecialEnabled() && choice.isSpecialCanBeEmpty()) {
if (choice.isKeyChoice()) {
choice.setChoiceByKey(null, isSpecial);
} else {
choice.setChoice(null, isSpecial);
}
return true;
}
// nothing to choose
choice.clearChoice(); choice.clearChoice();
return false; return false;
} }
@ -311,6 +328,7 @@ public class PickChoiceDialog extends MageDialog {
panelCommands = new javax.swing.JPanel(); panelCommands = new javax.swing.JPanel();
btOK = new javax.swing.JButton(); btOK = new javax.swing.JButton();
btCancel = new javax.swing.JButton(); btCancel = new javax.swing.JButton();
cbSpecial = new javax.swing.JCheckBox();
setResizable(true); setResizable(true);
@ -386,19 +404,22 @@ public class PickChoiceDialog extends MageDialog {
} }
}); });
cbSpecial.setText("Remember choose");
javax.swing.GroupLayout panelCommandsLayout = new javax.swing.GroupLayout(panelCommands); javax.swing.GroupLayout panelCommandsLayout = new javax.swing.GroupLayout(panelCommands);
panelCommands.setLayout(panelCommandsLayout); panelCommands.setLayout(panelCommandsLayout);
panelCommandsLayout.setHorizontalGroup( panelCommandsLayout.setHorizontalGroup(
panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelCommandsLayout.createSequentialGroup() .addGroup(panelCommandsLayout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(cbSpecial)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btOK) .addComponent(btOK)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(btCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap()) .addContainerGap())
); );
panelCommandsLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, btCancel, btOK); panelCommandsLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {btCancel, btOK});
panelCommandsLayout.setVerticalGroup( panelCommandsLayout.setVerticalGroup(
panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -406,7 +427,8 @@ public class PickChoiceDialog extends MageDialog {
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btCancel) .addComponent(btCancel)
.addComponent(btOK)) .addComponent(btOK)
.addComponent(cbSpecial))
.addContainerGap()) .addContainerGap())
); );
@ -460,6 +482,7 @@ public class PickChoiceDialog extends MageDialog {
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btCancel; private javax.swing.JButton btCancel;
private javax.swing.JButton btOK; private javax.swing.JButton btOK;
private javax.swing.JCheckBox cbSpecial;
private javax.swing.JTextField editSearch; private javax.swing.JTextField editSearch;
private javax.swing.JLabel labelMessage; private javax.swing.JLabel labelMessage;
private javax.swing.JLabel labelSearch; private javax.swing.JLabel labelSearch;

View file

@ -4082,8 +4082,8 @@
<Component id="checkBoxEndTurnOthers" min="-2" max="-2" attributes="0"/> <Component id="checkBoxEndTurnOthers" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="phases_stopSettings" min="-2" max="-2" attributes="0"/> <Component id="phases_stopSettings" pref="291" max="32767" attributes="0"/>
<EmptySpace max="32767" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -4182,7 +4182,7 @@
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout"> <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout">
<Property name="columns" type="int" value="1"/> <Property name="columns" type="int" value="1"/>
<Property name="rows" type="int" value="9"/> <Property name="rows" type="int" value="10"/>
</Layout> </Layout>
<SubComponents> <SubComponents>
<Component class="javax.swing.JCheckBox" name="cbStopAttack"> <Component class="javax.swing.JCheckBox" name="cbStopAttack">
@ -4281,8 +4281,8 @@
</Component> </Component>
<Component class="javax.swing.JCheckBox" name="cbAutoOrderTrigger"> <Component class="javax.swing.JCheckBox" name="cbAutoOrderTrigger">
<Properties> <Properties>
<Property name="text" type="java.lang.String" value="Set order for your triggers automatically if all have the same text"/> <Property name="text" type="java.lang.String" value="TRIGGERS: auto-choose triggers order for same rule texts (put same triggers to the stack at default order)"/>
<Property name="toolTipText" type="java.lang.String" value="&lt;HTML&gt;If activated the order to put on the stack your triggers that trigger at the same time&lt;br/&gt;&#xa;is set automatically if all have the same text."/> <Property name="toolTipText" type="java.lang.String" value="&lt;HTML&gt;If you put same triggers with same texts on the stack then auto-choose their order.&lt;br/&gt;&#xa;You can change that settings anytime at the game."/>
<Property name="actionCommand" type="java.lang.String" value=""/> <Property name="actionCommand" type="java.lang.String" value=""/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[300, 25]"/> <Dimension value="[300, 25]"/>
@ -4292,6 +4292,19 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbAutoOrderTriggerActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbAutoOrderTriggerActionPerformed"/>
</Events> </Events>
</Component> </Component>
<Component class="javax.swing.JCheckBox" name="cbUseSameSettingsForReplacementEffect">
<Properties>
<Property name="text" type="java.lang.String" value="REPLACEMENT EFFECTS: use same auto-choose settings for same cards (choose replacement effects order dialog)"/>
<Property name="toolTipText" type="java.lang.String" value="&lt;HTML&gt;If you setup auto-choose for one object/card then it will be applied for all other objects with same name.&lt;br/&gt;&#xa;You can change that settings anytime at the game."/>
<Property name="actionCommand" type="java.lang.String" value=""/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[300, 25]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbUseSameSettingsForReplacementEffectActionPerformed"/>
</Events>
</Component>
</SubComponents> </SubComponents>
</Container> </Container>
</SubComponents> </SubComponents>

View file

@ -134,6 +134,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static final String KEY_PASS_PRIORITY_CAST = "passPriorityCast"; public static final String KEY_PASS_PRIORITY_CAST = "passPriorityCast";
public static final String KEY_PASS_PRIORITY_ACTIVATION = "passPriorityActivation"; public static final String KEY_PASS_PRIORITY_ACTIVATION = "passPriorityActivation";
public static final String KEY_AUTO_ORDER_TRIGGER = "autoOrderTrigger"; public static final String KEY_AUTO_ORDER_TRIGGER = "autoOrderTrigger";
public static final String KEY_USE_SAME_SETTINGS_FOR_SAME_REPLACEMENT_EFFECTS = "useSameSettingsForSameReplacementEffects";
public static final String KEY_USE_FIRST_MANA_ABILITY = "useFirstManaAbility"; public static final String KEY_USE_FIRST_MANA_ABILITY = "useFirstManaAbility";
// mana auto payment // mana auto payment
@ -501,6 +502,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
cbPassPriorityCast = new javax.swing.JCheckBox(); cbPassPriorityCast = new javax.swing.JCheckBox();
cbPassPriorityActivation = new javax.swing.JCheckBox(); cbPassPriorityActivation = new javax.swing.JCheckBox();
cbAutoOrderTrigger = new javax.swing.JCheckBox(); cbAutoOrderTrigger = new javax.swing.JCheckBox();
cbUseSameSettingsForReplacementEffect = new javax.swing.JCheckBox();
tabImages = new javax.swing.JPanel(); tabImages = new javax.swing.JPanel();
panelCardImages = new javax.swing.JPanel(); panelCardImages = new javax.swing.JPanel();
cbUseDefaultImageFolder = new javax.swing.JCheckBox(); cbUseDefaultImageFolder = new javax.swing.JCheckBox();
@ -1405,7 +1407,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
jLabelEndOfTurn.setText("End of turn:"); jLabelEndOfTurn.setText("End of turn:");
phases_stopSettings.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "SKIP settings")); phases_stopSettings.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "SKIP settings"));
phases_stopSettings.setLayout(new java.awt.GridLayout(9, 1)); phases_stopSettings.setLayout(new java.awt.GridLayout(10, 1));
cbStopAttack.setSelected(true); cbStopAttack.setSelected(true);
cbStopAttack.setText("STOP skips on declare attackers if attackers are available"); cbStopAttack.setText("STOP skips on declare attackers if attackers are available");
@ -1493,8 +1495,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
}); });
phases_stopSettings.add(cbPassPriorityActivation); phases_stopSettings.add(cbPassPriorityActivation);
cbAutoOrderTrigger.setText("Set order for your triggers automatically if all have the same text"); cbAutoOrderTrigger.setText("TRIGGERS: auto-choose triggers order for same rule texts (put same triggers to the stack at default order)");
cbAutoOrderTrigger.setToolTipText("<HTML>If activated the order to put on the stack your triggers that trigger at the same time<br/>\nis set automatically if all have the same text."); cbAutoOrderTrigger.setToolTipText("<HTML>If you put same triggers with same texts on the stack then auto-choose their order.<br/>\nYou can change that settings anytime at the game.");
cbAutoOrderTrigger.setActionCommand(""); cbAutoOrderTrigger.setActionCommand("");
cbAutoOrderTrigger.setPreferredSize(new java.awt.Dimension(300, 25)); cbAutoOrderTrigger.setPreferredSize(new java.awt.Dimension(300, 25));
cbAutoOrderTrigger.addActionListener(new java.awt.event.ActionListener() { cbAutoOrderTrigger.addActionListener(new java.awt.event.ActionListener() {
@ -1504,6 +1506,17 @@ public class PreferencesDialog extends javax.swing.JDialog {
}); });
phases_stopSettings.add(cbAutoOrderTrigger); phases_stopSettings.add(cbAutoOrderTrigger);
cbUseSameSettingsForReplacementEffect.setText("REPLACEMENT EFFECTS: use same auto-choose settings for same cards (choose replacement effects order dialog)");
cbUseSameSettingsForReplacementEffect.setToolTipText("<HTML>If you setup auto-choose for one object/card then it will be applied for all other objects with same name.<br/>\nYou can change that settings anytime at the game.");
cbUseSameSettingsForReplacementEffect.setActionCommand("");
cbUseSameSettingsForReplacementEffect.setPreferredSize(new java.awt.Dimension(300, 25));
cbUseSameSettingsForReplacementEffect.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbUseSameSettingsForReplacementEffectActionPerformed(evt);
}
});
phases_stopSettings.add(cbUseSameSettingsForReplacementEffect);
org.jdesktop.layout.GroupLayout tabPhasesLayout = new org.jdesktop.layout.GroupLayout(tabPhases); org.jdesktop.layout.GroupLayout tabPhasesLayout = new org.jdesktop.layout.GroupLayout(tabPhases);
tabPhases.setLayout(tabPhasesLayout); tabPhases.setLayout(tabPhasesLayout);
tabPhasesLayout.setHorizontalGroup( tabPhasesLayout.setHorizontalGroup(
@ -1614,8 +1627,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
.add(jLabelEndOfTurn) .add(jLabelEndOfTurn)
.add(checkBoxEndTurnOthers)) .add(checkBoxEndTurnOthers))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(phases_stopSettings, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(phases_stopSettings, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 291, Short.MAX_VALUE)
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap())
); );
tabsPanel.addTab("Phases & Priority", tabPhases); tabsPanel.addTab("Phases & Priority", tabPhases);
@ -2925,6 +2938,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
save(prefs, dialog.cbPassPriorityCast, KEY_PASS_PRIORITY_CAST, "true", "false", UPDATE_CACHE_POLICY); save(prefs, dialog.cbPassPriorityCast, KEY_PASS_PRIORITY_CAST, "true", "false", UPDATE_CACHE_POLICY);
save(prefs, dialog.cbPassPriorityActivation, KEY_PASS_PRIORITY_ACTIVATION, "true", "false", UPDATE_CACHE_POLICY); save(prefs, dialog.cbPassPriorityActivation, KEY_PASS_PRIORITY_ACTIVATION, "true", "false", UPDATE_CACHE_POLICY);
save(prefs, dialog.cbAutoOrderTrigger, KEY_AUTO_ORDER_TRIGGER, "true", "false", UPDATE_CACHE_POLICY); save(prefs, dialog.cbAutoOrderTrigger, KEY_AUTO_ORDER_TRIGGER, "true", "false", UPDATE_CACHE_POLICY);
save(prefs, dialog.cbUseSameSettingsForReplacementEffect, KEY_USE_SAME_SETTINGS_FOR_SAME_REPLACEMENT_EFFECTS, "true", "false", UPDATE_CACHE_POLICY);
// images // images
save(prefs, dialog.cbUseDefaultImageFolder, KEY_CARD_IMAGES_USE_DEFAULT, "true", "false", UPDATE_CACHE_POLICY); save(prefs, dialog.cbUseDefaultImageFolder, KEY_CARD_IMAGES_USE_DEFAULT, "true", "false", UPDATE_CACHE_POLICY);
@ -3309,6 +3323,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
} }
}//GEN-LAST:event_sliderGUISizeStateChanged }//GEN-LAST:event_sliderGUISizeStateChanged
private void cbUseSameSettingsForReplacementEffectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbUseSameSettingsForReplacementEffectActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_cbUseSameSettingsForReplacementEffectActionPerformed
private void showProxySettings() { private void showProxySettings() {
Connection.ProxyType proxyType = (Connection.ProxyType) cbProxyType.getSelectedItem(); Connection.ProxyType proxyType = (Connection.ProxyType) cbProxyType.getSelectedItem();
switch (proxyType) { switch (proxyType) {
@ -3465,7 +3483,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
load(prefs, dialog.cbPassPriorityCast, KEY_PASS_PRIORITY_CAST, "true", "false"); load(prefs, dialog.cbPassPriorityCast, KEY_PASS_PRIORITY_CAST, "true", "false");
load(prefs, dialog.cbPassPriorityActivation, KEY_PASS_PRIORITY_ACTIVATION, "true", "false"); load(prefs, dialog.cbPassPriorityActivation, KEY_PASS_PRIORITY_ACTIVATION, "true", "false");
load(prefs, dialog.cbAutoOrderTrigger, KEY_AUTO_ORDER_TRIGGER, "true", "true"); load(prefs, dialog.cbAutoOrderTrigger, KEY_AUTO_ORDER_TRIGGER, "true", "true");
load(prefs, dialog.cbUseSameSettingsForReplacementEffect, KEY_USE_SAME_SETTINGS_FOR_SAME_REPLACEMENT_EFFECTS, "true", "true");
} }
private static void loadGuiSize(Preferences prefs) { private static void loadGuiSize(Preferences prefs) {
@ -3996,6 +4014,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PASS_PRIORITY_CAST, "true").equals("true"), PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PASS_PRIORITY_CAST, "true").equals("true"),
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PASS_PRIORITY_ACTIVATION, "true").equals("true"), PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PASS_PRIORITY_ACTIVATION, "true").equals("true"),
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_AUTO_ORDER_TRIGGER, "true").equals("true"), PreferencesDialog.getCachedValue(PreferencesDialog.KEY_AUTO_ORDER_TRIGGER, "true").equals("true"),
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_USE_SAME_SETTINGS_FOR_SAME_REPLACEMENT_EFFECTS, "true").equals("true"),
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"), PreferencesDialog.getCachedValue(PreferencesDialog.KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"),
userStrId userStrId
); );
@ -4069,6 +4088,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JCheckBox cbUseDefaultBattleImage; private javax.swing.JCheckBox cbUseDefaultBattleImage;
private javax.swing.JCheckBox cbUseDefaultImageFolder; private javax.swing.JCheckBox cbUseDefaultImageFolder;
private javax.swing.JCheckBox cbUseRandomBattleImage; private javax.swing.JCheckBox cbUseRandomBattleImage;
private javax.swing.JCheckBox cbUseSameSettingsForReplacementEffect;
private javax.swing.JLabel chatFontSizeLabel; private javax.swing.JLabel chatFontSizeLabel;
private javax.swing.JCheckBox checkBoxBeforeCOthers; private javax.swing.JCheckBox checkBoxBeforeCOthers;
private javax.swing.JCheckBox checkBoxBeforeCYou; private javax.swing.JCheckBox checkBoxBeforeCYou;

View file

@ -108,7 +108,7 @@ public final class GamePanel extends javax.swing.JPanel {
private boolean initComponents; private boolean initComponents;
private Timer resizeTimer; // can't be final private final Timer resizeTimer; // can't be final
private enum PopUpMenuType { private enum PopUpMenuType {
TRIGGER_ORDER TRIGGER_ORDER
@ -128,6 +128,7 @@ public final class GamePanel extends javax.swing.JPanel {
Map<String, Serializable> options; Map<String, Serializable> options;
Set<UUID> targets; Set<UUID> targets;
} }
private final LastGameData lastGameData = new LastGameData(); private final LastGameData lastGameData = new LastGameData();
@ -1746,18 +1747,22 @@ public final class GamePanel extends javax.swing.JPanel {
// TODO: remember last choices and search incremental for same events? // TODO: remember last choices and search incremental for same events?
PickChoiceDialog pickChoice = new PickChoiceDialog(); PickChoiceDialog pickChoice = new PickChoiceDialog();
pickChoice.showDialog(choice, objectId, choiceWindowState); pickChoice.showDialog(choice, objectId, choiceWindowState);
// special mode adds # to the answer (server side code must process that prefix, see replacementEffectChoice)
String specialPrefix = choice.isChosenSpecial() ? "#" : "";
String valueToSend;
if (choice.isKeyChoice()) { if (choice.isKeyChoice()) {
SessionHandler.sendPlayerString(gameId, choice.getChoiceKey()); valueToSend = choice.getChoiceKey();
/* // old code, auto complete was for auto scripting?
if (pickChoice.isAutoSelect()) {
SessionHandler.sendPlayerString(gameId, '#' + choice.getChoiceKey());
} else {
SessionHandler.sendPlayerString(gameId, choice.getChoiceKey());
}*/
} else { } else {
valueToSend = choice.getChoice();
SessionHandler.sendPlayerString(gameId, choice.getChoice()); SessionHandler.sendPlayerString(gameId, choice.getChoice());
} }
SessionHandler.sendPlayerString(gameId, valueToSend == null ? null : specialPrefix + valueToSend);
// keep dialog position
choiceWindowState = new MageDialogState(pickChoice); choiceWindowState = new MageDialogState(pickChoice);
pickChoice.removeDialog(); pickChoice.removeDialog();
} }

View file

@ -74,7 +74,7 @@ public class HumanPlayer extends PlayerImpl {
protected final Choice replacementEffectChoice; protected final Choice replacementEffectChoice;
private static final Logger logger = Logger.getLogger(HumanPlayer.class); private static final Logger logger = Logger.getLogger(HumanPlayer.class);
protected HashSet<String> autoSelectReplacementEffects = new HashSet<>(); protected HashSet<String> autoSelectReplacementEffects = new LinkedHashSet<>(); // must be sorted
protected ManaCost currentlyUnpaidMana; protected ManaCost currentlyUnpaidMana;
protected Set<UUID> triggerAutoOrderAbilityFirst = new HashSet<>(); protected Set<UUID> triggerAutoOrderAbilityFirst = new HashSet<>();
@ -96,9 +96,16 @@ public class HumanPlayer extends PlayerImpl {
public HumanPlayer(String name, RangeOfInfluence range, int skill) { public HumanPlayer(String name, RangeOfInfluence range, int skill) {
super(name, range); super(name, range);
human = true;
replacementEffectChoice = new ChoiceImpl(true); replacementEffectChoice = new ChoiceImpl(true);
replacementEffectChoice.setMessage("Choose replacement effect to resolve first"); replacementEffectChoice.setMessage("Choose replacement effect to resolve first");
human = true; replacementEffectChoice.setSpecial(
true,
false,
"Remember answer",
"Choose same answer next time (you can reset saved answers by battlefield popup menu)"
);
} }
public HumanPlayer(final HumanPlayer player) { public HumanPlayer(final HumanPlayer player) {
@ -289,6 +296,8 @@ public class HumanPlayer extends PlayerImpl {
if (falseText != null) { if (falseText != null) {
options.put("UI.right.btn.text", falseText); options.put("UI.right.btn.text", falseText);
} }
// auto-answer
if (source != null) { if (source != null) {
Boolean answer = requestAutoAnswerId.get(source.getOriginalId() + "#" + message); Boolean answer = requestAutoAnswerId.get(source.getOriginalId() + "#" + message);
if (answer != null) { if (answer != null) {
@ -359,11 +368,20 @@ public class HumanPlayer extends PlayerImpl {
return 0; return 0;
} }
// use auto-choice:
// - uses "always first" logic (choose in same order as user answer saves)
// - search same effects by text (object name [id]: rules)
// - autoSelectReplacementEffects is sorted set
// - must get "same settings" option between cycle/response (user can change it by preferences)
boolean useSameSettings = getControllingPlayersUserData(game).isUseSameSettingsForReplacementEffects();
if (!autoSelectReplacementEffects.isEmpty()) { if (!autoSelectReplacementEffects.isEmpty()) {
for (String autoKey : autoSelectReplacementEffects) { for (String autoText : autoSelectReplacementEffects) {
int count = 0; int count = 0;
// find effect with same saved text
for (String effectKey : rEffects.keySet()) { for (String effectKey : rEffects.keySet()) {
if (effectKey.equals(autoKey)) { String currentText = prepareReplacementText(rEffects.get(effectKey), useSameSettings);
if (currentText.equals(autoText)) {
return count; return count;
} }
count++; count++;
@ -371,10 +389,11 @@ public class HumanPlayer extends PlayerImpl {
} }
} }
replacementEffectChoice.clearChoice();
replacementEffectChoice.getChoices().clear(); replacementEffectChoice.getChoices().clear();
replacementEffectChoice.setKeyChoices(rEffects); replacementEffectChoice.setKeyChoices(rEffects);
// Check if there are different ones // if same choices then select first
int differentChoices = 0; int differentChoices = 0;
String lastChoice = ""; String lastChoice = "";
for (String value : replacementEffectChoice.getKeyChoices().values()) { for (String value : replacementEffectChoice.getKeyChoices().values()) {
@ -397,11 +416,18 @@ public class HumanPlayer extends PlayerImpl {
logger.debug("Choose effect: " + response.getString()); logger.debug("Choose effect: " + response.getString());
if (response.getString() != null) { if (response.getString() != null) {
// save auto-choice (effect's text)
if (response.getString().startsWith("#")) { if (response.getString().startsWith("#")) {
autoSelectReplacementEffects.add(response.getString().substring(1)); replacementEffectChoice.setChoiceByKey(response.getString().substring(1), true);
replacementEffectChoice.setChoiceByKey(response.getString().substring(1)); if (replacementEffectChoice.isChosen()) {
// put auto-choice to the end
useSameSettings = getControllingPlayersUserData(game).isUseSameSettingsForReplacementEffects();
String effectText = prepareReplacementText(replacementEffectChoice.getChoiceValue(), useSameSettings);
autoSelectReplacementEffects.remove(effectText);
autoSelectReplacementEffects.add(effectText);
}
} else { } else {
replacementEffectChoice.setChoiceByKey(response.getString()); replacementEffectChoice.setChoiceByKey(response.getString(), false);
} }
if (replacementEffectChoice.getChoiceKey() != null) { if (replacementEffectChoice.getChoiceKey() != null) {
@ -419,6 +445,14 @@ public class HumanPlayer extends PlayerImpl {
return 0; return 0;
} }
private String prepareReplacementText(String fullText, boolean useSameSettingsForDifferentObjects) {
// remove object id from the rules text (example: object [abd]: rules -> object : rules)
if (useSameSettingsForDifferentObjects) {
fullText = fullText.replaceAll("\\[\\w+\\]", "");
}
return fullText;
}
@Override @Override
public boolean choose(Outcome outcome, Choice choice, Game game) { public boolean choose(Outcome outcome, Choice choice, Game game) {
if (gameInCheckPlayableState(game)) { if (gameInCheckPlayableState(game)) {

View file

@ -189,7 +189,7 @@ public class ContinuousEffects implements Serializable {
} }
} }
} else { } else {
logger.error("No abilities for continuous effect: " + effect.toString()); logger.error("No abilities for continuous effect: " + effect);
} }
break; break;
default: default:
@ -1282,7 +1282,7 @@ public class ContinuousEffects implements Serializable {
logger.error("Effect is null: " + source.toString()); logger.error("Effect is null: " + source.toString());
return; return;
} else if (source == null) { } else if (source == null) {
logger.warn("Adding effect without ability : " + effect.toString()); logger.warn("Adding effect without ability : " + effect);
} }
switch (effect.getEffectType()) { switch (effect.getEffectType()) {
case REPLACEMENT: case REPLACEMENT:
@ -1369,6 +1369,8 @@ public class ContinuousEffects implements Serializable {
} }
public Map<String, String> getReplacementEffectsTexts(Map<ReplacementEffect, Set<Ability>> rEffects, Game game) { public Map<String, String> getReplacementEffectsTexts(Map<ReplacementEffect, Set<Ability>> rEffects, Game game) {
// warning, autoSelectReplacementEffects uses [object id] in texts as different settings,
// so if you change keys or texts logic then don't forget to change auto-choose too
Map<String, String> texts = new LinkedHashMap<>(); Map<String, String> texts = new LinkedHashMap<>();
for (Map.Entry<ReplacementEffect, Set<Ability>> entry : rEffects.entrySet()) { for (Map.Entry<ReplacementEffect, Set<Ability>> entry : rEffects.entrySet()) {
if (entry.getValue() != null) { if (entry.getValue() != null) {

View file

@ -1,55 +1,92 @@
package mage.choices; package mage.choices;
import mage.util.Copyable;
import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
/** /**
*
* @author BetaSteward_at_googlemail.com, JayDi85 * @author BetaSteward_at_googlemail.com, JayDi85
*/ */
public interface Choice { public interface Choice extends Serializable, Copyable<Choice> {
String getMessage(); String getMessage();
void setMessage(String message); void setMessage(String message);
String getSubMessage(); String getSubMessage();
void setSubMessage(String subMessage); void setSubMessage(String subMessage);
void clearChoice(); void clearChoice();
boolean isChosen(); boolean isChosen();
boolean isChosenSpecial();
boolean isRequired(); boolean isRequired();
Choice copy(); // special mode for all choices
void setSpecial(boolean enabled, boolean canBeEmpty, String text, String hint);
boolean isSpecialEnabled();
boolean isSpecialCanBeEmpty();
String getSpecialText();
String getSpecialHint();
// string choice // string choice
void setChoices(Set<String> choices); void setChoices(Set<String> choices);
Set<String> getChoices(); Set<String> getChoices();
void setChoice(String choice);
void setChoice(String choice, boolean isSpecial);
String getChoice(); String getChoice();
default void setChoice(String choice) {
setChoice(choice, false);
}
// key-value choice // key-value choice
boolean isKeyChoice(); boolean isKeyChoice();
void setKeyChoices(Map<String, String> choices); void setKeyChoices(Map<String, String> choices);
Map<String, String> getKeyChoices(); Map<String, String> getKeyChoices();
void setChoiceByKey(String choiceKey);
void setChoiceByKey(String choiceKey, boolean isSpecial);
String getChoiceKey(); String getChoiceKey();
String getChoiceValue(); String getChoiceValue();
default void setChoiceByKey(String choiceKey) {
setChoiceByKey(choiceKey, false);
}
// search // search
boolean isSearchEnabled(); boolean isSearchEnabled();
void setSearchEnabled(boolean isEnabled); void setSearchEnabled(boolean isEnabled);
void setSearchText(String searchText); void setSearchText(String searchText);
String getSearchText(); String getSearchText();
// sorting // sorting
boolean isSortEnabled(); boolean isSortEnabled();
void setSortData(Map<String, Integer> sortData); void setSortData(Map<String, Integer> sortData);
Map<String, Integer> getSortData(); Map<String, Integer> getSortData();
// random choice // random choice (for AI usage)
void setRandomChoice(); void setRandomChoice();
boolean setChoiceByAnswers(List<String> answers, boolean removeSelectAnswerFromList); boolean setChoiceByAnswers(List<String> answers, boolean removeSelectAnswerFromList);
} }

View file

@ -2,15 +2,15 @@ package mage.choices;
import mage.util.RandomUtil; import mage.util.RandomUtil;
import java.io.Serializable;
import java.util.*; import java.util.*;
/** /**
* @author BetaSteward_at_googlemail.com, JayDi85 * @author BetaSteward_at_googlemail.com, JayDi85
*/ */
public class ChoiceImpl implements Choice, Serializable { public class ChoiceImpl implements Choice {
protected boolean chosen; protected boolean chosenNormal;
protected boolean chosenSpecial;
protected final boolean required; protected final boolean required;
protected String choice; protected String choice;
protected String choiceKey; protected String choiceKey;
@ -22,6 +22,13 @@ public class ChoiceImpl implements Choice, Serializable {
protected boolean searchEnabled = true; // enable for all windows by default protected boolean searchEnabled = true; // enable for all windows by default
protected String searchText; protected String searchText;
// special button with #-answer
// warning, only for human's GUI, not AI
protected boolean specialEnabled = false;
protected boolean specialCanBeEmpty = false; // enable if you want to select "nothing", but not cancel
protected String specialText = "";
protected String specialHint = "";
public ChoiceImpl() { public ChoiceImpl() {
this(false); this(false);
} }
@ -30,9 +37,10 @@ public class ChoiceImpl implements Choice, Serializable {
this.required = required; this.required = required;
} }
public ChoiceImpl(ChoiceImpl choice) { public ChoiceImpl(final ChoiceImpl choice) {
this.choice = choice.choice; this.choice = choice.choice;
this.chosen = choice.chosen; this.chosenNormal = choice.chosenNormal;
this.chosenSpecial = choice.chosenSpecial;
this.required = choice.required; this.required = choice.required;
this.message = choice.message; this.message = choice.message;
this.subMessage = choice.subMessage; this.subMessage = choice.subMessage;
@ -42,18 +50,28 @@ public class ChoiceImpl implements Choice, Serializable {
this.choiceKey = choice.choiceKey; this.choiceKey = choice.choiceKey;
this.keyChoices = choice.keyChoices; // list should never change for the same object so copy by reference TODO: check errors with that, it that ok? Color list is static this.keyChoices = choice.keyChoices; // list should never change for the same object so copy by reference TODO: check errors with that, it that ok? Color list is static
this.sortData = choice.sortData; this.sortData = choice.sortData;
this.specialEnabled = choice.specialEnabled;
this.specialCanBeEmpty = choice.specialCanBeEmpty;
this.specialText = choice.specialText;
this.specialHint = choice.specialHint;
} }
@Override @Override
public boolean isChosen() { public boolean isChosen() {
return chosen; return chosenNormal || chosenSpecial;
}
@Override
public boolean isChosenSpecial() {
return chosenSpecial;
} }
@Override @Override
public void clearChoice() { public void clearChoice() {
choice = null; this.choice = null;
choiceKey = null; this.choiceKey = null;
chosen = false; this.chosenNormal = false;
this.chosenSpecial = false;
} }
@Override @Override
@ -92,10 +110,17 @@ public class ChoiceImpl implements Choice, Serializable {
} }
@Override @Override
public void setChoice(String choice) { public void setChoice(String choice, boolean isSpecial) {
if (choices.contains(choice)) { if (choices.contains(choice)) {
this.choice = choice; this.choice = choice;
this.chosen = true; this.chosenNormal = true;
this.chosenSpecial = isSpecial;
}
if (isSpecial && this.specialCanBeEmpty && (choice == null || choice.isEmpty())) {
clearChoice();
this.chosenNormal = false;
this.chosenSpecial = true;
} }
} }
@ -134,12 +159,19 @@ public class ChoiceImpl implements Choice, Serializable {
} }
@Override @Override
public void setChoiceByKey(String choiceKey) { public void setChoiceByKey(String choiceKey, boolean isSpecial) {
String choiceToSet = keyChoices.get(choiceKey); String choiceToSet = keyChoices.get(choiceKey);
if (choiceToSet != null) { if (choiceToSet != null) {
this.choice = choiceToSet; this.choice = choiceToSet;
this.choiceKey = choiceKey; this.choiceKey = choiceKey;
this.chosen = true; this.chosenNormal = true;
this.chosenSpecial = isSpecial;
}
if (isSpecial && this.specialCanBeEmpty && (choiceKey == null || choiceKey.isEmpty())) {
clearChoice();
this.chosenNormal = false;
this.chosenSpecial = true;
} }
} }
@ -191,14 +223,14 @@ public class ChoiceImpl implements Choice, Serializable {
String[] vals = this.getKeyChoices().keySet().toArray(new String[0]); String[] vals = this.getKeyChoices().keySet().toArray(new String[0]);
if (vals.length > 0) { if (vals.length > 0) {
int choiceNum = RandomUtil.nextInt(vals.length); int choiceNum = RandomUtil.nextInt(vals.length);
this.setChoiceByKey(vals[choiceNum]); this.setChoiceByKey(vals[choiceNum], false);
} }
} else { } else {
// string mode // string mode
String[] vals = this.getChoices().toArray(new String[0]); String[] vals = this.getChoices().toArray(new String[0]);
if (vals.length > 0) { if (vals.length > 0) {
int choiceNum = RandomUtil.nextInt(vals.length); int choiceNum = RandomUtil.nextInt(vals.length);
this.setChoice(vals[choiceNum]); this.setChoice(vals[choiceNum], false);
} }
} }
} }
@ -211,18 +243,18 @@ public class ChoiceImpl implements Choice, Serializable {
for (String needChoice : answers) { for (String needChoice : answers) {
for (Map.Entry<String, String> currentChoice : this.getKeyChoices().entrySet()) { for (Map.Entry<String, String> currentChoice : this.getKeyChoices().entrySet()) {
if (currentChoice.getKey().equals(needChoice)) { if (currentChoice.getKey().equals(needChoice)) {
this.setChoiceByKey(needChoice); this.setChoiceByKey(needChoice, false);
answers.remove(needChoice); answers.remove(needChoice);
return true; return true;
} }
} }
} }
// no key answer found, try to macht by text starting with // no key answer found, try to match by text starting with
for (String needChoice : answers) { for (String needChoice : answers) {
for (Map.Entry<String, String> currentChoice : this.getKeyChoices().entrySet()) { for (Map.Entry<String, String> currentChoice : this.getKeyChoices().entrySet()) {
if (currentChoice.getValue().startsWith(needChoice)) { if (currentChoice.getValue().startsWith(needChoice)) {
this.setChoiceByKey(currentChoice.getKey()); this.setChoiceByKey(currentChoice.getKey(), false);
answers.remove(needChoice); answers.remove(needChoice);
return true; return true;
} }
@ -233,7 +265,7 @@ public class ChoiceImpl implements Choice, Serializable {
for (String needChoice : answers) { for (String needChoice : answers) {
for (String currentChoice : this.getChoices()) { for (String currentChoice : this.getChoices()) {
if (currentChoice.equals(needChoice)) { if (currentChoice.equals(needChoice)) {
this.setChoice(needChoice); this.setChoice(needChoice, false);
answers.remove(needChoice); answers.remove(needChoice);
return true; return true;
} }
@ -242,4 +274,32 @@ public class ChoiceImpl implements Choice, Serializable {
} }
return false; // can't find answer return false; // can't find answer
} }
@Override
public void setSpecial(boolean enabled, boolean canBeEmpty, String text, String hint) {
this.specialEnabled = enabled;
this.specialCanBeEmpty = canBeEmpty;
this.specialText = text;
this.specialHint = hint;
}
@Override
public boolean isSpecialEnabled() {
return this.specialEnabled;
}
@Override
public boolean isSpecialCanBeEmpty() {
return this.specialCanBeEmpty;
}
@Override
public String getSpecialText() {
return this.specialText;
}
@Override
public String getSpecialHint() {
return this.specialHint;
}
} }

View file

@ -23,6 +23,7 @@ public class UserData implements Serializable {
protected boolean passPriorityCast; protected boolean passPriorityCast;
protected boolean passPriorityActivation; protected boolean passPriorityActivation;
protected boolean autoOrderTrigger; protected boolean autoOrderTrigger;
protected boolean useSameSettingsForReplacementEffects;
protected boolean useFirstManaAbility = false; protected boolean useFirstManaAbility = false;
private String userIdStr; private String userIdStr;
protected Map<UUID, Set<UUID>> requestedHandPlayersList; // game -> players list protected Map<UUID, Set<UUID>> requestedHandPlayersList; // game -> players list
@ -36,10 +37,22 @@ public class UserData implements Serializable {
private int constructedRating; private int constructedRating;
private int limitedRating; private int limitedRating;
public UserData(UserGroup userGroup, int avatarId, boolean showAbilityPickerForced, public UserData(UserGroup userGroup,
boolean allowRequestShowHandCards, boolean confirmEmptyManaPool, UserSkipPrioritySteps userSkipPrioritySteps, int avatarId,
String flagName, boolean askMoveToGraveOrder, boolean manaPoolAutomatic, boolean manaPoolAutomaticRestricted, boolean showAbilityPickerForced,
boolean passPriorityCast, boolean passPriorityActivation, boolean autoOrderTrigger, boolean useFirstManaAbility, String userIdStr) { boolean allowRequestShowHandCards,
boolean confirmEmptyManaPool,
UserSkipPrioritySteps userSkipPrioritySteps,
String flagName,
boolean askMoveToGraveOrder,
boolean manaPoolAutomatic,
boolean manaPoolAutomaticRestricted,
boolean passPriorityCast,
boolean passPriorityActivation,
boolean autoOrderTrigger,
boolean useSameSettingsForReplacementEffects,
boolean useFirstManaAbility,
String userIdStr) {
this.groupId = userGroup.getGroupId(); this.groupId = userGroup.getGroupId();
this.avatarId = avatarId; this.avatarId = avatarId;
this.showAbilityPickerForced = showAbilityPickerForced; this.showAbilityPickerForced = showAbilityPickerForced;
@ -53,6 +66,7 @@ public class UserData implements Serializable {
this.passPriorityCast = passPriorityCast; this.passPriorityCast = passPriorityCast;
this.passPriorityActivation = passPriorityActivation; this.passPriorityActivation = passPriorityActivation;
this.autoOrderTrigger = autoOrderTrigger; this.autoOrderTrigger = autoOrderTrigger;
this.useSameSettingsForReplacementEffects = useSameSettingsForReplacementEffects;
this.useFirstManaAbility = useFirstManaAbility; this.useFirstManaAbility = useFirstManaAbility;
this.matchHistory = ""; this.matchHistory = "";
this.matchQuitRatio = 0; this.matchQuitRatio = 0;
@ -76,13 +90,31 @@ public class UserData implements Serializable {
this.passPriorityCast = userData.passPriorityCast; this.passPriorityCast = userData.passPriorityCast;
this.passPriorityActivation = userData.passPriorityActivation; this.passPriorityActivation = userData.passPriorityActivation;
this.autoOrderTrigger = userData.autoOrderTrigger; this.autoOrderTrigger = userData.autoOrderTrigger;
this.useSameSettingsForReplacementEffects = userData.useSameSettingsForReplacementEffects;
this.useFirstManaAbility = userData.useFirstManaAbility; this.useFirstManaAbility = userData.useFirstManaAbility;
this.userIdStr = userData.userIdStr; this.userIdStr = userData.userIdStr;
// todo: why we don't update user stats here? => can't be updated from client side // todo: why we don't update user stats here? => can't be updated from client side
} }
public static UserData getDefaultUserDataView() { public static UserData getDefaultUserDataView() {
return new UserData(UserGroup.DEFAULT, 0, false, false, true, new UserSkipPrioritySteps(), getDefaultFlagName(), false, true, true, false, false, false, false, ""); return new UserData(
UserGroup.DEFAULT,
0,
false,
false,
true,
new UserSkipPrioritySteps(),
getDefaultFlagName(),
false,
true,
true,
false,
false,
true,
true,
false,
""
);
} }
public void setGroupId(int groupId) { public void setGroupId(int groupId) {
@ -115,10 +147,7 @@ public class UserData implements Serializable {
public boolean isAllowRequestHandToPlayer(UUID gameId, UUID requesterPlayerId) { public boolean isAllowRequestHandToPlayer(UUID gameId, UUID requesterPlayerId) {
// once per game // once per game
boolean allowToPlayer = true; boolean allowToPlayer = !requestedHandPlayersList.containsKey(gameId) || !requestedHandPlayersList.get(gameId).contains(requesterPlayerId);
if (requestedHandPlayersList.containsKey(gameId) && requestedHandPlayersList.get(gameId).contains(requesterPlayerId)) {
allowToPlayer = false;
}
return isAllowRequestHandToAll() && allowToPlayer; return isAllowRequestHandToAll() && allowToPlayer;
} }
@ -206,6 +235,10 @@ public class UserData implements Serializable {
return autoOrderTrigger; return autoOrderTrigger;
} }
public boolean isUseSameSettingsForReplacementEffects() {
return useSameSettingsForReplacementEffects;
}
public void setAutoOrderTrigger(boolean autoOrderTrigger) { public void setAutoOrderTrigger(boolean autoOrderTrigger) {
this.autoOrderTrigger = autoOrderTrigger; this.autoOrderTrigger = autoOrderTrigger;
} }