Hold priority on Ctrl+click

In most cases, it is not useful to hold priority after doing something,
since the spell or ability added to the stack can just be performed
beforehand.

Hence, automatically passing priority is the only comfortable setting.

However, in some cases it is useful (chiefly for Infernal Tutor +
Lion's Eye Diamond and similar interaction), and currently players
have to open Preferences, change the option and then change it back
whenever they need to hold priority, which is very annoying.

This change allows to temporarily hold priority by simply holding
Control while performing an action, which solves the issue in a
manner similar to other clients.

A "Hold" indicator next to the spells cast indicator is displayed so
that the user knows his Control key holding was registered.

The code works by adding a new HOLD_PRIORITY player action that causes
the automatic priority pass options to be ignored until the player is
given priority again.

The client sends the message whenever it's not already holding priority
and Ctrl+click/space/enter happens anywhere.

This is somewhat "loose" as it means that Ctrl+click on the background
also holds priority, but this might actually be desirable and it greatly
simplifies the code, since only a global AWT event listener is required,
and there is no need to change every place in the code that could add
something to the stack.

It is also possible to hold priority and stop holding priority using
the context menu.
This commit is contained in:
draxdyn 2016-06-24 17:46:46 +02:00
parent 4ed2e40841
commit a7409f3d08
8 changed files with 147 additions and 13 deletions

View file

@ -27,6 +27,7 @@
*/
package mage.client.game;
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
@ -391,6 +392,7 @@ public final class GamePanel extends javax.swing.JPanel {
stackObjects.setCardDimension(GUISizeHelper.handCardDimension);
txtSpellsCast.setFont(new Font(GUISizeHelper.gameDialogAreaFont.getFontName(), Font.BOLD, GUISizeHelper.gameDialogAreaFont.getSize()));
txtHoldPriority.setFont(new Font(GUISizeHelper.gameDialogAreaFont.getFontName(), Font.BOLD, GUISizeHelper.gameDialogAreaFont.getSize()));
GUISizeHelper.changePopupMenuFont(popupMenuTriggerOrder);
int newStackWidth = pnlHelperHandButtonsStackArea.getWidth() * GUISizeHelper.stackWidth / 100;
@ -589,7 +591,8 @@ public final class GamePanel extends javax.swing.JPanel {
setMenuStates(
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true")
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"),
holdingPriority
);
updateGame(game);
@ -957,9 +960,9 @@ public final class GamePanel extends javax.swing.JPanel {
* @param manaPoolAutomaticRestricted
* @param useFirstManaAbility
*/
public void setMenuStates(boolean manaPoolAutomatic, boolean manaPoolAutomaticRestricted, boolean useFirstManaAbility) {
public void setMenuStates(boolean manaPoolAutomatic, boolean manaPoolAutomaticRestricted, boolean useFirstManaAbility, boolean holdPriority) {
for (PlayAreaPanel playAreaPanel : players.values()) {
playAreaPanel.setMenuStates(manaPoolAutomatic, manaPoolAutomaticRestricted, useFirstManaAbility);
playAreaPanel.setMenuStates(manaPoolAutomatic, manaPoolAutomaticRestricted, useFirstManaAbility, holdPriority);
}
}
@ -1201,6 +1204,14 @@ public final class GamePanel extends javax.swing.JPanel {
}
public void select(String message, GameView gameView, int messageId, Map<String, Serializable> options) {
holdingPriority = false;
txtHoldPriority.setVisible(false);
setMenuStates(
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"),
false);
updateGame(gameView, options);
boolean controllingPlayer = false;
for (PlayerView playerView : gameView.getPlayers()) {
@ -1340,6 +1351,14 @@ public final class GamePanel extends javax.swing.JPanel {
txtSpellsCast.setOpaque(true);
txtSpellsCast.setToolTipText("spells cast during the current turn");
txtHoldPriority = new javax.swing.JLabel();
txtHoldPriority.setText("Hold");
txtHoldPriority.setBorder(BorderFactory.createCompoundBorder(border, paddingBorder));
txtHoldPriority.setBackground(Color.LIGHT_GRAY);
txtHoldPriority.setOpaque(true);
txtHoldPriority.setToolTipText("Holding priority after the next spell cast or ability activation");
txtHoldPriority.setVisible(false);
btnCancelSkip = new javax.swing.JButton(); // F3
btnSkipToNextTurn = new javax.swing.JButton(); // F4
btnSkipToEndTurn = new javax.swing.JButton(); // F5
@ -1670,7 +1689,8 @@ public final class GamePanel extends javax.swing.JPanel {
setMenuStates(
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"));
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"),
holdingPriority);
}
});
@ -1713,7 +1733,8 @@ public final class GamePanel extends javax.swing.JPanel {
setMenuStates(
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"));
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"),
holdingPriority);
}
});
@ -1829,6 +1850,7 @@ public final class GamePanel extends javax.swing.JPanel {
.addComponent(btnSkipToEndStepBeforeYourTurn)
)
.addGroup(gl_pnlShortCuts.createSequentialGroup()
.addComponent(txtHoldPriority)
.addComponent(txtSpellsCast)
.addComponent(btnSwitchHands)
.addComponent(btnCancelSkip)
@ -1862,6 +1884,7 @@ public final class GamePanel extends javax.swing.JPanel {
.addComponent(btnSkipToEndStepBeforeYourTurn)
)
.addGroup(gl_pnlShortCuts.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(txtHoldPriority)
.addComponent(txtSpellsCast)
.addComponent(btnSwitchHands)
.addComponent(btnCancelSkip)
@ -2343,6 +2366,48 @@ public final class GamePanel extends javax.swing.JPanel {
return feedbackPanel;
}
// Use Cmd on OSX since Ctrl+click is already used to simulate right click
private static int holdPriorityMask = System.getProperty("os.name").contains("Mac OS X") ? InputEvent.META_DOWN_MASK : InputEvent.CTRL_DOWN_MASK;
public void handleEvent(AWTEvent event) {
if(event instanceof InputEvent) {
int id = event.getID();
boolean isActionEvent = false;
if(id == MouseEvent.MOUSE_PRESSED)
isActionEvent = true;
else if(id == KeyEvent.KEY_PRESSED)
{
KeyEvent key = (KeyEvent)event;
int keyCode = key.getKeyCode();
if(keyCode == KeyEvent.VK_ENTER || keyCode == KeyEvent.VK_SPACE)
isActionEvent = true;
}
if(isActionEvent) {
InputEvent input = (InputEvent)event;
if((input.getModifiersEx() & holdPriorityMask) != 0) {
setMenuStates(
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true"),
PreferencesDialog.getCachedValue(KEY_USE_FIRST_MANA_ABILITY, "false").equals("true"),
true);
holdPriority(true);
}
}
}
}
public void holdPriority(boolean holdPriority) {
if(holdingPriority != holdPriority) {
holdingPriority = holdPriority;
txtHoldPriority.setVisible(holdPriority);
if(holdPriority)
session.sendPlayerAction(PlayerAction.HOLD_PRIORITY, gameId, null);
else
session.sendPlayerAction(PlayerAction.UNHOLD_PRIORITY, gameId, null);
}
}
private boolean holdingPriority;
private mage.client.components.ability.AbilityPicker abilityPicker;
private mage.client.cards.BigCard bigCard;
@ -2397,6 +2462,7 @@ public final class GamePanel extends javax.swing.JPanel {
private JPanel jPhases;
private JPanel phasesContainer;
private javax.swing.JLabel txtSpellsCast;
private javax.swing.JLabel txtHoldPriority;
private HoverButton currentStep;
private Point prevPoint;