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)

This commit is contained in:
drdev
2014-11-26 20:22:48 +00:00
parent 74c579c286
commit 7c7163b511
12 changed files with 65 additions and 44 deletions

View File

@@ -108,8 +108,8 @@ public enum CPrompt implements ICDoc {
MatchUtil.getHumanController().selectPlayer(playerView, triggerEvent);
}
public void selectCard(final CardView cardView, final List<CardView> otherCardViewsToSelect, final ITriggerEvent triggerEvent) {
MatchUtil.getHumanController().selectCard(cardView, otherCardViewsToSelect, triggerEvent);
public boolean selectCard(final CardView cardView, final List<CardView> otherCardViewsToSelect, final ITriggerEvent triggerEvent) {
return MatchUtil.getHumanController().selectCard(cardView, otherCardViewsToSelect, triggerEvent);
}
public void selectAbility(final SpellAbility sa) {

View File

@@ -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<CardView> 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<CardPanel> stack = panel.getStack();
List<CardPanel> stack = panel.getStack();
if (selectOtherCardsInStack) {
if (stack != null) {
stack = new ArrayList<CardPanel>(stack);
stack.remove(panel);
if (stack.size() > 0) {
otherCardViewsToSelect = new ArrayList<CardView>();
for (CardPanel p : stack) {
for (CardPanel p : stack) {
if (p != panel && p.getCard() != null) {
if (otherCardViewsToSelect == null) {
otherCardViewsToSelect = new ArrayList<CardView>();
}
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)) {

View File

@@ -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<CardView> getOtherCardsToSelect(boolean isDoubleTap) {
if (!isDoubleTap) { return null; }
private List<CardView> 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;
}

View File

@@ -15,7 +15,7 @@ public interface Input {
boolean selectCard(Card card, final List<Card> otherCardsToSelect, ITriggerEvent triggerEvent);
void selectAbility(SpellAbility ab);
boolean selectAbility(SpellAbility ab);
void selectPlayer(Player player, ITriggerEvent triggerEvent);

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -153,8 +153,6 @@ public class InputBlock extends InputSyncronizedBase {
if (isCorrectAction) {
card.getGame().fireEvent(new GameEventCombatChanged());
} else {
flashIncorrectAction();
}
showMessage();

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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<SpellAbility> 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;
}
}

View File

@@ -68,7 +68,6 @@ public abstract class InputPayMana extends InputSyncronizedBase {
@Override
protected boolean onCardSelected(final Card card, final List<Card> 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<SpellAbility> getUsefulManaAbilities(Card card) {

View File

@@ -41,7 +41,6 @@ public final class InputSelectCardsForConvoke extends InputSelectManyBase<Card>
protected boolean onCardSelected(final Card card, final List<Card> 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<Card>
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<Card>
}
}
showMessage("The colors provided by " + card.toString() + " you've chosen cannot be used to decrease the manacost of " + remainingCost.toString());
flashIncorrectAction();
return false;
}
}