From 7c7163b511365e7fb9bf3d8d555b7b6b476f6c8c Mon Sep 17 00:00:00 2001 From: drdev Date: Wed, 26 Nov 2014 20:22:48 +0000 Subject: [PATCH] Add support for tapping the topmost card of a stack to activate the card behind if the card on top has no remaining actions (same as mobile game already supports) --- .../screens/match/controllers/CPrompt.java | 4 +- .../main/java/forge/view/arcane/PlayArea.java | 49 +++++++++++++++---- .../screens/match/views/VCardDisplayArea.java | 17 +++---- .../main/java/forge/match/input/Input.java | 2 +- .../java/forge/match/input/InputAttack.java | 5 +- .../java/forge/match/input/InputBase.java | 8 ++- .../java/forge/match/input/InputBlock.java | 2 - .../match/input/InputConfirmMulligan.java | 1 - .../java/forge/match/input/InputLockUI.java | 3 +- .../forge/match/input/InputPassPriority.java | 8 +-- .../java/forge/match/input/InputPayMana.java | 6 +-- .../input/InputSelectCardsForConvoke.java | 4 +- 12 files changed, 65 insertions(+), 44 deletions(-) diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPrompt.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPrompt.java index b3e5766ee5d..d06b54670eb 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPrompt.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPrompt.java @@ -108,8 +108,8 @@ public enum CPrompt implements ICDoc { MatchUtil.getHumanController().selectPlayer(playerView, triggerEvent); } - public void selectCard(final CardView cardView, final List otherCardViewsToSelect, final ITriggerEvent triggerEvent) { - MatchUtil.getHumanController().selectCard(cardView, otherCardViewsToSelect, triggerEvent); + public boolean selectCard(final CardView cardView, final List otherCardViewsToSelect, final ITriggerEvent triggerEvent) { + return MatchUtil.getHumanController().selectCard(cardView, otherCardViewsToSelect, triggerEvent); } public void selectAbility(final SpellAbility sa) { diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java b/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java index 00a4abd82d7..d32152763b1 100644 --- a/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java +++ b/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java @@ -32,6 +32,7 @@ import forge.game.card.CardView; import forge.game.card.CardView.CardStateView; import forge.game.player.PlayerView; import forge.game.zone.ZoneType; +import forge.match.MatchUtil; import forge.screens.match.CMatchUI; import forge.screens.match.controllers.CPrompt; import forge.toolbox.FScrollPane; @@ -530,22 +531,46 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen } private void selectCard(final CardPanel panel, final MouseEvent evt) { + //on left double-click or Shift+left, select all other cards in stack if any + selectCard(panel, new MouseTriggerEvent(evt), + evt.getButton() == 1 && (evt.isShiftDown() || evt.getClickCount() == 2)); + } + + private boolean selectCard(final CardPanel panel, final MouseTriggerEvent triggerEvent, final boolean selectOtherCardsInStack) { List otherCardViewsToSelect = null; - if (evt.getButton() == 1 && (evt.isShiftDown() || evt.getClickCount() == 2)) { - //on left double-click or Shift+left, select all other cards in stack if any - List stack = panel.getStack(); + List stack = panel.getStack(); + if (selectOtherCardsInStack) { if (stack != null) { - stack = new ArrayList(stack); - stack.remove(panel); - if (stack.size() > 0) { - otherCardViewsToSelect = new ArrayList(); - for (CardPanel p : stack) { + for (CardPanel p : stack) { + if (p != panel && p.getCard() != null) { + if (otherCardViewsToSelect == null) { + otherCardViewsToSelect = new ArrayList(); + } otherCardViewsToSelect.add(p.getCard()); } } } } - CPrompt.SINGLETON_INSTANCE.selectCard(panel.getCard(), otherCardViewsToSelect, new MouseTriggerEvent(evt)); + if (CPrompt.SINGLETON_INSTANCE.selectCard(panel.getCard(), otherCardViewsToSelect, triggerEvent)) { + return true; + } + //if panel can't do anything with card selection, try selecting previous panel in stack + if (stack != null) { + int index = stack.indexOf(panel); + if (index < stack.size() - 1 && selectCard(stack.get(index + 1), triggerEvent, selectOtherCardsInStack)) { + return true; + } + } + //as a last resort try to select attached panels not in stack + for (CardPanel p : panel.getAttachedPanels()) { + if (p.getStack() != stack) { //ensure same panel not checked more than once + if (selectCard(p, triggerEvent, selectOtherCardsInStack)) { + return true; + } + } + } + MatchUtil.getController().flashIncorrectAction(); + return false; } public void setupPlayZone() { @@ -839,6 +864,12 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen return false; } + @Override + public void add(final int index, final CardPanel panel) { + super.add(index, panel); + panel.setStack(this); + } + private void addAttachedPanels(final CardPanel panel) { for (final CardPanel attachedPanel : panel.getAttachedPanels()) { if (panel.getCard() != null && super.add(attachedPanel)) { diff --git a/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java b/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java index 822946daa07..b1816c45da5 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java @@ -260,11 +260,11 @@ public abstract class VCardDisplayArea extends VDisplayArea { @Override public boolean tap(float x, float y, int count) { if (renderedCardContains(x, y)) { - final boolean isDoubleTap = (count % 2 == 0); + final boolean selectOtherCardsInStack = (count % 2 == 0); ThreadUtil.invokeInGameThread(new Runnable() { //must invoke in game thread in case a dialog needs to be shown @Override public void run() { - if (!selectCard(isDoubleTap)) { + if (!selectCard(selectOtherCardsInStack)) { //if no cards in stack can be selected, just show zoom/details for card CardZoom.show(getCard()); } @@ -275,17 +275,17 @@ public abstract class VCardDisplayArea extends VDisplayArea { return false; } - public boolean selectCard(boolean isDoubleTap) { - if (MatchUtil.getHumanController().selectCard(getCard(), getOtherCardsToSelect(isDoubleTap), null)) { + public boolean selectCard(boolean selectOtherCardsInStack) { + if (MatchUtil.getHumanController().selectCard(getCard(), getOtherCardsToSelect(selectOtherCardsInStack), null)) { return true; } //if panel can't do anything with card selection, try selecting previous panel in stack - if (prevPanelInStack != null && prevPanelInStack.selectCard(isDoubleTap)) { + if (prevPanelInStack != null && prevPanelInStack.selectCard(selectOtherCardsInStack)) { return true; } //as a last resort try to select attached panels for (CardAreaPanel panel : attachedPanels) { - if (panel.selectCard(isDoubleTap)) { + if (panel.selectCard(selectOtherCardsInStack)) { return true; } } @@ -315,8 +315,8 @@ public abstract class VCardDisplayArea extends VDisplayArea { } } - private List getOtherCardsToSelect(boolean isDoubleTap) { - if (!isDoubleTap) { return null; } + private List getOtherCardsToSelect(boolean selectOtherCardsInStack) { + if (!selectOtherCardsInStack) { return null; } //on double-tap select all other cards in stack if any if (prevPanelInStack == null && nextPanelInStack == null) { return null; } @@ -333,7 +333,6 @@ public abstract class VCardDisplayArea extends VDisplayArea { cards.add(panel.getCard()); panel = panel.prevPanelInStack; } - return cards; } diff --git a/forge-gui/src/main/java/forge/match/input/Input.java b/forge-gui/src/main/java/forge/match/input/Input.java index 992fe5c1030..86702f88de5 100644 --- a/forge-gui/src/main/java/forge/match/input/Input.java +++ b/forge-gui/src/main/java/forge/match/input/Input.java @@ -15,7 +15,7 @@ public interface Input { boolean selectCard(Card card, final List otherCardsToSelect, ITriggerEvent triggerEvent); - void selectAbility(SpellAbility ab); + boolean selectAbility(SpellAbility ab); void selectPlayer(Player player, ITriggerEvent triggerEvent); diff --git a/forge-gui/src/main/java/forge/match/input/InputAttack.java b/forge-gui/src/main/java/forge/match/input/InputAttack.java index 5ff2d1c1d9e..d08e781f0eb 100644 --- a/forge-gui/src/main/java/forge/match/input/InputAttack.java +++ b/forge-gui/src/main/java/forge/match/input/InputAttack.java @@ -147,7 +147,7 @@ public class InputAttack extends InputSyncronizedBase { setCurrentDefender(selected); } else { - flashIncorrectAction(); // cannot attack that player + MatchUtil.getController().flashIncorrectAction(); // cannot attack that player } } @@ -176,7 +176,6 @@ public class InputAttack extends InputSyncronizedBase { declareAttacker(card); } else { - flashIncorrectAction(); validAction = false; } } @@ -201,7 +200,6 @@ public class InputAttack extends InputSyncronizedBase { if (activeBand != null && !activeBand.canJoinBand(card)) { activateBand(null); updateMessage(); - flashIncorrectAction(); return false; } @@ -214,7 +212,6 @@ public class InputAttack extends InputSyncronizedBase { return true; } - flashIncorrectAction(); return false; } diff --git a/forge-gui/src/main/java/forge/match/input/InputBase.java b/forge-gui/src/main/java/forge/match/input/InputBase.java index dadb18b0c72..cc1b42bb14c 100644 --- a/forge-gui/src/main/java/forge/match/input/InputBase.java +++ b/forge-gui/src/main/java/forge/match/input/InputBase.java @@ -141,7 +141,9 @@ public abstract class InputBase implements java.io.Serializable, Input { } @Override - public void selectAbility(final SpellAbility ab) { } + public boolean selectAbility(final SpellAbility ab) { + return false; + } @Override public final void selectButtonCancel() { @@ -173,10 +175,6 @@ public abstract class InputBase implements java.io.Serializable, Input { MatchUtil.getController().showPromptMessage(getOwner(), message); } - protected final void flashIncorrectAction() { - MatchUtil.getController().flashIncorrectAction(); - } - protected String getTurnPhasePriorityMessage(final Game game) { final PhaseHandler ph = game.getPhaseHandler(); final StringBuilder sb = new StringBuilder(); diff --git a/forge-gui/src/main/java/forge/match/input/InputBlock.java b/forge-gui/src/main/java/forge/match/input/InputBlock.java index 0b1270749c2..ef630bb8d98 100644 --- a/forge-gui/src/main/java/forge/match/input/InputBlock.java +++ b/forge-gui/src/main/java/forge/match/input/InputBlock.java @@ -153,8 +153,6 @@ public class InputBlock extends InputSyncronizedBase { if (isCorrectAction) { card.getGame().fireEvent(new GameEventCombatChanged()); - } else { - flashIncorrectAction(); } showMessage(); diff --git a/forge-gui/src/main/java/forge/match/input/InputConfirmMulligan.java b/forge-gui/src/main/java/forge/match/input/InputConfirmMulligan.java index d5d5d5e3fde..742e876f694 100644 --- a/forge-gui/src/main/java/forge/match/input/InputConfirmMulligan.java +++ b/forge-gui/src/main/java/forge/match/input/InputConfirmMulligan.java @@ -117,7 +117,6 @@ public class InputConfirmMulligan extends InputSyncronizedBase { boolean isSerumPowder = c0.getName().equals("Serum Powder"); boolean isLegalChoice = fromHand && (isCommander || isSerumPowder); if (!isLegalChoice || cardSelectLocked) { - flashIncorrectAction(); return false; } diff --git a/forge-gui/src/main/java/forge/match/input/InputLockUI.java b/forge-gui/src/main/java/forge/match/input/InputLockUI.java index 6fe18041de9..d2c2be7d42f 100644 --- a/forge-gui/src/main/java/forge/match/input/InputLockUI.java +++ b/forge-gui/src/main/java/forge/match/input/InputLockUI.java @@ -74,7 +74,8 @@ public class InputLockUI implements Input { return false; } @Override - public void selectAbility(SpellAbility ab) { + public boolean selectAbility(SpellAbility ab) { + return false; } @Override public void selectPlayer(Player player, ITriggerEvent triggerEvent) { diff --git a/forge-gui/src/main/java/forge/match/input/InputPassPriority.java b/forge-gui/src/main/java/forge/match/input/InputPassPriority.java index 89fe40ceb68..3f71df5932b 100644 --- a/forge-gui/src/main/java/forge/match/input/InputPassPriority.java +++ b/forge-gui/src/main/java/forge/match/input/InputPassPriority.java @@ -128,19 +128,19 @@ public class InputPassPriority extends InputSyncronizedBase { //remove unplayable unless triggerEvent specified, in which case unplayable may be shown as disabled options List abilities = card.getAllPossibleAbilities(player, triggerEvent == null); if (abilities.isEmpty()) { - flashIncorrectAction(); return false; } - selectAbility(player.getController().getAbilityToPlay(abilities, triggerEvent)); - return true; + return selectAbility(player.getController().getAbilityToPlay(abilities, triggerEvent)); } @Override - public void selectAbility(final SpellAbility ab) { + public boolean selectAbility(final SpellAbility ab) { if (ab != null) { chosenSa = ab; stop(); + return true; } + return false; } } diff --git a/forge-gui/src/main/java/forge/match/input/InputPayMana.java b/forge-gui/src/main/java/forge/match/input/InputPayMana.java index f63cbb5efab..85c21a9fae9 100644 --- a/forge-gui/src/main/java/forge/match/input/InputPayMana.java +++ b/forge-gui/src/main/java/forge/match/input/InputPayMana.java @@ -68,7 +68,6 @@ public abstract class InputPayMana extends InputSyncronizedBase { @Override protected boolean onCardSelected(final Card card, final List otherCardsToSelect, final ITriggerEvent triggerEvent) { if (card.getManaAbilities().isEmpty()) { - flashIncorrectAction(); return false; } // only tap card if the mana is needed @@ -76,10 +75,11 @@ public abstract class InputPayMana extends InputSyncronizedBase { } @Override - public void selectAbility(final SpellAbility ab) { + public boolean selectAbility(final SpellAbility ab) { if (ab != null && ab.isManaAbility()) { - activateManaAbility(ab.getHostCard(), manaCost, ab); + return activateManaAbility(ab.getHostCard(), manaCost, ab); } + return false; } public List getUsefulManaAbilities(Card card) { diff --git a/forge-gui/src/main/java/forge/match/input/InputSelectCardsForConvoke.java b/forge-gui/src/main/java/forge/match/input/InputSelectCardsForConvoke.java index a497fd16ccf..fed6f93a2d9 100644 --- a/forge-gui/src/main/java/forge/match/input/InputSelectCardsForConvoke.java +++ b/forge-gui/src/main/java/forge/match/input/InputSelectCardsForConvoke.java @@ -41,7 +41,6 @@ public final class InputSelectCardsForConvoke extends InputSelectManyBase protected boolean onCardSelected(final Card card, final List otherCardsToSelect, final ITriggerEvent triggerEvent) { if (!availableCreatures.contains(card)) { // Not in untapped creatures list provided. Not a legal Convoke selection. - flashIncorrectAction(); return false; } @@ -52,7 +51,6 @@ public final class InputSelectCardsForConvoke extends InputSelectManyBase onSelectStateChanged(card, false); } else { - byte chosenColor = player.getController().chooseColorAllowColorless("Convoke " + card.toString() + " for which color?", card, CardUtil.getColors(card)); if (remainingCost.getColorlessManaAmount() > 0 && (chosenColor == 0 || !remainingCost.needsColor(chosenColor, player.getManaPool()))) { @@ -67,7 +65,7 @@ public final class InputSelectCardsForConvoke extends InputSelectManyBase } } showMessage("The colors provided by " + card.toString() + " you've chosen cannot be used to decrease the manacost of " + remainingCost.toString()); - flashIncorrectAction(); + return false; } }