diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java index af889cad68..5221a55051 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java @@ -134,6 +134,7 @@ public class PreferencesDialog extends javax.swing.JDialog { // mana auto payment public static final String KEY_GAME_MANA_AUTOPAYMENT = "gameManaAutopayment"; + public static final String KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE = "gameManaAutopaymentOnlyOne"; // Size of frame to check if divider locations should be used public static final String KEY_MAGE_PANEL_LAST_SIZE = "gamepanelLastSize"; diff --git a/Mage.Client/src/main/java/mage/client/game/GamePanel.java b/Mage.Client/src/main/java/mage/client/game/GamePanel.java index 7f08d27340..029e928fd7 100644 --- a/Mage.Client/src/main/java/mage/client/game/GamePanel.java +++ b/Mage.Client/src/main/java/mage/client/game/GamePanel.java @@ -91,6 +91,7 @@ import mage.client.dialog.PickNumberDialog; import mage.client.dialog.PickPileDialog; import mage.client.dialog.PreferencesDialog; import static mage.client.dialog.PreferencesDialog.KEY_GAME_MANA_AUTOPAYMENT; +import static mage.client.dialog.PreferencesDialog.KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE; import mage.client.dialog.ShowCardsDialog; import mage.client.game.FeedbackPanel.FeedbackMode; import mage.client.plugins.adapters.MageActionCallback; @@ -459,7 +460,9 @@ public final class GamePanel extends javax.swing.JPanel { public synchronized void init(GameView game) { addPlayers(game); // default menu states - setMenuStates(PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true")); + setMenuStates( + PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true"), + PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true")); updateGame(game); } @@ -734,10 +737,11 @@ public final class GamePanel extends javax.swing.JPanel { /** * Set the same state for menu selections to all player areas. * @param manaPoolAutomatic + * @param manaPoolAutomaticRestricted */ - public void setMenuStates(boolean manaPoolAutomatic) { + public void setMenuStates(boolean manaPoolAutomatic, boolean manaPoolAutomaticRestricted) { for(PlayAreaPanel playAreaPanel: players.values()) { - playAreaPanel.setMenuStates(manaPoolAutomatic); + playAreaPanel.setMenuStates(manaPoolAutomatic, manaPoolAutomaticRestricted); } } diff --git a/Mage.Client/src/main/java/mage/client/game/PlayAreaPanel.java b/Mage.Client/src/main/java/mage/client/game/PlayAreaPanel.java index eef809c720..8c4de96db8 100644 --- a/Mage.Client/src/main/java/mage/client/game/PlayAreaPanel.java +++ b/Mage.Client/src/main/java/mage/client/game/PlayAreaPanel.java @@ -55,6 +55,7 @@ import mage.client.cards.BigCard; import mage.client.dialog.PreferencesDialog; import static mage.client.dialog.PreferencesDialog.KEY_GAME_ALLOW_REQUEST_SHOW_HAND_CARDS; import static mage.client.dialog.PreferencesDialog.KEY_GAME_MANA_AUTOPAYMENT; +import static mage.client.dialog.PreferencesDialog.KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE; import mage.constants.PlayerAction; import mage.view.PlayerView; @@ -72,7 +73,8 @@ public class PlayAreaPanel extends javax.swing.JPanel { private final GamePanel gamePanel; private final PlayAreaPanelOptions options; - private JCheckBoxMenuItem manaPoolMenuItem; + private JCheckBoxMenuItem manaPoolMenuItem1; + private JCheckBoxMenuItem manaPoolMenuItem2; private JCheckBoxMenuItem allowViewHandCardsMenuItem; public static final int PANEL_HEIGHT = 242; @@ -139,99 +141,135 @@ public class PlayAreaPanel extends javax.swing.JPanel { JMenuItem menuItem; - menuItem = new JMenuItem("F2 - Confirm"); - popupMenu.add(menuItem); - - // Confirm (F2) - menuItem.addActionListener(new ActionListener() { + ActionListener skipListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - if (gamePanel.getFeedbackPanel() != null) { - gamePanel.getFeedbackPanel().pressOKYesOrDone(); + switch (e.getActionCommand()) { + case "F2": { + if (gamePanel.getFeedbackPanel() != null) { + gamePanel.getFeedbackPanel().pressOKYesOrDone(); + } + break; + } + case "F3": { + gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_CANCEL_ALL_ACTIONS, gameId, null); + break; + } + case "F4": { + gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_TURN, gameId, null); + break; + } + case "F5": { + gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_TURN_END_STEP, gameId, null); + break; + } + case "F7": { + gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_MAIN_PHASE, gameId, null); + break; + } + case "F9": { + gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_MY_NEXT_TURN, gameId, null); + break; + } } } - }); - - - menuItem = new JMenuItem("F3 - Cancel previous F4/F9 skip action"); + }; + + menuItem = new JMenuItem("F2 - Confirm current request"); + menuItem.setActionCommand("F2"); + menuItem.setMnemonic(KeyEvent.VK_O); popupMenu.add(menuItem); + menuItem.addActionListener(skipListener); - // Cancel (F3) - menuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_CANCEL_ALL_ACTIONS, gameId, null); - } - }); + menuItem = new JMenuItem("F3 - Cancel active skip action"); + menuItem.setActionCommand("F3"); + menuItem.setMnemonic(KeyEvent.VK_N); + popupMenu.add(menuItem); + menuItem.addActionListener(skipListener); + + + JMenu skipMenu = new JMenu("Skip"); + skipMenu.setMnemonic(KeyEvent.VK_S); + popupMenu.add(skipMenu); + + String tooltipText = "This skip actions stops if something goes to
stack and if attackers or blocker have to be declared."; + menuItem = new JMenuItem("F4 - Phases until next turn"); + menuItem.setActionCommand("F4"); + menuItem.setToolTipText(tooltipText); + menuItem.setMnemonic(KeyEvent.VK_T); + skipMenu.add(menuItem); + menuItem.addActionListener(skipListener); + + menuItem = new JMenuItem("F5 - Phases until next end step"); + menuItem.setActionCommand("F5"); + menuItem.setToolTipText(tooltipText); + menuItem.setMnemonic(KeyEvent.VK_E); + skipMenu.add(menuItem); + menuItem.addActionListener(skipListener); + + menuItem = new JMenuItem("F7 - Phases until begin of next main phase"); + menuItem.setToolTipText(tooltipText); + menuItem.setActionCommand("F7"); + menuItem.setMnemonic(KeyEvent.VK_M); + skipMenu.add(menuItem); + menuItem.addActionListener(skipListener); + + menuItem = new JMenuItem("F9 - Everything until your own next turn"); + menuItem.setActionCommand("F9"); + menuItem.setToolTipText(tooltipText); + menuItem.setMnemonic(KeyEvent.VK_N); + skipMenu.add(menuItem); + menuItem.addActionListener(skipListener); popupMenu.addSeparator(); - - menuItem = new JMenuItem("F4 - Skip phases until next turn (stop on stack/attack/block)"); - popupMenu.add(menuItem); - - // Skip to next turn (F4) - menuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_TURN, gameId, null); - } - }); - - menuItem = new JMenuItem("F5 - Skip phases until next end step (stop on stack/attack/block)"); - popupMenu.add(menuItem); - - // Skip to next end step of turn (F5) - menuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_TURN_END_STEP, gameId, null); - } - }); - - menuItem = new JMenuItem("F7 - Skip phases until begin of next main phase (stop on stack/attack/block)"); - popupMenu.add(menuItem); - - // Skip to next main phase (F7) - menuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_MAIN_PHASE, gameId, null); - } - }); - menuItem = new JMenuItem("F9 - Skip everything until own next turn (stop on attack/block)"); - popupMenu.add(menuItem); - - // Skip to next own turn (F9) - menuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_MY_NEXT_TURN, gameId, null); - } - }); - - popupMenu.addSeparator(); - - manaPoolMenuItem = new JCheckBoxMenuItem("Use mana from pool automatically", true); - manaPoolMenuItem.setMnemonic(KeyEvent.VK_M); - manaPoolMenuItem.setToolTipText("If not active, you have to click the type of mana you want to pay in the player panel."); - popupMenu.add(manaPoolMenuItem); + + JMenu manaPoolMenu = new JMenu("Mana payment"); + manaPoolMenu.setMnemonic(KeyEvent.VK_M); + popupMenu.add(manaPoolMenu); + + manaPoolMenuItem1 = new JCheckBoxMenuItem("Automatically", true); + manaPoolMenuItem1.setMnemonic(KeyEvent.VK_A); + manaPoolMenuItem1.setToolTipText("If not active, produced mana goes only to the mana pool
" + + "and you have to click the type of mana you want to use
" + + "in the player mana pool panel for payment."); + manaPoolMenu.add(manaPoolMenuItem1); // Auto pay mana from mana pool - manaPoolMenuItem.addActionListener(new ActionListener() { + manaPoolMenuItem1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { boolean manaPoolAutomatic = ((JCheckBoxMenuItem)e.getSource()).getState(); PreferencesDialog.saveValue(KEY_GAME_MANA_AUTOPAYMENT, manaPoolAutomatic ? "true": "false"); - gamePanel.setMenuStates(manaPoolAutomatic); + gamePanel.setMenuStates(manaPoolAutomatic, manaPoolMenuItem2.getState()); gamePanel.getSession().sendPlayerAction(manaPoolAutomatic ? PlayerAction.MANA_AUTO_PAYMENT_ON: PlayerAction.MANA_AUTO_PAYMENT_OFF, gameId, null); } }); + manaPoolMenuItem2 = new JCheckBoxMenuItem("No automatic usage for mana already in the pool", true); + manaPoolMenuItem2.setMnemonic(KeyEvent.VK_N); + manaPoolMenuItem2.setToolTipText("Mana that is already in the mana pool as you start casting a spell or activating an ability
" + + " needs to be payed manually. So you use the mana in the pool only by clicking on the related
" + + " mana symbols of mana pool area."); + manaPoolMenu.add(manaPoolMenuItem2); + // Auto pay mana from mana pool + manaPoolMenuItem2.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + boolean manaPoolAutomaticRestricted = ((JCheckBoxMenuItem)e.getSource()).getState(); + PreferencesDialog.saveValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, manaPoolAutomaticRestricted ? "true": "false"); + gamePanel.setMenuStates(manaPoolMenuItem1.getState(), manaPoolAutomaticRestricted); + gamePanel.getSession().sendPlayerAction(manaPoolAutomaticRestricted ? PlayerAction.MANA_AUTO_PAYMENT_RESTRICTED_ON: PlayerAction.MANA_AUTO_PAYMENT_RESTRICTED_OFF, gameId, null); + } + }); + JMenu automaticConfirmsMenu = new JMenu("Automatic confirms"); + automaticConfirmsMenu.setMnemonic(KeyEvent.VK_U); + popupMenu.add(automaticConfirmsMenu); + menuItem = new JMenuItem("Replacement effects - reset auto select"); menuItem.setMnemonic(KeyEvent.VK_R); menuItem.setToolTipText("Reset all effects that were added to the list of auto select replacement effects this game."); - popupMenu.add(menuItem); + automaticConfirmsMenu.add(menuItem); // Reset the replacement effcts that were auto selected for the game menuItem.addActionListener(new ActionListener() { @Override @@ -240,11 +278,14 @@ public class PlayAreaPanel extends javax.swing.JPanel { } }); - popupMenu.addSeparator(); - + JMenu handCardsMenu = new JMenu("Cards on hand"); + handCardsMenu.setMnemonic(KeyEvent.VK_H); + popupMenu.add(handCardsMenu); + if (!options.playerItself) { - menuItem = new JMenuItem("Request permission to see hand cards"); - popupMenu.add(menuItem); + menuItem = new JMenuItem("Request permission to see the hand cards"); + menuItem.setMnemonic(KeyEvent.VK_P); + handCardsMenu.add(menuItem); // Request to see hand cards menuItem.addActionListener(new ActionListener() { @@ -254,10 +295,10 @@ public class PlayAreaPanel extends javax.swing.JPanel { } }); } else { - allowViewHandCardsMenuItem = new JCheckBoxMenuItem("Allow requests to show your hand cards", allowRequestToShowHandCards); + allowViewHandCardsMenuItem = new JCheckBoxMenuItem("Allow requests to show from other users", allowRequestToShowHandCards); allowViewHandCardsMenuItem.setMnemonic(KeyEvent.VK_A); allowViewHandCardsMenuItem.setToolTipText("If activated watchers or other players can request to see your hand cards. If you grant this to a user, it's valid for the complete match."); - popupMenu.add(allowViewHandCardsMenuItem); + handCardsMenu.add(allowViewHandCardsMenuItem); // Requests allowed allowViewHandCardsMenuItem.addActionListener(new ActionListener() { @@ -270,9 +311,9 @@ public class PlayAreaPanel extends javax.swing.JPanel { }); menuItem = new JMenuItem("Revoke all permission(s) to see your hand cards"); - menuItem.setMnemonic(KeyEvent.VK_P); + menuItem.setMnemonic(KeyEvent.VK_R); menuItem.setToolTipText("Revoke already granted permission for all spectators to see your hand cards."); - popupMenu.add(menuItem); + handCardsMenu.add(menuItem); // revoke permissions to see hand cards menuItem.addActionListener(new ActionListener() { @@ -282,8 +323,7 @@ public class PlayAreaPanel extends javax.swing.JPanel { } }); } - popupMenu.addSeparator(); - + if (options.rollbackTurnsAllowed) { ActionListener rollBackActionListener = new ActionListener() { @Override @@ -298,78 +338,73 @@ public class PlayAreaPanel extends javax.swing.JPanel { rollbackMainItem.setToolTipText("The game will be rolled back to the start of the requested turn if all players agree."); popupMenu.add(rollbackMainItem); - menuItem = new JMenuItem("to the start of the current turn"); + menuItem = new JMenuItem("To the start of the current turn"); menuItem.setMnemonic(KeyEvent.VK_C); menuItem.setActionCommand("0"); menuItem.addActionListener(rollBackActionListener); rollbackMainItem.add(menuItem); - menuItem = new JMenuItem("to the start of the previous turn"); + menuItem = new JMenuItem("To the start of the previous turn"); menuItem.setMnemonic(KeyEvent.VK_P); menuItem.setActionCommand("1"); menuItem.addActionListener(rollBackActionListener); rollbackMainItem.add(menuItem); - menuItem = new JMenuItem("the current turn and the 2 turns before"); + menuItem = new JMenuItem("The current turn and the 2 turns before"); menuItem.setMnemonic(KeyEvent.VK_2); menuItem.setActionCommand("2"); menuItem.addActionListener(rollBackActionListener); rollbackMainItem.add(menuItem); - menuItem = new JMenuItem("the current turn and the 3 turns before"); + menuItem = new JMenuItem("The current turn and the 3 turns before"); menuItem.setMnemonic(KeyEvent.VK_3); menuItem.setActionCommand("3"); menuItem.addActionListener(rollBackActionListener); rollbackMainItem.add(menuItem); + + } - popupMenu.addSeparator(); - - } - - menuItem = new JMenuItem("Revoke all permission(s) to see your hand cards"); - menuItem.setMnemonic(KeyEvent.VK_P); - menuItem.setToolTipText("Revoke already granted permission for all spectators to see your hand cards."); - popupMenu.add(menuItem); + - // revoke permissions to see hand cards - menuItem.addActionListener(new ActionListener() { + JMenu concedeMenu = new JMenu("Concede"); + concedeMenu.setMnemonic(KeyEvent.VK_C); + popupMenu.add(concedeMenu); + + ActionListener concedeListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - gamePanel.getSession().sendPlayerAction(PlayerAction.REVOKE_PERMISSIONS_TO_SEE_HAND_CARDS, gameId, null); - } - }); - - popupMenu.addSeparator(); - - menuItem = new JMenuItem("Concede game"); - popupMenu.add(menuItem); - - // Concede - menuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (JOptionPane.showConfirmDialog(PlayAreaPanel.this, "Are you sure you want to concede the game?", "Confirm concede game", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { - MageFrame.getSession().sendPlayerAction(PlayerAction.CONCEDE, gameId, null); + switch (e.getActionCommand()) { + case "Game": { + if (JOptionPane.showConfirmDialog(PlayAreaPanel.this, "Are you sure you want to concede the game?", "Confirm concede game", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { + MageFrame.getSession().sendPlayerAction(PlayerAction.CONCEDE, gameId, null); + } + } + case "Match": { + if (JOptionPane.showConfirmDialog(PlayAreaPanel.this, "Are you sure you want to concede the complete match?", "Confirm concede match", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { + MageFrame.getSession().quitMatch(gameId); + } + } } } - }); - - popupMenu.addSeparator(); - - menuItem = new JMenuItem("Concede complete match"); - popupMenu.add(menuItem); - - // Quit match - menuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (JOptionPane.showConfirmDialog(PlayAreaPanel.this, "Are you sure you want to concede the complete match?", "Confirm concede match", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { - MageFrame.getSession().quitMatch(gameId); - } - } - }); - + }; + + // Concede Game + menuItem = new JMenuItem("Game"); + menuItem.setMnemonic(KeyEvent.VK_G); + menuItem.setActionCommand("Game"); + menuItem.setToolTipText("Concedes only the current game and after that the next game of the match is started if there is another game needed."); + concedeMenu.add(menuItem); + menuItem.addActionListener(concedeListener); + + // Concede Match + menuItem = new JMenuItem("Match"); + menuItem.setMnemonic(KeyEvent.VK_M); + menuItem.setActionCommand("Match"); + menuItem.setToolTipText("Concedes the complete match. So if you're in a tournament you finish the current tournament round."); + concedeMenu.add(menuItem); + menuItem.addActionListener(concedeListener); + battlefieldPanel.getMainPanel().addMouseListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent Me) { @@ -531,8 +566,9 @@ public class PlayAreaPanel extends javax.swing.JPanel { this.playingMode = playingMode; } - public void setMenuStates(boolean manaPoolAutomatic) { - manaPoolMenuItem.setSelected(manaPoolAutomatic); + public void setMenuStates(boolean manaPoolAutomatic, boolean manaPoolAutomaticRestricted) { + manaPoolMenuItem1.setSelected(manaPoolAutomatic); + manaPoolMenuItem2.setSelected(manaPoolAutomaticRestricted); } private mage.client.game.BattlefieldPanel battlefieldPanel; diff --git a/Mage.Common/src/mage/remote/interfaces/GamePlay.java b/Mage.Common/src/mage/remote/interfaces/GamePlay.java index d99f17011c..f54a193fd3 100644 --- a/Mage.Common/src/mage/remote/interfaces/GamePlay.java +++ b/Mage.Common/src/mage/remote/interfaces/GamePlay.java @@ -78,6 +78,7 @@ public interface GamePlay { * * @param passPriorityAction * @param gameId + * @param Data * @return */ boolean sendPlayerAction(PlayerAction passPriorityAction, UUID gameId, Object Data); diff --git a/Mage.Server/src/main/java/mage/server/game/GameController.java b/Mage.Server/src/main/java/mage/server/game/GameController.java index da30ce7fde..5f541cc186 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameController.java +++ b/Mage.Server/src/main/java/mage/server/game/GameController.java @@ -537,10 +537,16 @@ public class GameController implements GameCallback { game.concede(getPlayerId(userId)); break; case MANA_AUTO_PAYMENT_OFF: - game.setManaPoolMode(getPlayerId(userId), false); + game.setManaPaymentMode(getPlayerId(userId), false); break; case MANA_AUTO_PAYMENT_ON: - game.setManaPoolMode(getPlayerId(userId), true); + game.setManaPaymentMode(getPlayerId(userId), true); + break; + case MANA_AUTO_PAYMENT_RESTRICTED_OFF: + game.setManaPaymentModeRestricted(getPlayerId(userId), false); + break; + case MANA_AUTO_PAYMENT_RESTRICTED_ON: + game.setManaPaymentModeRestricted(getPlayerId(userId), true); break; case ADD_PERMISSION_TO_SEE_HAND_CARDS: if (data instanceof UUID) { diff --git a/Mage/src/mage/constants/PlayerAction.java b/Mage/src/mage/constants/PlayerAction.java index 5194b11303..82c18616d7 100644 --- a/Mage/src/mage/constants/PlayerAction.java +++ b/Mage/src/mage/constants/PlayerAction.java @@ -44,6 +44,8 @@ public enum PlayerAction { CONCEDE, MANA_AUTO_PAYMENT_ON, MANA_AUTO_PAYMENT_OFF, + MANA_AUTO_PAYMENT_RESTRICTED_ON, + MANA_AUTO_PAYMENT_RESTRICTED_OFF, RESET_AUTO_SELECT_REPLACEMENT_EFFECTS, REVOKE_PERMISSIONS_TO_SEE_HAND_CARDS, REQUEST_PERMISSION_TO_SEE_HAND_CARDS, diff --git a/Mage/src/mage/game/Game.java b/Mage/src/mage/game/Game.java index 6429c34a0a..3743aae59c 100644 --- a/Mage/src/mage/game/Game.java +++ b/Mage/src/mage/game/Game.java @@ -224,7 +224,8 @@ public interface Game extends MageItem, Serializable { void timerTimeout(UUID playerId); void idleTimeout(UUID playerId); void concede(UUID playerId); - void setManaPoolMode(UUID playerId, boolean autoPayment); + void setManaPaymentMode(UUID playerId, boolean autoPayment); + void setManaPaymentModeRestricted(UUID playerId, boolean autoPaymentRestricted); void undo(UUID playerId); void emptyManaPools(); void addEffect(ContinuousEffect continuousEffect, Ability source); diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 991c93727c..8a108c50aa 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -1124,12 +1124,20 @@ public abstract class GameImpl implements Game, Serializable { @Override - public synchronized void setManaPoolMode(UUID playerId, boolean autoPayment) { + public synchronized void setManaPaymentMode(UUID playerId, boolean autoPayment) { Player player = state.getPlayer(playerId); if (player != null) { player.getManaPool().setAutoPayment(autoPayment); } } + + @Override + public synchronized void setManaPaymentModeRestricted(UUID playerId, boolean autoPaymentRestricted) { + Player player = state.getPlayer(playerId); + if (player != null) { + player.getManaPool().setAutoPaymentRestricted(autoPaymentRestricted); + } + } @Override public void playPriority(UUID activePlayerId, boolean resuming) { diff --git a/Mage/src/mage/players/ManaPool.java b/Mage/src/mage/players/ManaPool.java index 3e50bbf9c2..200faae6b7 100644 --- a/Mage/src/mage/players/ManaPool.java +++ b/Mage/src/mage/players/ManaPool.java @@ -61,6 +61,7 @@ public class ManaPool implements Serializable { private final List manaItems = new ArrayList<>(); private boolean autoPayment; // auto payment from mana pool: true - mode is active + private boolean autoPaymentRestricted; // auto payment from mana pool: true - if auto Payment is on, it will only pay if one kind of mana is in the pool private ManaType unlockedManaType; // type of mana that was selected to pay manually private final Set doNotEmptyManaTypes = new HashSet<>(); @@ -68,6 +69,7 @@ public class ManaPool implements Serializable { public ManaPool(UUID playerId) { this.playerId = playerId; autoPayment = true; + autoPaymentRestricted = true; unlockedManaType = null; } @@ -77,6 +79,7 @@ public class ManaPool implements Serializable { manaItems.add(item.copy()); } this.autoPayment = pool.autoPayment; + this.autoPaymentRestricted = pool.autoPaymentRestricted; this.unlockedManaType = pool.unlockedManaType; this.doNotEmptyManaTypes.addAll(pool.doNotEmptyManaTypes); } @@ -101,11 +104,25 @@ public class ManaPool implements Serializable { return get(ManaType.BLACK); } + /** + * + * @param manaType the mana type that should be paid + * @param ability + * @param filter + * @param game + * @return + */ public boolean pay(ManaType manaType, Ability ability, Filter filter, Game game) { if (!autoPayment && !manaType.equals(unlockedManaType)) { // if manual payment and the needed mana type was not unlocked, nothing will be paid return false; } + if (autoPayment && autoPaymentRestricted && !wasManaAddedBeyondStock() && !manaType.equals(unlockedManaType)) { + // if automatic restricted payment and there is laready mana in the pool + // and the needed mana type was not unlocked, nothing will be paid + return false; + } + if (getConditional(manaType, ability, filter, game) > 0) { removeConditional(manaType, ability, game); lockManaType(); // pay only one mana if mana payment is set to manually @@ -118,6 +135,10 @@ public class ManaPool implements Serializable { continue; } } + if (!manaType.equals(unlockedManaType) && autoPayment && autoPaymentRestricted && mana.count() == mana.getStock()) { + // no mana added beyond the stock so don't auto pay this + continue; + } boolean spendAnyMana = spendAnyMana(ability, game); if (mana.get(manaType) > 0 || (spendAnyMana && mana.count() > 0)) { GameEvent event = new GameEvent(GameEvent.EventType.MANA_PAYED, ability.getId(), mana.getSourceId(), ability.getControllerId(), 0, mana.getFlag()); @@ -128,6 +149,9 @@ public class ManaPool implements Serializable { } else { mana.remove(manaType); } + if (mana.count() == 0) { // so no items with count 0 stay in list + manaItems.remove(mana); + } lockManaType(); // pay only one mana if mana payment is set to manually return true; } @@ -416,6 +440,14 @@ public class ManaPool implements Serializable { this.autoPayment = autoPayment; } + public void setAutoPaymentRestricted(boolean autoPaymentRestricted) { + this.autoPaymentRestricted = autoPaymentRestricted; + } + + public boolean isAutoPaymentRestricted() { + return autoPaymentRestricted; + } + public ManaType getUnlockedManaType() { return unlockedManaType; } @@ -428,4 +460,18 @@ public class ManaPool implements Serializable { this.unlockedManaType = null; } + public void setStock() { + for (ManaPoolItem mana : manaItems) { + mana.setStock(mana.count()); + } + } + + private boolean wasManaAddedBeyondStock() { + for (ManaPoolItem mana : manaItems) { + if (mana.getStock() < mana.count()) { + return true; + } + } + return false; + } } diff --git a/Mage/src/mage/players/ManaPoolItem.java b/Mage/src/mage/players/ManaPoolItem.java index 0d952cb41c..b6a8f796b9 100644 --- a/Mage/src/mage/players/ManaPoolItem.java +++ b/Mage/src/mage/players/ManaPoolItem.java @@ -51,6 +51,7 @@ public class ManaPoolItem implements Serializable { private UUID originalId; // originalId of the mana producing ability private boolean flag = false; private Duration duration; + private int stock; // amount the item had at the start of casting something public ManaPoolItem() {} @@ -91,6 +92,7 @@ public class ManaPoolItem implements Serializable { this.originalId = item.originalId; this.flag = item.flag; this.duration = item.duration; + this.stock = item.stock; } public ManaPoolItem copy() { @@ -207,8 +209,9 @@ public class ManaPoolItem implements Serializable { } public void removeAny() { + int oldCount = count(); if (black > 0) { - black--; + black--; } else if (blue > 0) { blue--; } else if (green > 0) { @@ -219,10 +222,14 @@ public class ManaPoolItem implements Serializable { white--; } else if (colorless > 0) { colorless--; - } + } + if (stock == oldCount && oldCount > count()) { + stock--; + } } public void remove(ManaType manaType) { + int oldCount = count(); switch(manaType) { case BLACK: if (black > 0) { @@ -255,6 +262,9 @@ public class ManaPoolItem implements Serializable { } break; } + if (stock == oldCount && oldCount > count()) { + stock--; + } } public void clear(ManaType manaType) { @@ -310,5 +320,13 @@ public class ManaPoolItem implements Serializable { public void setDuration(Duration duration) { this.duration = duration; } + + public int getStock() { + return stock; + } + + public void setStock(int stock) { + this.stock = stock; + } } diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index da437f0943..1d3bd46276 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -1085,6 +1085,7 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean activateAbility(ActivatedAbility ability, Game game) { + getManaPool().setStock(); // needed for the "mana already in the pool has to be used manually" option boolean result; if (ability instanceof PassAbility) { pass(game);