mirror of
https://github.com/correl/mage.git
synced 2024-11-22 03:00:11 +00:00
GUI: Autochoose targets if choice can be made (#9206)
This commit is contained in:
parent
1e01efd49d
commit
96f6fbefc8
29 changed files with 492 additions and 213 deletions
|
@ -93,6 +93,10 @@ public final class Constants {
|
|||
public static final int BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_ONE_COLOR = 1;
|
||||
public static final int BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_MULTICOLOR = 2;
|
||||
|
||||
public static final int AUTO_TARGET_DISABLE = 0;
|
||||
public static final int AUTO_TARGET_NON_FEEL_BAD = 1;
|
||||
public static final int AUTO_TARGET_ALL = 2;
|
||||
|
||||
public interface IO {
|
||||
String DEFAULT_IMAGES_DIR = "plugins" + File.separator + "images" + File.separator;
|
||||
}
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="tabsPanel" min="-2" pref="554" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="tabsPanel" pref="554" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="saveButton" alignment="3" min="-2" pref="30" max="-2" attributes="0"/>
|
||||
<Component id="exitButton" alignment="3" min="-2" pref="30" max="-2" attributes="0"/>
|
||||
|
@ -98,7 +98,7 @@
|
|||
<Component id="main_gamelog" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="main_battlefield" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<EmptySpace pref="22" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -171,18 +171,19 @@
|
|||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
|
||||
<Component id="tooltipDelayLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="383" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
|
||||
<Component id="tooltipDelayLabel" max="32767" attributes="0"/>
|
||||
<Component id="tooltipDelay" alignment="1" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="showCardName" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="showFullImagePath" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="tooltipDelay" alignment="0" min="-2" pref="522" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -268,22 +269,25 @@
|
|||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="showPlayerNamesPermanently" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="nonLandPermanentsInOnePile" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="cbConfirmEmptyManaPool" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="cbAllowRequestToShowHandCards" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="cbShowStormCounter" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="cbAskMoveToGraveOrder" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="showAbilityPickerForced" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="displayLifeOnAvatar" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="lblTargetAutoChoose" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cbTargetAutoChooseLevel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="displayLifeOnAvatar" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="cbAskMoveToGraveOrder" alignment="0" min="-2" pref="596" max="-2" attributes="0"/>
|
||||
<Group type="103" alignment="0" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="showPlayerNamesPermanently" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="nonLandPermanentsInOnePile" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="cbConfirmEmptyManaPool" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="cbAllowRequestToShowHandCards" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="cbShowStormCounter" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="showAbilityPickerForced" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="315" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -305,6 +309,11 @@
|
|||
<Component id="cbConfirmEmptyManaPool" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cbAskMoveToGraveOrder" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="lblTargetAutoChoose" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cbTargetAutoChooseLevel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -328,7 +337,6 @@
|
|||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" value="Show player names on avatar permanently"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Instead showing the names only if you hover over the avatar with the mouse, the name is shown all the time."/>
|
||||
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="showPlayerNamesPermanentlyActionPerformed"/>
|
||||
|
@ -339,7 +347,6 @@
|
|||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" value="Display life on avatar image"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Display the player's life over its avatar image."/>
|
||||
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="displayLifeOnAvatarActionPerformed"/>
|
||||
|
@ -350,7 +357,6 @@
|
|||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" value="Show ability picker for 1 available option (spells without costs, mdf/split side, adventure)"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="This prevents you from accidently activating abilities what you don't want (example: if you haven't mana to cast main side, but clicks on mdf card and play land instead)"/>
|
||||
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="showAbilityPickerForcedActionPerformed"/>
|
||||
|
@ -361,7 +367,6 @@
|
|||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" value="Allow requests from players and spectators to show your hand cards"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="<html>This is the default setting used for your matches. If activated other players or spectators<br>
of your match can send a request so you can allow them to see your hand cards."/>
|
||||
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbAllowRequestToShowHandCardsActionPerformed"/>
|
||||
|
@ -372,7 +377,6 @@
|
|||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" value="Show the number of spell casts during the current turn"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="<html>Adds a little box left to the short keys line with the number<br>
of spells already cast during the current turn (storm counter)."/>
|
||||
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbShowStormCounterActionPerformed"/>
|
||||
|
@ -383,7 +387,6 @@
|
|||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" value="Confirm if you want to pass a phase/step but there is still mana in your mana pool"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="<html>If activated you get a confirm message if you pass priority while stack is empty<br>
 and you still have mana in your mana pool."/>
|
||||
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbConfirmEmptyManaPoolActionPerformed"/>
|
||||
|
@ -394,12 +397,41 @@
|
|||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" value="Ask player for setting order cards go to graveyard"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="<html>If activated and multiple cards go to the graveyard at the same time<br>
the player is asked to set the order of the cards."/>
|
||||
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbAskMoveToGraveOrderActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblTargetAutoChoose">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Auto-choose targets for player:"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="<html>
When there is only one possible outcome for targeting, the targets can be chosen for you.
<br>
<b>None:</b> All targeting must be done by the player.
<br>
<b>Most:</b> All targeting other than feel-bad effects (discarding, destroy, sacrifice, exile) that target you, a card you own, or a permanent/spell you control.
<br>
<b>All:</b> All targeting that can be automated will be."/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cbTargetAutoChooseLevel">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="3">
|
||||
<StringItem index="0" value="Off"/>
|
||||
<StringItem index="1" value="Most"/>
|
||||
<StringItem index="2" value="All"/>
|
||||
</StringArray>
|
||||
</Property>
|
||||
<Property name="selectedIndex" type="int" value="1"/>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection component="lblTargetAutoChoose" name="toolTipText" type="property"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AccessibilityProperties>
|
||||
<Property name="AccessibleContext.accessibleName" type="java.lang.String" value="Auto-choose targets for player combo box"/>
|
||||
</AccessibilityProperties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbTargetAutoChooseLevelActionPerformed"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="main_battlefield">
|
||||
|
@ -4082,7 +4114,7 @@
|
|||
<Component id="checkBoxEndTurnOthers" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="phases_stopSettings" pref="291" max="32767" attributes="0"/>
|
||||
<Component id="phases_stopSettings" pref="354" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
|
@ -4341,7 +4373,7 @@
|
|||
<Component id="panelCardImages" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="panelBackgroundImages" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="98" max="32767" attributes="0"/>
|
||||
<EmptySpace pref="142" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -6297,12 +6329,12 @@
|
|||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="526" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="623" max="32767" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" pref="21" max="-2" attributes="0"/>
|
||||
<Component id="themesCategory" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="430" max="32767" attributes="0"/>
|
||||
<EmptySpace pref="523" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
|
@ -6395,7 +6427,6 @@
|
|||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[100, 30]"/>
|
||||
</Property>
|
||||
<Property name="verticalAlignment" type="int" value="3"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="saveButtonActionPerformed"/>
|
||||
|
@ -6413,7 +6444,6 @@
|
|||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[100, 30]"/>
|
||||
</Property>
|
||||
<Property name="verticalAlignment" type="int" value="3"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="exitButtonActionPerformed"/>
|
||||
|
|
|
@ -31,6 +31,7 @@ import java.util.*;
|
|||
import java.util.prefs.BackingStoreException;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
import static mage.client.constants.Constants.AUTO_TARGET_NON_FEEL_BAD;
|
||||
import static mage.client.constants.Constants.BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_MULTICOLOR;
|
||||
import static mage.constants.Constants.*;
|
||||
|
||||
|
@ -236,6 +237,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
public static final String KEY_NEW_TOURNAMENT_MINIMUM_RATING = "newTournamentMinimumRating";
|
||||
public static final String KEY_NEW_TOURNAMENT_RATED = "newTournamentRated";
|
||||
|
||||
// Settings for auto-choosing targets
|
||||
public static final String KEY_AUTO_TARGET_LEVEL = "autoTargetLevel";
|
||||
|
||||
// pref setting for deck generator
|
||||
public static final String KEY_NEW_DECK_GENERATOR_DECK_SIZE = "newDeckGeneratorDeckSize";
|
||||
public static final String KEY_NEW_DECK_GENERATOR_SET = "newDeckGeneratorSet";
|
||||
|
@ -435,6 +439,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
cbShowStormCounter = new javax.swing.JCheckBox();
|
||||
cbConfirmEmptyManaPool = new javax.swing.JCheckBox();
|
||||
cbAskMoveToGraveOrder = new javax.swing.JCheckBox();
|
||||
lblTargetAutoChoose = new javax.swing.JLabel();
|
||||
cbTargetAutoChooseLevel = new javax.swing.JComboBox<>();
|
||||
main_battlefield = new javax.swing.JPanel();
|
||||
cbBattlefieldFeedbackColorizingMode = new javax.swing.JComboBox();
|
||||
lblBattlefieldFeedbackColorizingMode = new javax.swing.JLabel();
|
||||
|
@ -689,15 +695,16 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
main_cardLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
.add(main_cardLayout.createSequentialGroup()
|
||||
.add(6, 6, 6)
|
||||
.add(tooltipDelayLabel)
|
||||
.addContainerGap(383, Short.MAX_VALUE))
|
||||
.add(main_cardLayout.createSequentialGroup()
|
||||
.add(main_cardLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
.add(main_cardLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false)
|
||||
.add(tooltipDelayLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(tooltipDelay, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.add(main_cardLayout.createSequentialGroup()
|
||||
.add(showCardName)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
|
||||
.add(showFullImagePath)))
|
||||
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.add(showFullImagePath))
|
||||
.add(tooltipDelay, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 522, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
|
||||
.add(0, 0, Short.MAX_VALUE))
|
||||
);
|
||||
main_cardLayout.setVerticalGroup(
|
||||
main_cardLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
|
@ -725,7 +732,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
showPlayerNamesPermanently.setSelected(true);
|
||||
showPlayerNamesPermanently.setText("Show player names on avatar permanently");
|
||||
showPlayerNamesPermanently.setToolTipText("Instead showing the names only if you hover over the avatar with the mouse, the name is shown all the time.");
|
||||
showPlayerNamesPermanently.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||
showPlayerNamesPermanently.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
showPlayerNamesPermanentlyActionPerformed(evt);
|
||||
|
@ -735,7 +741,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
displayLifeOnAvatar.setSelected(true);
|
||||
displayLifeOnAvatar.setText("Display life on avatar image");
|
||||
displayLifeOnAvatar.setToolTipText("Display the player's life over its avatar image.");
|
||||
displayLifeOnAvatar.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||
displayLifeOnAvatar.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
displayLifeOnAvatarActionPerformed(evt);
|
||||
|
@ -745,7 +750,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
showAbilityPickerForced.setSelected(true);
|
||||
showAbilityPickerForced.setText("Show ability picker for 1 available option (spells without costs, mdf/split side, adventure)");
|
||||
showAbilityPickerForced.setToolTipText("This prevents you from accidently activating abilities what you don't want (example: if you haven't mana to cast main side, but clicks on mdf card and play land instead)");
|
||||
showAbilityPickerForced.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||
showAbilityPickerForced.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
showAbilityPickerForcedActionPerformed(evt);
|
||||
|
@ -755,7 +759,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
cbAllowRequestToShowHandCards.setSelected(true);
|
||||
cbAllowRequestToShowHandCards.setText("Allow requests from players and spectators to show your hand cards");
|
||||
cbAllowRequestToShowHandCards.setToolTipText("<html>This is the default setting used for your matches. If activated other players or spectators<br>\nof your match can send a request so you can allow them to see your hand cards.");
|
||||
cbAllowRequestToShowHandCards.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||
cbAllowRequestToShowHandCards.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cbAllowRequestToShowHandCardsActionPerformed(evt);
|
||||
|
@ -765,7 +768,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
cbShowStormCounter.setSelected(true);
|
||||
cbShowStormCounter.setText("Show the number of spell casts during the current turn");
|
||||
cbShowStormCounter.setToolTipText("<html>Adds a little box left to the short keys line with the number<br>\nof spells already cast during the current turn (storm counter).");
|
||||
cbShowStormCounter.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||
cbShowStormCounter.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cbShowStormCounterActionPerformed(evt);
|
||||
|
@ -775,7 +777,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
cbConfirmEmptyManaPool.setSelected(true);
|
||||
cbConfirmEmptyManaPool.setText("Confirm if you want to pass a phase/step but there is still mana in your mana pool");
|
||||
cbConfirmEmptyManaPool.setToolTipText("<html>If activated you get a confirm message if you pass priority while stack is empty<br>\n and you still have mana in your mana pool.");
|
||||
cbConfirmEmptyManaPool.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||
cbConfirmEmptyManaPool.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cbConfirmEmptyManaPoolActionPerformed(evt);
|
||||
|
@ -785,32 +786,46 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
cbAskMoveToGraveOrder.setSelected(true);
|
||||
cbAskMoveToGraveOrder.setText("Ask player for setting order cards go to graveyard");
|
||||
cbAskMoveToGraveOrder.setToolTipText("<html>If activated and multiple cards go to the graveyard at the same time<br>\nthe player is asked to set the order of the cards.");
|
||||
cbAskMoveToGraveOrder.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||
cbAskMoveToGraveOrder.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cbAskMoveToGraveOrderActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblTargetAutoChoose.setText("Auto-choose targets for player:");
|
||||
lblTargetAutoChoose.setToolTipText("<html>\nWhen there is only one possible outcome for targeting, the targets can be chosen for you.\n<br>\n<b>None:</b> All targeting must be done by the player.\n<br>\n<b>Most:</b> All targeting other than feel-bad effects (discarding, destroy, sacrifice, exile) that target you, a card you own, or a permanent/spell you control.\n<br>\n<b>All:</b> All targeting that can be automated will be.");
|
||||
|
||||
cbTargetAutoChooseLevel.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Off", "Most", "All" }));
|
||||
cbTargetAutoChooseLevel.setSelectedIndex(1);
|
||||
cbTargetAutoChooseLevel.setToolTipText(lblTargetAutoChoose.getToolTipText());
|
||||
cbTargetAutoChooseLevel.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cbTargetAutoChooseLevelActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.jdesktop.layout.GroupLayout main_gameLayout = new org.jdesktop.layout.GroupLayout(main_game);
|
||||
main_game.setLayout(main_gameLayout);
|
||||
main_gameLayout.setHorizontalGroup(
|
||||
main_gameLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
.add(main_gameLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.add(lblTargetAutoChoose)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(cbTargetAutoChooseLevel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.add(displayLifeOnAvatar, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(main_gameLayout.createSequentialGroup()
|
||||
.add(main_gameLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
.add(main_gameLayout.createSequentialGroup()
|
||||
.add(main_gameLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
|
||||
.add(showPlayerNamesPermanently, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(nonLandPermanentsInOnePile, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(cbConfirmEmptyManaPool, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(cbAllowRequestToShowHandCards, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(cbShowStormCounter, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(cbAskMoveToGraveOrder, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(showAbilityPickerForced, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.add(0, 0, Short.MAX_VALUE))
|
||||
.add(displayLifeOnAvatar, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
.add(cbAskMoveToGraveOrder, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 596, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.add(main_gameLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
|
||||
.add(showPlayerNamesPermanently, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(nonLandPermanentsInOnePile, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(cbConfirmEmptyManaPool, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(cbAllowRequestToShowHandCards, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(cbShowStormCounter, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(showAbilityPickerForced)))
|
||||
.add(0, 315, Short.MAX_VALUE))
|
||||
);
|
||||
main_gameLayout.setVerticalGroup(
|
||||
main_gameLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
|
@ -829,10 +844,15 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(cbConfirmEmptyManaPool)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(cbAskMoveToGraveOrder))
|
||||
.add(cbAskMoveToGraveOrder)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(main_gameLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
|
||||
.add(lblTargetAutoChoose)
|
||||
.add(cbTargetAutoChooseLevel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
|
||||
);
|
||||
|
||||
nonLandPermanentsInOnePile.getAccessibleContext().setAccessibleName("nonLandPermanentsInOnePile");
|
||||
cbTargetAutoChooseLevel.getAccessibleContext().setAccessibleName("Auto-choose targets for player combo box");
|
||||
|
||||
main_battlefield.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Battlefield"));
|
||||
|
||||
|
@ -889,7 +909,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
.add(main_gamelog, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(main_battlefield, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap(22, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
main_card.getAccessibleContext().setAccessibleName("Game panel");
|
||||
|
@ -1627,7 +1647,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
.add(jLabelEndOfTurn)
|
||||
.add(checkBoxEndTurnOthers))
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
|
||||
.add(phases_stopSettings, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 291, Short.MAX_VALUE)
|
||||
.add(phases_stopSettings, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 354, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
|
@ -1852,7 +1872,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
.add(panelCardImages, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(panelBackgroundImages, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(98, Short.MAX_VALUE))
|
||||
.addContainerGap(142, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
tabsPanel.addTab("Images", tabImages);
|
||||
|
@ -2819,12 +2839,12 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
);
|
||||
tabThemesLayout.setVerticalGroup(
|
||||
tabThemesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
.add(0, 526, Short.MAX_VALUE)
|
||||
.add(0, 623, Short.MAX_VALUE)
|
||||
.add(tabThemesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
.add(tabThemesLayout.createSequentialGroup()
|
||||
.add(21, 21, 21)
|
||||
.add(themesCategory, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(430, Short.MAX_VALUE)))
|
||||
.addContainerGap(523, Short.MAX_VALUE)))
|
||||
);
|
||||
|
||||
tabsPanel.addTab("Themes", tabThemes);
|
||||
|
@ -2833,7 +2853,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
saveButton.setMaximumSize(new java.awt.Dimension(100, 30));
|
||||
saveButton.setMinimumSize(new java.awt.Dimension(100, 30));
|
||||
saveButton.setPreferredSize(new java.awt.Dimension(100, 30));
|
||||
saveButton.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);
|
||||
saveButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
saveButtonActionPerformed(evt);
|
||||
|
@ -2844,7 +2863,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
exitButton.setMaximumSize(new java.awt.Dimension(100, 30));
|
||||
exitButton.setMinimumSize(new java.awt.Dimension(100, 30));
|
||||
exitButton.setPreferredSize(new java.awt.Dimension(100, 30));
|
||||
exitButton.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);
|
||||
exitButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
exitButtonActionPerformed(evt);
|
||||
|
@ -2869,8 +2887,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
|
||||
.add(layout.createSequentialGroup()
|
||||
.add(tabsPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 554, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(tabsPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 554, Short.MAX_VALUE)
|
||||
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
|
||||
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
|
||||
.add(saveButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 30, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
|
||||
.add(exitButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 30, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
|
||||
|
@ -2910,6 +2928,16 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
}
|
||||
}
|
||||
|
||||
String paramNameAutoTarget = KEY_AUTO_TARGET_LEVEL;
|
||||
int paramValueAutoTarger = dialog.cbTargetAutoChooseLevel.getSelectedIndex();
|
||||
int paramDefaultAutoTarget = AUTO_TARGET_NON_FEEL_BAD;
|
||||
if (getCachedValue(paramNameAutoTarget, paramDefault) != paramValueAutoTarger) {
|
||||
prefs.putInt(paramNameAutoTarget, paramValueAutoTarger);
|
||||
if (UPDATE_CACHE_POLICY) {
|
||||
updateCache(paramNameAutoTarget, Integer.toString(paramValueAutoTarger));
|
||||
}
|
||||
}
|
||||
|
||||
saveGUISize();
|
||||
|
||||
// Phases & Priority
|
||||
|
@ -3327,6 +3355,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_cbUseSameSettingsForReplacementEffectActionPerformed
|
||||
|
||||
private void cbTargetAutoChooseLevelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbTargetAutoChooseLevelActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_cbTargetAutoChooseLevelActionPerformed
|
||||
|
||||
private void showProxySettings() {
|
||||
Connection.ProxyType proxyType = (Connection.ProxyType) cbProxyType.getSelectedItem();
|
||||
switch (proxyType) {
|
||||
|
@ -3458,6 +3490,17 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
dialog.cbBattlefieldFeedbackColorizingMode.setSelectedIndex(BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_MULTICOLOR);
|
||||
}
|
||||
|
||||
String autoTargetParam;
|
||||
try {
|
||||
autoTargetParam = MageFrame.getPreferences().get(KEY_AUTO_TARGET_LEVEL, "1");
|
||||
int autoTargetMode = Integer.parseInt(autoTargetParam);
|
||||
dialog.cbTargetAutoChooseLevel.setSelectedIndex(autoTargetMode);
|
||||
} catch (Throwable e) {
|
||||
autoTargetParam = "";
|
||||
dialog.cbTargetAutoChooseLevel.setSelectedIndex(AUTO_TARGET_NON_FEEL_BAD);
|
||||
logger.error("Can't Parse and setup param " + KEY_AUTO_TARGET_LEVEL + " = " + autoTargetParam, e);
|
||||
}
|
||||
|
||||
load(prefs, dialog.checkBoxUpkeepYou, UPKEEP_YOU, "on", "on");
|
||||
load(prefs, dialog.checkBoxDrawYou, DRAW_YOU, "on", "on");
|
||||
load(prefs, dialog.checkBoxMainYou, MAIN_YOU, "on", "on");
|
||||
|
@ -4014,6 +4057,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PASS_PRIORITY_CAST, "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_TARGET_LEVEL, 1),
|
||||
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"),
|
||||
userStrId
|
||||
|
@ -4083,6 +4127,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
private javax.swing.JCheckBox cbStopOnAllEnd;
|
||||
private javax.swing.JCheckBox cbStopOnAllMain;
|
||||
private javax.swing.JCheckBox cbStopOnNewStackObjects;
|
||||
private javax.swing.JComboBox<String> cbTargetAutoChooseLevel;
|
||||
private javax.swing.JComboBox<ThemeType> cbTheme;
|
||||
private javax.swing.JCheckBox cbUseDefaultBackground;
|
||||
private javax.swing.JCheckBox cbUseDefaultBattleImage;
|
||||
|
@ -4192,6 +4237,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
|
|||
private javax.swing.JLabel lblProxyServer;
|
||||
private javax.swing.JLabel lblProxyType;
|
||||
private javax.swing.JLabel lblProxyUserName;
|
||||
private javax.swing.JLabel lblTargetAutoChoose;
|
||||
private javax.swing.JLabel lblURLServerList;
|
||||
private javax.swing.JLabel lebelSkip;
|
||||
private javax.swing.JPanel main_battlefield;
|
||||
|
|
|
@ -69,12 +69,12 @@
|
|||
cardArea.clearCardEventListeners();
|
||||
cardArea.loadCards(showCards, bigCard, gameId);
|
||||
if (options != null) {
|
||||
if (options.containsKey("chosen")) {
|
||||
java.util.List<UUID> chosenCards = (java.util.List<UUID>) options.get("chosen");
|
||||
if (options.containsKey("chosenTargets")) {
|
||||
java.util.List<UUID> chosenCards = (java.util.List<UUID>) options.get("chosenTargets");
|
||||
cardArea.selectCards(chosenCards);
|
||||
}
|
||||
if (options.containsKey("choosable")) {
|
||||
java.util.List<UUID> choosableCards = (java.util.List<UUID>) options.get("choosable");
|
||||
if (options.containsKey("possibleTargets")) {
|
||||
java.util.List<UUID> choosableCards = (java.util.List<UUID>) options.get("possibleTargets");
|
||||
cardArea.markCards(choosableCards);
|
||||
}
|
||||
if (options.containsKey("queryType") && options.get("queryType") == QueryType.PICK_ABILITY) {
|
||||
|
|
|
@ -1382,8 +1382,8 @@ public final class GamePanel extends javax.swing.JPanel {
|
|||
}
|
||||
|
||||
List<UUID> needChosen;
|
||||
if (lastGameData.options != null && lastGameData.options.containsKey("chosen")) {
|
||||
needChosen = (List<UUID>) lastGameData.options.get("chosen");
|
||||
if (lastGameData.options != null && lastGameData.options.containsKey("chosenTargets")) {
|
||||
needChosen = (List<UUID>) lastGameData.options.get("chosenTargets");
|
||||
} else {
|
||||
needChosen = new ArrayList<>();
|
||||
}
|
||||
|
|
|
@ -519,8 +519,8 @@ public class HumanPlayer extends PlayerImpl {
|
|||
}
|
||||
|
||||
while (canRespond()) {
|
||||
Set<UUID> targetIds = target.possibleTargets(abilityControllerId, source, game);
|
||||
if (targetIds == null || targetIds.isEmpty()) {
|
||||
Set<UUID> possibleTargetIds = target.possibleTargets(abilityControllerId, source, game);
|
||||
if (possibleTargetIds == null || possibleTargetIds.isEmpty()) {
|
||||
return target.getTargets().size() >= target.getNumberOfTargets();
|
||||
}
|
||||
|
||||
|
@ -529,17 +529,22 @@ public class HumanPlayer extends PlayerImpl {
|
|||
required = false;
|
||||
}
|
||||
|
||||
java.util.List<UUID> chosen = target.getTargets();
|
||||
options.put("chosen", (Serializable) chosen);
|
||||
UUID responseId = target.tryToAutoChoose(abilityControllerId, source, game);
|
||||
|
||||
updateGameStatePriority("choose(5)", game);
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)), targetIds, required, getOptions(target, options));
|
||||
// responseId is null if a choice couldn't be automatically made
|
||||
if (responseId == null) {
|
||||
List<UUID> chosenTargets = target.getTargets();
|
||||
options.put("chosenTargets", (Serializable) chosenTargets);
|
||||
|
||||
updateGameStatePriority("choose(5)", game);
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)), possibleTargetIds, required, getOptions(target, options));
|
||||
}
|
||||
waitForResponse(game);
|
||||
responseId = getFixedResponseUUID(game);
|
||||
}
|
||||
waitForResponse(game);
|
||||
|
||||
UUID responseId = getFixedResponseUUID(game);
|
||||
if (responseId != null) {
|
||||
// selected some target
|
||||
|
||||
|
@ -549,7 +554,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!targetIds.contains(responseId)) {
|
||||
if (!possibleTargetIds.contains(responseId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -617,25 +622,32 @@ public class HumanPlayer extends PlayerImpl {
|
|||
Map<String, Serializable> options = new HashMap<>();
|
||||
|
||||
while (canRespond()) {
|
||||
Set<UUID> possibleTargets = target.possibleTargets(abilityControllerId, source, game);
|
||||
Set<UUID> possibleTargetIds = target.possibleTargets(abilityControllerId, source, game);
|
||||
boolean required = target.isRequired(source != null ? source.getSourceId() : null, game);
|
||||
if (possibleTargets.isEmpty()
|
||||
if (possibleTargetIds.isEmpty()
|
||||
|| target.getTargets().size() >= target.getNumberOfTargets()) {
|
||||
required = false;
|
||||
}
|
||||
|
||||
java.util.List<UUID> chosen = target.getTargets();
|
||||
options.put("chosen", (Serializable) chosen);
|
||||
UUID responseId = target.tryToAutoChoose(abilityControllerId, source, game);
|
||||
|
||||
updateGameStatePriority("chooseTarget", game);
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)),
|
||||
possibleTargets, required, getOptions(target, options));
|
||||
// responseId is null if a choice couldn't be automatically made
|
||||
if (responseId == null) {
|
||||
|
||||
|
||||
List<UUID> chosenTargets = target.getTargets();
|
||||
options.put("chosenTargets", (Serializable) chosenTargets);
|
||||
|
||||
updateGameStatePriority("chooseTarget", game);
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
game.fireSelectTargetEvent(getId(), new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)),
|
||||
possibleTargetIds, required, getOptions(target, options));
|
||||
}
|
||||
waitForResponse(game);
|
||||
responseId = getFixedResponseUUID(game);
|
||||
}
|
||||
waitForResponse(game);
|
||||
|
||||
UUID responseId = getFixedResponseUUID(game);
|
||||
if (responseId != null) {
|
||||
// remove selected
|
||||
if (target.getTargets().contains(responseId)) {
|
||||
|
@ -643,7 +655,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (possibleTargets.contains(responseId)) {
|
||||
if (possibleTargetIds.contains(responseId)) {
|
||||
if (target.canTarget(abilityControllerId, responseId, source, game)) {
|
||||
target.addTarget(responseId, source, game);
|
||||
if (target.doneChoosing()) {
|
||||
|
@ -687,10 +699,12 @@ public class HumanPlayer extends PlayerImpl {
|
|||
return false;
|
||||
}
|
||||
|
||||
UUID abilityControllerId = playerId;
|
||||
UUID abilityControllerId;
|
||||
if (target.getTargetController() != null
|
||||
&& target.getAbilityController() != null) {
|
||||
abilityControllerId = target.getAbilityController();
|
||||
} else {
|
||||
abilityControllerId = playerId;
|
||||
}
|
||||
|
||||
while (canRespond()) {
|
||||
|
@ -701,32 +715,37 @@ public class HumanPlayer extends PlayerImpl {
|
|||
required = false;
|
||||
}
|
||||
|
||||
Map<String, Serializable> options = getOptions(target, null);
|
||||
java.util.List<UUID> chosen = target.getTargets();
|
||||
options.put("chosen", (Serializable) chosen);
|
||||
java.util.List<UUID> choosable = new ArrayList<>();
|
||||
List<UUID> chosenTargets = target.getTargets();
|
||||
List<UUID> possibleTargets = new ArrayList<>();
|
||||
for (UUID cardId : cards) {
|
||||
if (target.canTarget(abilityControllerId, cardId, null, cards, game)) {
|
||||
choosable.add(cardId);
|
||||
possibleTargets.add(cardId);
|
||||
}
|
||||
}
|
||||
if (!choosable.isEmpty()) {
|
||||
options.put("choosable", (Serializable) choosable);
|
||||
}
|
||||
|
||||
// if nothing to choose then show dialog (user must see non selectable items and click on any of them)
|
||||
if (required && choosable.isEmpty()) {
|
||||
if (required && possibleTargets.isEmpty()) {
|
||||
required = false;
|
||||
}
|
||||
|
||||
updateGameStatePriority("choose(4)", game);
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage()), cards, required, options);
|
||||
}
|
||||
waitForResponse(game);
|
||||
UUID responseId = target.tryToAutoChoose(abilityControllerId, null, game, possibleTargets);
|
||||
|
||||
if (responseId == null) {
|
||||
Map<String, Serializable> options = getOptions(target, null);
|
||||
options.put("chosenTargets", (Serializable) chosenTargets);
|
||||
if (!possibleTargets.isEmpty()) {
|
||||
options.put("possibleTargets", (Serializable) possibleTargets);
|
||||
}
|
||||
|
||||
updateGameStatePriority("choose(4)", game);
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage()), cards, required, options);
|
||||
}
|
||||
waitForResponse(game);
|
||||
|
||||
responseId = getFixedResponseUUID(game);
|
||||
}
|
||||
|
||||
UUID responseId = getFixedResponseUUID(game);
|
||||
if (responseId != null) {
|
||||
if (target.getTargets().contains(responseId)) { // if already included remove it with
|
||||
target.remove(responseId);
|
||||
|
@ -762,10 +781,12 @@ public class HumanPlayer extends PlayerImpl {
|
|||
return false;
|
||||
}
|
||||
|
||||
UUID abilityControllerId = playerId;
|
||||
UUID abilityControllerId;
|
||||
if (target.getTargetController() != null
|
||||
&& target.getAbilityController() != null) {
|
||||
abilityControllerId = target.getAbilityController();
|
||||
} else {
|
||||
abilityControllerId = playerId;
|
||||
}
|
||||
|
||||
while (canRespond()) {
|
||||
|
@ -776,32 +797,38 @@ public class HumanPlayer extends PlayerImpl {
|
|||
required = false;
|
||||
}
|
||||
|
||||
Map<String, Serializable> options = getOptions(target, null);
|
||||
java.util.List<UUID> chosen = target.getTargets();
|
||||
options.put("chosen", (Serializable) chosen);
|
||||
java.util.List<UUID> choosable = new ArrayList<>();
|
||||
List<UUID> possibleTargets = new ArrayList<>();
|
||||
for (UUID cardId : cards) {
|
||||
if (target.canTarget(abilityControllerId, cardId, source, cards, game)) {
|
||||
choosable.add(cardId);
|
||||
possibleTargets.add(cardId);
|
||||
}
|
||||
}
|
||||
if (!choosable.isEmpty()) {
|
||||
options.put("choosable", (Serializable) choosable);
|
||||
}
|
||||
|
||||
// if nothing to choose then show dialog (user must see non selectable items and click on any of them)
|
||||
if (required && choosable.isEmpty()) {
|
||||
if (required && possibleTargets.isEmpty()) {
|
||||
required = false;
|
||||
}
|
||||
|
||||
updateGameStatePriority("chooseTarget(5)", game);
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)), cards, required, options);
|
||||
}
|
||||
waitForResponse(game);
|
||||
UUID responseId = target.tryToAutoChoose(abilityControllerId, source, game, possibleTargets);
|
||||
|
||||
if (responseId == null) {
|
||||
List<UUID> chosenTargets = target.getTargets();
|
||||
Map<String, Serializable> options = getOptions(target, null);
|
||||
options.put("chosenTargets", (Serializable) chosenTargets);
|
||||
|
||||
if (!possibleTargets.isEmpty()) {
|
||||
options.put("possibleTargets", (Serializable) possibleTargets);
|
||||
}
|
||||
|
||||
updateGameStatePriority("chooseTarget(5)", game);
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)), cards, required, options);
|
||||
}
|
||||
waitForResponse(game);
|
||||
|
||||
responseId = getFixedResponseUUID(game);
|
||||
}
|
||||
|
||||
UUID responseId = getFixedResponseUUID(game);
|
||||
if (responseId != null) {
|
||||
if (target.getTargets().contains(responseId)) { // if already included remove it
|
||||
target.remove(responseId);
|
||||
|
@ -849,47 +876,53 @@ public class HumanPlayer extends PlayerImpl {
|
|||
|
||||
// 1. Select targets
|
||||
while (canRespond()) {
|
||||
Set<UUID> possibleTargets = target.possibleTargets(abilityControllerId, source, game);
|
||||
Set<UUID> possibleTargetIds = target.possibleTargets(abilityControllerId, source, game);
|
||||
boolean required = target.isRequired(source != null ? source.getSourceId() : null, game);
|
||||
if (possibleTargets.isEmpty()
|
||||
if (possibleTargetIds.isEmpty()
|
||||
|| target.getSize() >= target.getNumberOfTargets()) {
|
||||
required = false;
|
||||
}
|
||||
|
||||
// selected
|
||||
Map<String, Serializable> options = getOptions(target, null);
|
||||
java.util.List<UUID> chosen = target.getTargets();
|
||||
options.put("chosen", (Serializable) chosen);
|
||||
// selectable
|
||||
java.util.List<UUID> choosable = new ArrayList<>();
|
||||
for (UUID targetId : possibleTargets) {
|
||||
if (target.canTarget(abilityControllerId, targetId, source, game)) {
|
||||
choosable.add(targetId);
|
||||
UUID responseId = target.tryToAutoChoose(abilityControllerId, source, game);
|
||||
|
||||
// responseId is null if a choice couldn't be automatically made
|
||||
if (responseId == null) {
|
||||
List<UUID> chosenTargets = target.getTargets();
|
||||
List<UUID> possibleTargets = new ArrayList<>();
|
||||
for (UUID targetId : possibleTargetIds) {
|
||||
if (target.canTarget(abilityControllerId, targetId, source, game)) {
|
||||
possibleTargets.add(targetId);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!choosable.isEmpty()) {
|
||||
options.put("choosable", (Serializable) choosable);
|
||||
// if nothing to choose then show dialog (user must see non selectable items and click on any of them)
|
||||
if (required && possibleTargets.isEmpty()) {
|
||||
required = false;
|
||||
}
|
||||
|
||||
// selected
|
||||
Map<String, Serializable> options = getOptions(target, null);
|
||||
options.put("chosenTargets", (Serializable) chosenTargets);
|
||||
if (!possibleTargets.isEmpty()) {
|
||||
options.put("possibleTargets", (Serializable) possibleTargets);
|
||||
}
|
||||
|
||||
updateGameStatePriority("chooseTargetAmount", game);
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
// target amount uses for damage only, if you see another use case then message must be changed here and on getMultiAmount call
|
||||
|
||||
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)), possibleTargetIds, required, options);
|
||||
}
|
||||
waitForResponse(game);
|
||||
|
||||
responseId = getFixedResponseUUID(game);
|
||||
}
|
||||
|
||||
// if nothing to choose then show dialog (user must see non selectable items and click on any of them)
|
||||
if (required && choosable.isEmpty()) {
|
||||
required = false;
|
||||
}
|
||||
|
||||
updateGameStatePriority("chooseTargetAmount", game);
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
// target amount uses for damage only, if you see another use case then message must be changed here and on getMultiAmount call
|
||||
game.fireSelectTargetEvent(playerId, new MessageToClient(target.getMessage(), getRelatedObjectName(source, game)), possibleTargets, required, options);
|
||||
}
|
||||
waitForResponse(game);
|
||||
|
||||
UUID responseId = getFixedResponseUUID(game);
|
||||
if (responseId != null) {
|
||||
if (target.contains(responseId)) {
|
||||
// unselect
|
||||
target.remove(responseId);
|
||||
} else if (possibleTargets.contains(responseId) && target.canTarget(abilityControllerId, responseId, source, game)) {
|
||||
} else if (possibleTargetIds.contains(responseId) && target.canTarget(abilityControllerId, responseId, source, game)) {
|
||||
// select
|
||||
target.addTarget(responseId, source, game);
|
||||
}
|
||||
|
@ -1892,6 +1925,8 @@ public class HumanPlayer extends PlayerImpl {
|
|||
return;
|
||||
}
|
||||
|
||||
UUID responseId = null;
|
||||
|
||||
updateGameStatePriority("selectCombatGroup", game);
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
|
@ -1905,12 +1940,19 @@ public class HumanPlayer extends PlayerImpl {
|
|||
possibleTargets.add(attackerId);
|
||||
}
|
||||
}
|
||||
game.fireSelectTargetEvent(playerId, new MessageToClient("Select attacker to block", getRelatedObjectName(blockerId, game)),
|
||||
possibleTargets, false, getOptions(target, null));
|
||||
if (possibleTargets.size() == 1) {
|
||||
responseId = possibleTargets.stream().iterator().next();
|
||||
} else {
|
||||
game.fireSelectTargetEvent(playerId, new MessageToClient("Select attacker to block", getRelatedObjectName(blockerId, game)),
|
||||
possibleTargets, false, getOptions(target, null));
|
||||
}
|
||||
}
|
||||
waitForResponse(game);
|
||||
|
||||
UUID responseId = getFixedResponseUUID(game);
|
||||
if (responseId == null) {
|
||||
responseId = getFixedResponseUUID(game);
|
||||
}
|
||||
|
||||
if (response.getBoolean() != null) {
|
||||
// do nothing
|
||||
} else if (responseId != null) {
|
||||
|
|
|
@ -41,7 +41,7 @@ public class EvokeTest extends CardTestPlayerBase {
|
|||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Shriekmaw");
|
||||
setChoice(playerA, true);
|
||||
addTarget(playerA, "Silvercoat Lion");
|
||||
// addTarget(playerA, "Silvercoat Lion"); Autochosen, only target
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Exhume");
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
|
|
@ -59,11 +59,11 @@ public class FiendHunterTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiend Hunter");
|
||||
addTarget(playerA, "Primeval Titan");
|
||||
// addTarget(playerA, "Primeval Titan"); Autochosen, only option
|
||||
|
||||
// When Restoration Angel enters the battlefield, you may exile target non-Angel creature you control, then return that card to the battlefield under your control
|
||||
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Restoration Angel");
|
||||
addTarget(playerA, "Fiend Hunter");
|
||||
// addTarget(playerA, "Fiend Hunter"); Autochosen, only option
|
||||
|
||||
setStopAt(4, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
|
|
@ -32,7 +32,7 @@ public class MerfolkTricksterTest extends CardTestPlayerBase {
|
|||
|
||||
attack(1, playerA, "Flying Men");
|
||||
castSpell(1, PhaseStep.DECLARE_BLOCKERS, playerB, mTrickster);
|
||||
addTarget(playerB, "Flying Men");
|
||||
// addTarget(playerB, "Flying Men"); Autochosen, only option
|
||||
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
@ -60,7 +60,7 @@ public class MerfolkTricksterTest extends CardTestPlayerBase {
|
|||
|
||||
attack(1, playerA, "Flying Men");
|
||||
castSpell(1, PhaseStep.DECLARE_ATTACKERS, playerB, mTrickster);
|
||||
addTarget(playerB, "Flying Men");
|
||||
// addTarget(playerB, "Flying Men"); Autochosen, only target
|
||||
block(1, playerB, mTrickster, "Flying Men");
|
||||
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
|
|
|
@ -105,7 +105,7 @@ public class CleverImpersonatorTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerB, "Liliana, Defiant Necromancer", 1);
|
||||
|
||||
attack(1, playerA, "Alesha, Who Smiles at Death");
|
||||
addTarget(playerA, "Clever Impersonator");
|
||||
// addTarget(playerA, "Clever Impersonator"); (Autochosen, only target)
|
||||
setChoice(playerA, "Liliana, Defiant Necromancer");
|
||||
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "+2: Each player discards a card");
|
||||
|
|
|
@ -59,25 +59,28 @@ public class SharuumTheHegemonTest extends CardTestPlayerBase {
|
|||
setChoice(playerA, "Whenever {this} or another creature dies"); // blood first
|
||||
addTarget(playerA, playerB); // damage by blood
|
||||
setChoice(playerA, true); // return
|
||||
addTarget(playerA, "Sharuum the Hegemon"); // return real sharuum
|
||||
// addTarget(playerA, "Sharuum the Hegemon"); // return real sharuum (Autochosen, only target)
|
||||
|
||||
addTarget(playerA, "Sharuum the Hegemon[only copy]"); // which legend to keep
|
||||
setChoice(playerA, "Whenever {this} or another creature dies"); // blood first
|
||||
addTarget(playerA, playerB); // damage by blood
|
||||
setChoice(playerA, true); // return
|
||||
addTarget(playerA, "Sharuum the Hegemon"); // return real sharuum
|
||||
// addTarget(playerA, "Sharuum the Hegemon"); // return real sharuum (Autochosen, only target
|
||||
|
||||
addTarget(playerA, "Sharuum the Hegemon[only copy]"); // which legend to keep
|
||||
setChoice(playerA, "Whenever {this} or another creature dies"); // blood first
|
||||
addTarget(playerA, playerB); // damage by blood
|
||||
setChoice(playerA, true); // return
|
||||
addTarget(playerA, "Sharuum the Hegemon"); // return real sharuum
|
||||
// addTarget(playerA, "Sharuum the Hegemon"); // return real sharuum (Autochosen, only target)
|
||||
|
||||
addTarget(playerA, "Sharuum the Hegemon[only copy]"); // which legend to keep
|
||||
setChoice(playerA, "Whenever {this} or another creature dies"); // blood first
|
||||
addTarget(playerA, playerB); // damage by blood
|
||||
setChoice(playerA, false); // Don't use it anymore
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertLife(playerA, 24);
|
||||
assertLife(playerB, 16);
|
||||
|
|
|
@ -26,8 +26,8 @@ public class SpelltwineTest extends CardTestPlayerBase {
|
|||
addCard(Zone.GRAVEYARD, playerB, "Shock");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Spelltwine");
|
||||
addTarget(playerA, "Lightning Bolt");
|
||||
addTarget(playerA, "Shock");
|
||||
// addTarget(playerA, "Lightning Bolt"); Autochosen, only target
|
||||
// addTarget(playerA, "Shock"); Autochosen, only target
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
|
|
@ -80,7 +80,7 @@ public class SweepTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerA, "Plow Through Reito");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Plow Through Reito");
|
||||
addTarget(playerA, "Raging Goblin"); // target to boost
|
||||
// addTarget(playerA, "Raging Goblin"); // Autochosen (target to boost)
|
||||
addTarget(playerA, TestPlayer.TARGET_SKIP); // targets to sweep (zero)
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
|
|
|
@ -24,7 +24,7 @@ public class OathOfLiegesTest extends CardTestPlayerBase {
|
|||
|
||||
// turn 1 - A
|
||||
// oath A triggers for A and activates
|
||||
addTarget(playerA, playerB); // who control more lands
|
||||
// addTarget(playerA, playerB); // who control more lands (Autochosen, only target)
|
||||
setChoice(playerA, true); // search library
|
||||
addTarget(playerA, "Plains"); // card from library
|
||||
|
||||
|
@ -56,7 +56,7 @@ public class OathOfLiegesTest extends CardTestPlayerBase {
|
|||
|
||||
// turn 2 - B
|
||||
// oath A triggers for B and activates
|
||||
addTarget(playerB, playerA); // who control more lands
|
||||
// addTarget(playerB, playerA); // who control more lands (Autochosen, only target)
|
||||
setChoice(playerB, true); // search library
|
||||
addTarget(playerB, "Plains"); // card from library
|
||||
|
||||
|
@ -80,7 +80,7 @@ public class OathOfLiegesTest extends CardTestPlayerBase {
|
|||
|
||||
// turn 1 - A
|
||||
// oath B triggers for A and activates
|
||||
addTarget(playerA, playerB); // who control more lands
|
||||
// addTarget(playerA, playerB); // who control more lands (Autochosen, only target)
|
||||
setChoice(playerA, true); // search library
|
||||
addTarget(playerA, "Plains"); // card from library
|
||||
|
||||
|
@ -105,11 +105,11 @@ public class OathOfLiegesTest extends CardTestPlayerBase {
|
|||
// oath A triggers for A and activates
|
||||
// oath B triggers for A and activates
|
||||
// 1
|
||||
addTarget(playerA, playerB); // who control more lands
|
||||
// addTarget(playerA, playerB); // who control more lands (Autochosen, only target)
|
||||
setChoice(playerA, true); // search library
|
||||
addTarget(playerA, "Plains"); // card from library
|
||||
// 2
|
||||
addTarget(playerA, playerB); // who control more lands
|
||||
// addTarget(playerA, playerB); // who control more lands (Autochosen, only target)
|
||||
setChoice(playerA, true); // search library
|
||||
addTarget(playerA, "Plains"); // card from library
|
||||
|
||||
|
@ -212,11 +212,11 @@ public class OathOfLiegesTest extends CardTestPlayerBase {
|
|||
// oath A triggers for A and activates
|
||||
// copy oath B triggers for A and activates
|
||||
// 1
|
||||
addTarget(playerA, playerB); // who control more lands
|
||||
// addTarget(playerA, playerB); // who control more lands (Autochosen, only target)
|
||||
setChoice(playerA, true); // search library
|
||||
addTarget(playerA, "Plains"); // card from library
|
||||
// 2
|
||||
addTarget(playerA, playerB); // who control more lands
|
||||
// addTarget(playerA, playerB); // who control more lands (Autochosen, only target)
|
||||
setChoice(playerA, true); // search library
|
||||
addTarget(playerA, "Plains"); // card from library
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ public class StarfieldOfNyxTest extends CardTestPlayerBase {
|
|||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Starfield of Nyx");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cloudform");
|
||||
|
||||
addTarget(playerA, "Cloudform");
|
||||
// addTarget(playerA, "Cloudform"); Autochosen, only target
|
||||
|
||||
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
|
|
@ -55,7 +55,9 @@ public class LilianaTest extends CardTestPlayerBase {
|
|||
addTarget(playerA, yOx); // tap the ox
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
setStrictChooseMode(true);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertPermanentCount(playerA, bMummy, 1);
|
||||
assertPermanentCount(playerA, liliannaDM, 1);
|
||||
|
|
|
@ -27,7 +27,7 @@ public class EonFrolickerTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 5);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Eon Frolicker");
|
||||
addTarget(playerA, playerB);
|
||||
// addTarget(playerA, playerB); Autochosen, only target
|
||||
|
||||
// AI can targets only Eon Frolicker (cause A protected from B)
|
||||
checkPlayableAbility("after", 1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Cast Chandra's Fury", true);
|
||||
|
|
|
@ -71,20 +71,13 @@ public class SimpleDominariaCards extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerB, "Avatar of Woe");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{T}");
|
||||
addTarget(playerB, "Knight of Grace");
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
|
||||
try {
|
||||
execute();
|
||||
Assert.fail("must throw exception on execute");
|
||||
} catch (Throwable e) {
|
||||
if (!e.getMessage().contains("setup good targets")) {
|
||||
Assert.fail("must throw error about bad targets, but got:\n" + e.getMessage());
|
||||
}
|
||||
}
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertTapped("Avatar of Woe", false);
|
||||
assertGraveyardCount(playerA, "Knight of Grace", 0);
|
||||
assertGraveyardCount(playerB, "Avatar of Woe", 1); // Autokills itself since its only valid target
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -23,7 +23,7 @@ public class BrainMaggotTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerB, "Bloodflow Connoisseur", 1);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Brain Maggot");
|
||||
addTarget(playerA, playerB);
|
||||
// addTarget(playerA, playerB); Autochosen, only target
|
||||
setChoice(playerA, "Bloodflow Connoisseur");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
|
@ -46,7 +46,7 @@ public class BrainMaggotTest extends CardTestPlayerBase {
|
|||
|
||||
// exile
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Brain Maggot");
|
||||
addTarget(playerA, playerB);
|
||||
// addTarget(playerA, playerB); Autochosen, only target
|
||||
setChoice(playerA, "Bloodflow Connoisseur");
|
||||
// showExile("exile", 1, PhaseStep.BEGIN_COMBAT, playerB);
|
||||
checkExileCount("blood must be in exile", 1, PhaseStep.BEGIN_COMBAT, playerB, "Bloodflow Connoisseur", 1);
|
||||
|
@ -77,7 +77,7 @@ public class BrainMaggotTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mesmeric Fiend");
|
||||
addTarget(playerA, playerB);
|
||||
// addTarget(playerA, playerB); Autochosen, only target
|
||||
setChoice(playerA, "Bloodflow Connoisseur");
|
||||
//
|
||||
castSpell(1, PhaseStep.BEGIN_COMBAT, playerB, "Lightning Bolt", "Mesmeric Fiend");
|
||||
|
|
|
@ -31,7 +31,7 @@ public class TidehollowScullerTest extends CardTestPlayerBase {
|
|||
// cast and exile from hand
|
||||
checkHandCardCount("B hand must have blood", 1, PhaseStep.UPKEEP, playerB, "Bloodflow Connoisseur", 1);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tidehollow Sculler");
|
||||
addTarget(playerA, playerB); // choose opponent
|
||||
// addTarget(playerA, playerB); // choose opponent (Autochosen, only target)
|
||||
setChoice(playerA, "Bloodflow Connoisseur"); // card to exile
|
||||
checkHandCardCount("B hand must lost blood", 1, PhaseStep.BEGIN_COMBAT, playerB, "Bloodflow Connoisseur", 0);
|
||||
|
||||
|
@ -68,13 +68,13 @@ public class TidehollowScullerTest extends CardTestPlayerBase {
|
|||
// cast 1 and exile from hand
|
||||
checkHandCardCount("B hand must have blood", 1, PhaseStep.UPKEEP, playerB, "Bloodflow Connoisseur", 1);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tidehollow Sculler");
|
||||
addTarget(playerA, playerB); // choose opponent
|
||||
// addTarget(playerA, playerB); // choose opponent (Autochosen, only target)
|
||||
setChoice(playerA, "Bloodflow Connoisseur"); // card to exile
|
||||
checkHandCardCount("B hand must lost blood", 1, PhaseStep.BEGIN_COMBAT, playerB, "Bloodflow Connoisseur", 0);
|
||||
// cast 2 and exile from hand
|
||||
checkHandCardCount("B hand must have lion", 1, PhaseStep.END_COMBAT, playerB, "Silvercoat Lion", 1);
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Tidehollow Sculler");
|
||||
addTarget(playerA, playerB); // choose opponent
|
||||
// addTarget(playerA, playerB); // choose opponent (Autochosen, only target)
|
||||
setChoice(playerA, "Silvercoat Lion"); // card to exile
|
||||
checkHandCardCount("B hand must lost lion", 1, PhaseStep.END_TURN, playerB, "Silvercoat Lion", 0);
|
||||
|
||||
|
|
|
@ -75,8 +75,8 @@ public class BlatantThieveryTest extends CardTestMultiPlayerBase {
|
|||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blatant Thievery");
|
||||
addTarget(playerA, "Silvercoat Lion");
|
||||
addTarget(playerA, "Walking Corpse");
|
||||
addTarget(playerA, "Pillarfield Ox");
|
||||
// addTarget(playerA, "Walking Corpse"); Autochosen, only target
|
||||
// addTarget(playerA, "Pillarfield Ox"); Autochosen, only target
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Act of Aggression", "Pillarfield Ox", "Blatant Thievery");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
|
|
|
@ -4346,6 +4346,16 @@ public class TestPlayer implements Player {
|
|||
this.strictChooseMode = enable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getStrictChooseMode() {
|
||||
return this.strictChooseMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserData getControllingPlayersUserData(Game game) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPhyrexianToColors(FilterMana colors) {
|
||||
computerPlayer.addPhyrexianToColors(colors);
|
||||
|
|
|
@ -1430,6 +1430,11 @@ public class PlayerStub implements Player {
|
|||
return (new FilterMana());
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserData getControllingPlayersUserData(Game game) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellAbility chooseAbilityForCast(Card card, Game game, boolean noMana) {
|
||||
return card.getSpellAbility();
|
||||
|
|
|
@ -788,7 +788,7 @@ public abstract class AbilityImpl implements Ability {
|
|||
@Override
|
||||
public String getRule(boolean all) {
|
||||
StringBuilder sbRule = threadLocalBuilder.get();
|
||||
if (all || this.abilityType != AbilityType.SPELL) {
|
||||
if (all || this.abilityType != AbilityType.SPELL) { // TODO: Why the override for non-spells?
|
||||
if (!manaCosts.isEmpty()) {
|
||||
sbRule.append(manaCosts.getText());
|
||||
}
|
||||
|
|
|
@ -1054,4 +1054,16 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
* @return
|
||||
*/
|
||||
FilterMana getPhyrexianColors();
|
||||
|
||||
/**
|
||||
* Function to query if the player has strictChooseMode enabled. Only the test player can have it.
|
||||
* Function is added here so that the test suite project does not have to be imported into the client/server project.
|
||||
*
|
||||
* @return whether the player has strictChooseMode enabled
|
||||
*/
|
||||
public default boolean getStrictChooseMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public UserData getControllingPlayersUserData(Game game);
|
||||
}
|
||||
|
|
|
@ -4268,6 +4268,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
return this.userData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserData getControllingPlayersUserData(Game game) {
|
||||
if (!isGameUnderControl()) {
|
||||
Player player = game.getPlayer(getTurnControlledBy());
|
||||
|
|
|
@ -23,6 +23,7 @@ public class UserData implements Serializable {
|
|||
protected boolean passPriorityCast;
|
||||
protected boolean passPriorityActivation;
|
||||
protected boolean autoOrderTrigger;
|
||||
protected int autoTargetLevel;
|
||||
protected boolean useSameSettingsForReplacementEffects;
|
||||
protected boolean useFirstManaAbility = false;
|
||||
private String userIdStr;
|
||||
|
@ -50,6 +51,7 @@ public class UserData implements Serializable {
|
|||
boolean passPriorityCast,
|
||||
boolean passPriorityActivation,
|
||||
boolean autoOrderTrigger,
|
||||
int autoTargetLevel,
|
||||
boolean useSameSettingsForReplacementEffects,
|
||||
boolean useFirstManaAbility,
|
||||
String userIdStr) {
|
||||
|
@ -66,6 +68,7 @@ public class UserData implements Serializable {
|
|||
this.passPriorityCast = passPriorityCast;
|
||||
this.passPriorityActivation = passPriorityActivation;
|
||||
this.autoOrderTrigger = autoOrderTrigger;
|
||||
this.autoTargetLevel = autoTargetLevel;
|
||||
this.useSameSettingsForReplacementEffects = useSameSettingsForReplacementEffects;
|
||||
this.useFirstManaAbility = useFirstManaAbility;
|
||||
this.matchHistory = "";
|
||||
|
@ -90,6 +93,7 @@ public class UserData implements Serializable {
|
|||
this.passPriorityCast = userData.passPriorityCast;
|
||||
this.passPriorityActivation = userData.passPriorityActivation;
|
||||
this.autoOrderTrigger = userData.autoOrderTrigger;
|
||||
this.autoTargetLevel = userData.autoTargetLevel;
|
||||
this.useSameSettingsForReplacementEffects = userData.useSameSettingsForReplacementEffects;
|
||||
this.useFirstManaAbility = userData.useFirstManaAbility;
|
||||
this.userIdStr = userData.userIdStr;
|
||||
|
@ -111,6 +115,7 @@ public class UserData implements Serializable {
|
|||
false,
|
||||
false,
|
||||
true,
|
||||
1,
|
||||
true,
|
||||
false,
|
||||
""
|
||||
|
@ -235,14 +240,22 @@ public class UserData implements Serializable {
|
|||
return autoOrderTrigger;
|
||||
}
|
||||
|
||||
public boolean isUseSameSettingsForReplacementEffects() {
|
||||
return useSameSettingsForReplacementEffects;
|
||||
}
|
||||
|
||||
public void setAutoOrderTrigger(boolean autoOrderTrigger) {
|
||||
this.autoOrderTrigger = autoOrderTrigger;
|
||||
}
|
||||
|
||||
public int getAutoTargetLevel() {
|
||||
return autoTargetLevel;
|
||||
}
|
||||
|
||||
public void setAutoTargetLevel(int autoTargetLevel) {
|
||||
this.autoTargetLevel = autoTargetLevel;
|
||||
}
|
||||
|
||||
public boolean isUseSameSettingsForReplacementEffects() {
|
||||
return useSameSettingsForReplacementEffects;
|
||||
}
|
||||
|
||||
public boolean isUseFirstManaAbility() {
|
||||
return useFirstManaAbility;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package mage.target;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.cards.Cards;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.Filter;
|
||||
|
@ -8,6 +9,7 @@ import mage.game.Game;
|
|||
import mage.players.Player;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
@ -159,4 +161,35 @@ public interface Target extends Serializable {
|
|||
int getSize();
|
||||
|
||||
boolean contains(UUID targetId);
|
||||
|
||||
/**
|
||||
* This function tries to auto-choose the next target.
|
||||
* <p>
|
||||
* It will NOT add it to the list of targets, it will ony choose the next target
|
||||
* <p>
|
||||
* Use this version when the targets is selected from targets.getTargets.
|
||||
* <p>
|
||||
* It will auto-choosen if all of the following criteria are met:
|
||||
* - The minimum and maximum number of targets is the same (i.e. effect does not have "up to" in its name)
|
||||
* - The number of valid targets is equal to the number of targets still left to be specified
|
||||
*
|
||||
*
|
||||
* @param abilityControllerId
|
||||
* @param source
|
||||
* @param game
|
||||
* @return The UUID of the chosen option, or null if one could not be chosen
|
||||
*/
|
||||
UUID tryToAutoChoose(UUID abilityControllerId, Ability source, Game game);
|
||||
|
||||
/**
|
||||
* Use this version when the target is chosen from a specified collection.
|
||||
* E.g. {@link Player#chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game)}
|
||||
*
|
||||
* @param abilityControllerId
|
||||
* @param source
|
||||
* @param game
|
||||
* @param possibleTargets
|
||||
* @return
|
||||
*/
|
||||
UUID tryToAutoChoose(UUID abilityControllerId, Ability source, Game game, Collection<UUID> possibleTargets);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import mage.game.Game;
|
|||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.TargetEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
import mage.util.RandomUtil;
|
||||
|
@ -317,8 +318,14 @@ public abstract class TargetImpl implements Target {
|
|||
possibleTargets.remove(index);
|
||||
}
|
||||
}
|
||||
} else if (!targetController.chooseTarget(outcome, this, source, game)) {
|
||||
return chosen;
|
||||
} else {
|
||||
// Try to autochoosen
|
||||
UUID autoChosenId = tryToAutoChoose(playerId, source, game);
|
||||
if (autoChosenId != null) {
|
||||
addTarget(autoChosenId, source, game);
|
||||
} else if (!targetController.chooseTarget(outcome, this, source, game)) { // If couldn't autochoose ask player
|
||||
return chosen;
|
||||
}
|
||||
}
|
||||
chosen = targets.size() >= getNumberOfTargets();
|
||||
} while (!isChosen() && !doneChoosing());
|
||||
|
@ -595,4 +602,82 @@ public abstract class TargetImpl implements Target {
|
|||
public boolean contains(UUID targetId) {
|
||||
return targets.containsKey(targetId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID tryToAutoChoose(UUID abilityControllerId, Ability source, Game game) {
|
||||
Set<UUID> possibleTargets = possibleTargets(abilityControllerId, source, game);
|
||||
possibleTargets.removeAll(this.targets.keySet());
|
||||
return tryToAutoChoose(abilityControllerId, source, game, possibleTargets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID tryToAutoChoose(UUID abilityControllerId, Ability source, Game game, Collection<UUID> possibleTargets) {
|
||||
Player player = game.getPlayer(abilityControllerId);
|
||||
if (player == null) {
|
||||
return null;
|
||||
}
|
||||
int playerAutoTargetLevel;
|
||||
if (player.isHuman() && player.getControllingPlayersUserData(game) != null) { // Ensure that non-strictChooseMode ComputerPlayer will still use this ability
|
||||
playerAutoTargetLevel = player.getControllingPlayersUserData(game).getAutoTargetLevel();
|
||||
} else {
|
||||
playerAutoTargetLevel = 2;
|
||||
}
|
||||
boolean strictModeEnabled = player.getStrictChooseMode();
|
||||
boolean canAutoChoose = this.getMinNumberOfTargets() == this.getMaxNumberOfTargets() && // Targets must be picked
|
||||
possibleTargets.size() == this.getNumberOfTargets() - this.getSize() && // Available targets are equal to the number that must be picked
|
||||
!strictModeEnabled && // Test AI is not set to strictChooseMode(true)
|
||||
playerAutoTargetLevel > 0; // Human player has enabled auto-choose in settings
|
||||
|
||||
if (canAutoChoose) {
|
||||
boolean autoTargetAll = playerAutoTargetLevel == 2;
|
||||
for (UUID possibleChooseId : possibleTargets) {
|
||||
// Don't pick a target that's already been chosen, this will lead to an infinite loop of
|
||||
// choosen and unchoosing the same target.
|
||||
if (this.targets.containsKey(possibleChooseId)) {
|
||||
continue;
|
||||
}
|
||||
if (autoTargetAll) { // No need for further checks since all targeting is to be automated
|
||||
return possibleChooseId;
|
||||
}
|
||||
|
||||
// Check if you control the target (or own the card)
|
||||
boolean targetingOwnThing;
|
||||
if (possibleChooseId == abilityControllerId) {
|
||||
targetingOwnThing = true;
|
||||
} else {
|
||||
Permanent targetPermanent = game.getPermanent(possibleChooseId);
|
||||
Card targetCard = game.getCard(possibleChooseId);
|
||||
Spell targetSpell = game.getSpell(possibleChooseId);
|
||||
if (targetPermanent != null) {
|
||||
targetingOwnThing = abilityControllerId == targetPermanent.getControllerId();
|
||||
} else if (targetCard != null) {
|
||||
targetingOwnThing = abilityControllerId == targetCard.getOwnerId();
|
||||
} else if (targetSpell != null) {
|
||||
targetingOwnThing = abilityControllerId == targetSpell.getControllerId();
|
||||
} else {
|
||||
// No point further checking
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If you control (or own the card) the target, check if it's one of the feel-bad effects.
|
||||
if (targetingOwnThing) {
|
||||
String abilityText = source.getRule(true).toLowerCase();
|
||||
|
||||
if (abilityText.contains("discard")
|
||||
|| abilityText.contains("sacrifice")
|
||||
|| abilityText.contains("destroy")
|
||||
|| abilityText.contains("exile")) {
|
||||
continue;
|
||||
}
|
||||
// Otherwise return the target with the return statement below.
|
||||
}
|
||||
|
||||
// If we get here then it means that the target UUID passes the checks.
|
||||
return possibleChooseId;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue