mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
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:
@@ -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) {
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -153,8 +153,6 @@ public class InputBlock extends InputSyncronizedBase {
|
||||
|
||||
if (isCorrectAction) {
|
||||
card.getGame().fireEvent(new GameEventCombatChanged());
|
||||
} else {
|
||||
flashIncorrectAction();
|
||||
}
|
||||
|
||||
showMessage();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user