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 ff2cea1e1b1..ca91c8cc5ec 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java @@ -173,12 +173,28 @@ public abstract class VCardDisplayArea extends VDisplayArea { ThreadUtil.invokeInGameThread(new Runnable() { //must invoke in game thread in case a dialog needs to be shown @Override public void run() { - FControl.getInputProxy().selectCard(getCard(), null); + if (!selectCard()) { + //if no cards in stack can be selected, just show zoom/details for card + CardZoom.show(getCard()); + } } }); return true; } + public boolean selectCard() { + if (FControl.getInputProxy().selectCard(getCard(), null)) { + return true; + } + //if panel can't do anything with card selection, try selecting an attached panel + for (CardAreaPanel panel : attachedPanels) { + if (panel.selectCard()) { + return true; + } + } + return false; + } + @Override public boolean longPress(float x, float y) { CardZoom.show(getCard()); 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 5764a571073..524fb58d950 100644 --- a/forge-gui/src/main/java/forge/match/input/Input.java +++ b/forge-gui/src/main/java/forge/match/input/Input.java @@ -9,7 +9,7 @@ import forge.util.ITriggerEvent; public interface Input { void showMessageInitial(); - void selectCard(Card c, ITriggerEvent triggerEvent); + boolean selectCard(Card c, ITriggerEvent triggerEvent); void selectAbility(SpellAbility ab); 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 88a38fbb4c9..4ff0fba1fec 100644 --- a/forge-gui/src/main/java/forge/match/input/InputAttack.java +++ b/forge-gui/src/main/java/forge/match/input/InputAttack.java @@ -69,7 +69,7 @@ public class InputAttack extends InputSyncronizedBase { setCurrentDefender(defenders.isEmpty() ? null : defenders.get(0)); - if ( null == currentDefender ) { + if (null == currentDefender) { System.err.println("InputAttack has no potential defenders!"); return; // should even throw here! } @@ -77,8 +77,8 @@ public class InputAttack extends InputSyncronizedBase { List possibleAttackers = playerAttacks.getCardsIn(ZoneType.Battlefield); for (Card c : Iterables.filter(possibleAttackers, CardPredicates.Presets.CREATURES)) { if (c.hasKeyword("CARDNAME attacks each turn if able.")) { - for(GameEntity def : defenders ) { - if( CombatUtil.canAttack(c, def, combat) ) { + for(GameEntity def : defenders) { + if(CombatUtil.canAttack(c, def, combat)) { combat.addAttacker(c, currentDefender); GuiBase.getInterface().fireEvent(new UiEventAttackerDeclared(c, currentDefender)); break; @@ -123,7 +123,7 @@ public class InputAttack extends InputSyncronizedBase { /** {@inheritDoc} */ @Override - protected final void onCardSelected(final Card card, final ITriggerEvent triggerEvent) { + protected final boolean onCardSelected(final Card card, final ITriggerEvent triggerEvent) { final List att = combat.getAttackers(); if (triggerEvent != null && triggerEvent.getButton() == 3 && att.contains(card) && !card.hasKeyword("CARDNAME attacks each turn if able.") && !card.hasStartOfKeyword("CARDNAME attacks specific player each combat if able")) { @@ -135,32 +135,37 @@ public class InputAttack extends InputSyncronizedBase { this.activateBand(null); GuiBase.getInterface().fireEvent(new UiEventAttackerDeclared(card, null)); - return; + return true; } if (combat.isAttacking(card, currentDefender)) { // Activate band by selecting/deselecting a band member + boolean validAction = true; if (this.activeBand == null) { this.activateBand(combat.getBandOfAttacker(card)); - } else if (this.activeBand.getAttackers().contains(card)) { + } + else if (this.activeBand.getAttackers().contains(card)) { this.activateBand(null); - } else { // Join a band by selecting a non-active band member after activating a band + } + else { // Join a band by selecting a non-active band member after activating a band if (this.activeBand.canJoinBand(card)) { combat.removeFromCombat(card); declareAttacker(card); - } else { + } + else { flashIncorrectAction(); + validAction = false; } } updateMessage(); - return; + return validAction; } - if ( card.getController().isOpponentOf(playerAttacks) ) { - if ( defenders.contains(card) ) { // planeswalker? + if (card.getController().isOpponentOf(playerAttacks)) { + if (defenders.contains(card)) { // planeswalker? setCurrentDefender(card); - return; + return true; } } @@ -169,7 +174,7 @@ public class InputAttack extends InputSyncronizedBase { this.activateBand(null); updateMessage(); flashIncorrectAction(); - return; + return false; } if(combat.isAttacking(card)) { @@ -178,12 +183,12 @@ public class InputAttack extends InputSyncronizedBase { declareAttacker(card); showCombat(); + return true; } - else { - flashIncorrectAction(); - } - } // selectCard() + flashIncorrectAction(); + return false; + } /** * TODO: Write javadoc for this method. @@ -199,8 +204,8 @@ public class InputAttack extends InputSyncronizedBase { private final void setCurrentDefender(GameEntity def) { currentDefender = def; - for( GameEntity ge: defenders ) { - if ( ge instanceof Card) { + for(GameEntity ge: defenders) { + if (ge instanceof Card) { GuiBase.getInterface().setUsedToPay((Card)ge, ge == def); } else if (ge instanceof Player) { 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 9dc16213da0..7e663aead40 100644 --- a/forge-gui/src/main/java/forge/match/input/InputBase.java +++ b/forge-gui/src/main/java/forge/match/input/InputBase.java @@ -71,12 +71,14 @@ public abstract class InputBase implements java.io.Serializable, Input { } @Override - public final void selectCard(final Card c, final ITriggerEvent triggerEvent) { - if (isFinished()) { return; } - onCardSelected(c, triggerEvent); + public final boolean selectCard(final Card c, final ITriggerEvent triggerEvent) { + if (isFinished()) { return false; } + return onCardSelected(c, triggerEvent); } - protected void onCardSelected(final Card c, final ITriggerEvent triggerEvent) {} + protected boolean onCardSelected(final Card c, final ITriggerEvent triggerEvent) { + return false; + } protected void onPlayerSelected(final Player p, final ITriggerEvent triggerEvent) {} protected void onCancel() {} protected void onOk() {} 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 751c6281eaa..61ccf41600a 100644 --- a/forge-gui/src/main/java/forge/match/input/InputBlock.java +++ b/forge-gui/src/main/java/forge/match/input/InputBlock.java @@ -97,22 +97,24 @@ public class InputBlock extends InputSyncronizedBase { /** {@inheritDoc} */ @Override - public final void onCardSelected(final Card card, final ITriggerEvent triggerEvent) { + public final boolean onCardSelected(final Card card, final ITriggerEvent triggerEvent) { + boolean isCorrectAction = false; if (triggerEvent != null && triggerEvent.getButton() == 3 && card.getController() == defender) { combat.removeFromCombat(card); GuiBase.getInterface().fireEvent(new UiEventBlockerAssigned(card, (Card)null)); - } else { + isCorrectAction = true; + } + else { // is attacking? - boolean isCorrectAction = false; - if (combat.isAttacking(card)) { setCurrentAttacker(card); isCorrectAction = true; - } else { + } + else { // Make sure this card is valid to even be a blocker if (this.currentAttacker != null && card.isCreature() && defender.getZone(ZoneType.Battlefield).contains(card)) { isCorrectAction = CombatUtil.canBlock(this.currentAttacker, card, combat); - if ( isCorrectAction ) { + if (isCorrectAction) { combat.addBlocker(this.currentAttacker, card); GuiBase.getInterface().fireEvent(new UiEventBlockerAssigned(card, currentAttacker)); } @@ -124,8 +126,8 @@ public class InputBlock extends InputSyncronizedBase { } } this.showMessage(); - } // selectCard() - + return isCorrectAction; + } private void setCurrentAttacker(Card card) { currentAttacker = card; 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 c74702b170e..b43ade73ce4 100644 --- a/forge-gui/src/main/java/forge/match/input/InputConfirmMulligan.java +++ b/forge-gui/src/main/java/forge/match/input/InputConfirmMulligan.java @@ -111,13 +111,13 @@ public class InputConfirmMulligan extends InputSyncronizedBase { volatile boolean cardSelectLocked = false; @Override - protected void onCardSelected(final Card c0, final ITriggerEvent triggerEvent) { // the only place that would cause troubles - input is supposed only to confirm, not to fire abilities + protected boolean onCardSelected(final Card c0, final ITriggerEvent triggerEvent) { // the only place that would cause troubles - input is supposed only to confirm, not to fire abilities boolean fromHand = player.getZone(ZoneType.Hand).contains(c0); boolean isSerumPowder = c0.getName().equals("Serum Powder"); boolean isLegalChoice = fromHand && (isCommander || isSerumPowder); if (!isLegalChoice || cardSelectLocked) { flashIncorrectAction(); - return; + return false; } if (isSerumPowder && SGuiDialog.confirm(c0, "Use " + c0.getName() + "'s ability?")) { @@ -132,7 +132,7 @@ public class InputConfirmMulligan extends InputSyncronizedBase { cardSelectLocked = false; } }); - return; + return true; } if (isCommander) { // allow to choose cards for partial paris @@ -151,6 +151,7 @@ public class InputConfirmMulligan extends InputSyncronizedBase { ButtonUtil.enableAllFocusOk(); } } + return true; } public final boolean isKeepHand() { 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 a769c542dc8..7c97bf4e4ea 100644 --- a/forge-gui/src/main/java/forge/match/input/InputLockUI.java +++ b/forge-gui/src/main/java/forge/match/input/InputLockUI.java @@ -59,10 +59,20 @@ public class InputLockUI implements Input { GuiBase.getInterface().showPromptMessage(message); } - @Override public void selectCard(Card c, ITriggerEvent triggerEvent) {} - @Override public void selectAbility(SpellAbility ab) {} - @Override public void selectPlayer(Player player, ITriggerEvent triggerEvent) {} - @Override public void selectButtonOK() {} - @Override public void selectButtonCancel() {} - + @Override + public boolean selectCard(Card c, ITriggerEvent triggerEvent) { + return false; + } + @Override + public void selectAbility(SpellAbility ab) { + } + @Override + public void selectPlayer(Player player, ITriggerEvent triggerEvent) { + } + @Override + public void selectButtonOK() { + } + @Override + public void selectButtonCancel() { + } } 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 2c0d94afa01..c14d54ada11 100644 --- a/forge-gui/src/main/java/forge/match/input/InputPassPriority.java +++ b/forge-gui/src/main/java/forge/match/input/InputPassPriority.java @@ -60,15 +60,16 @@ public class InputPassPriority extends InputSyncronizedBase { public SpellAbility getChosenSa() { return chosenSa; } @Override - protected void onCardSelected(final Card card, final ITriggerEvent triggerEvent) { + protected boolean onCardSelected(final Card card, final ITriggerEvent triggerEvent) { //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; + return false; } selectAbility(player.getController().getAbilityToPlay(abilities, triggerEvent)); + return true; } @Override 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 ccb9eb93c57..9b32f5cd0a5 100644 --- a/forge-gui/src/main/java/forge/match/input/InputPayMana.java +++ b/forge-gui/src/main/java/forge/match/input/InputPayMana.java @@ -49,13 +49,13 @@ public abstract class InputPayMana extends InputSyncronizedBase { } @Override - protected void onCardSelected(final Card card, final ITriggerEvent triggerEvent) { + protected boolean onCardSelected(final Card card, final ITriggerEvent triggerEvent) { if (card.getManaAbility().isEmpty()) { flashIncorrectAction(); - return; + return false; } // only tap card if the mana is needed - activateManaAbility(card, this.manaCost); + return activateManaAbility(card, this.manaCost); } @Override @@ -123,18 +123,18 @@ public abstract class InputPayMana extends InputSyncronizedBase { * a {@link forge.game.mana.ManaCostBeingPaid} object. * @return a {@link forge.game.mana.ManaCostBeingPaid} object. */ - protected void activateManaAbility(final Card card, ManaCostBeingPaid manaCost) { - activateManaAbility(card, manaCost, null); + protected boolean activateManaAbility(final Card card, ManaCostBeingPaid manaCost) { + return activateManaAbility(card, manaCost, null); } - protected void activateManaAbility(final Card card, ManaCostBeingPaid manaCost, SpellAbility chosenAbility) { - if ( locked ) { + protected boolean activateManaAbility(final Card card, ManaCostBeingPaid manaCost, SpellAbility chosenAbility) { + if (locked) { System.err.print("Should wait till previous call to playAbility finishes."); - return; + return false; } // make sure computer's lands aren't selected if (card.getController() != player) { - return; + return false; } byte colorCanUse = 0; @@ -149,7 +149,7 @@ public abstract class InputPayMana extends InputSyncronizedBase { } if (colorCanUse == 0) { // no mana cost or something - return; + return false; } List abilities = new ArrayList(); @@ -157,7 +157,7 @@ public abstract class InputPayMana extends InputSyncronizedBase { final String typeRes = manaCost.getSourceRestriction(); if (StringUtils.isNotBlank(typeRes) && !card.isType(typeRes)) { - return; + return false; } boolean guessAbilityWithRequiredColors = true; @@ -179,7 +179,7 @@ public abstract class InputPayMana extends InputSyncronizedBase { } if (abilities.isEmpty() || (chosenAbility != null && !abilities.contains(chosenAbility))) { - return; + return false; } // Store some information about color costs to help with any mana choices @@ -251,6 +251,7 @@ public abstract class InputPayMana extends InputSyncronizedBase { }; locked = true; game.getAction().invoke(proc); + return true; } /** diff --git a/forge-gui/src/main/java/forge/match/input/InputPayManaX.java b/forge-gui/src/main/java/forge/match/input/InputPayManaX.java index 11417da1877..f59e3ef30af 100644 --- a/forge-gui/src/main/java/forge/match/input/InputPayManaX.java +++ b/forge-gui/src/main/java/forge/match/input/InputPayManaX.java @@ -92,9 +92,9 @@ public class InputPayManaX extends InputPayMana { } @Override - protected void onCardSelected(final Card card, final ITriggerEvent triggerEvent) { + protected boolean onCardSelected(final Card card, final ITriggerEvent triggerEvent) { // don't allow here the cards that produce only wrong colors - activateManaAbility(card, this.manaCost); + return activateManaAbility(card, this.manaCost); } @Override diff --git a/forge-gui/src/main/java/forge/match/input/InputProliferate.java b/forge-gui/src/main/java/forge/match/input/InputProliferate.java index cef4de14970..60a331d1723 100644 --- a/forge-gui/src/main/java/forge/match/input/InputProliferate.java +++ b/forge-gui/src/main/java/forge/match/input/InputProliferate.java @@ -42,9 +42,9 @@ public final class InputProliferate extends InputSelectManyBase { } @Override - protected void onCardSelected(final Card card, final ITriggerEvent triggerEvent) { + protected boolean onCardSelected(final Card card, final ITriggerEvent triggerEvent) { if (!card.hasCounters()) { - return; + return false; } boolean entityWasSelected = chosenCounters.containsKey(card); @@ -64,6 +64,7 @@ public final class InputProliferate extends InputSelectManyBase { } refresh(); + return true; } @Override diff --git a/forge-gui/src/main/java/forge/match/input/InputProxy.java b/forge-gui/src/main/java/forge/match/input/InputProxy.java index b0c56d50e6c..24de86350a7 100644 --- a/forge-gui/src/main/java/forge/match/input/InputProxy.java +++ b/forge-gui/src/main/java/forge/match/input/InputProxy.java @@ -136,11 +136,12 @@ public class InputProxy implements Observer { * a {@link forge.game.card.Card} object. * @param triggerEvent */ - public final void selectCard(final Card card, final ITriggerEvent triggerEvent) { + public final boolean selectCard(final Card card, final ITriggerEvent triggerEvent) { Input inp = getInput(); if (inp != null) { - inp.selectCard(card, triggerEvent); + return inp.selectCard(card, triggerEvent); } + return false; } public final void selectAbility(SpellAbility ab) { 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 d240ef1537b..913ff20b88e 100644 --- a/forge-gui/src/main/java/forge/match/input/InputSelectCardsForConvoke.java +++ b/forge-gui/src/main/java/forge/match/input/InputSelectCardsForConvoke.java @@ -38,11 +38,11 @@ public final class InputSelectCardsForConvoke extends InputSelectManyBase } @Override - protected void onCardSelected(final Card card, final ITriggerEvent triggerEvent) { + protected boolean onCardSelected(final Card card, final ITriggerEvent triggerEvent) { if (!availableCreatures.contains(card)) { // Not in untapped creatures list provided. Not a legal Convoke selection. flashIncorrectAction(); - return; + return false; } boolean entityWasSelected = chosenCards.containsKey(card); @@ -57,11 +57,12 @@ public final class InputSelectCardsForConvoke extends InputSelectManyBase if (remainingCost.getColorlessManaAmount() > 0 && (chosenColor == 0 || !remainingCost.needsColor(chosenColor, player.getManaPool()))) { registerConvoked(card, ManaCostShard.COLORLESS, chosenColor); - } else { + } + else { for (ManaCostShard shard : remainingCost.getDistinctShards()) { if (shard.canBePaidWithManaOfColor(chosenColor)) { registerConvoked(card, shard, chosenColor); - return; + return true; } } showMessage("The colors provided by " + card.toString() + " you've chosen cannot be used to decrease the manacost of " + remainingCost.toString()); @@ -70,6 +71,7 @@ public final class InputSelectCardsForConvoke extends InputSelectManyBase } refresh(); + return true; } private void registerConvoked(Card card, ManaCostShard shard, byte chosenColor) { diff --git a/forge-gui/src/main/java/forge/match/input/InputSelectEntitiesFromList.java b/forge-gui/src/main/java/forge/match/input/InputSelectEntitiesFromList.java index 67450d3b9d0..39b36c68025 100644 --- a/forge-gui/src/main/java/forge/match/input/InputSelectEntitiesFromList.java +++ b/forge-gui/src/main/java/forge/match/input/InputSelectEntitiesFromList.java @@ -25,11 +25,12 @@ public class InputSelectEntitiesFromList extends InputSele } @Override - protected void onCardSelected(final Card c, final ITriggerEvent triggerEvent) { + protected boolean onCardSelected(final Card c, final ITriggerEvent triggerEvent) { if (!selectEntity(c)) { - return; + return false; } refresh(); + return true; } @Override diff --git a/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java b/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java index 66ca394edb8..41356271648 100644 --- a/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java +++ b/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java @@ -104,33 +104,33 @@ public final class InputSelectTargets extends InputSyncronizedBase { } @Override - protected final void onCardSelected(final Card card, final ITriggerEvent triggerEvent) { + protected final boolean onCardSelected(final Card card, final ITriggerEvent triggerEvent) { if (!tgt.isUniqueTargets() && targetDepth.containsKey(card)) { - return; + return false; } // leave this in temporarily, there some seriously wrong things going on here // Can be targeted doesn't check if the target is a valid type, only if a card is generally "targetable" if (!card.canBeTargetedBy(sa)) { showMessage(sa.getHostCard() + " - Cannot target this card (Shroud? Protection? Restrictions)."); - return; + return false; } // If all cards must be from the same zone if (tgt.isSingleZone() && lastTarget != null && !card.getController().equals(lastTarget.getController())) { showMessage(sa.getHostCard() + " - Cannot target this card (not in the same zone)"); - return; + return false; } // If all cards must be from different zones if (tgt.isDifferentZone() && lastTarget != null && !card.getController().equals(lastTarget.getController().getOpponent())) { showMessage(sa.getHostCard() + " - Cannot target this card (not in different zones)"); - return; + return false; } // If the cards can't share a creature type if (tgt.isWithoutSameCreatureType() && lastTarget != null && card.sharesCreatureTypeWith(lastTarget)) { showMessage(sa.getHostCard() + " - Cannot target this card (should not share a creature type)"); - return; + return false; } // If all cards must have different controllers @@ -144,17 +144,18 @@ public final class InputSelectTargets extends InputSyncronizedBase { } if (targetedControllers.contains(card.getController())) { showMessage(sa.getHostCard() + " - Cannot target this card (must have different controllers)"); - return; + return false; } } if (!choices.contains(card)) { if (card.isPlaneswalker() && sa.getApi() == ApiType.DealDamage) { showMessage(sa.getHostCard() + " - To deal an opposing Planeswalker direct damage, target its controller and then redirect the damage on resolution."); - } else { + } + else { showMessage(sa.getHostCard() + " - The selected card is not a valid choice to be targeted."); } - return; + return false; } if (tgt.isDividedAsYouChoose()) { @@ -179,8 +180,8 @@ public final class InputSelectTargets extends InputSyncronizedBase { sb.append(apiBasedMessage); sb.append(card.toString()); Integer chosen = SGuiChoose.oneOrNone(sb.toString(), choices); - if (null == chosen) { - return; + if (chosen == null) { + return true; //still return true since there was a valid choice } allocatedPortion = chosen; } else { // otherwise assign the rest of the damage/protection @@ -190,6 +191,7 @@ public final class InputSelectTargets extends InputSyncronizedBase { tgt.addDividedAllocation(card, allocatedPortion); } addTarget(card); + return true; } // selectCard() @Override diff --git a/forge-gui/src/main/java/forge/player/HumanCostDecision.java b/forge-gui/src/main/java/forge/player/HumanCostDecision.java index 605a08d9c9d..51499c77f9b 100644 --- a/forge-gui/src/main/java/forge/player/HumanCostDecision.java +++ b/forge-gui/src/main/java/forge/player/HumanCostDecision.java @@ -727,11 +727,12 @@ public class HumanCostDecision extends CostDecisionMakerBase { private static final long serialVersionUID = 8338626212893374798L; @Override - protected void onCardSelected(Card c, ITriggerEvent triggerEvent) { + protected boolean onCardSelected(Card c, ITriggerEvent triggerEvent) { Card firstCard = Iterables.getFirst(this.selected, null); - if(firstCard != null && !CardPredicates.sharesColorWith(firstCard).apply(c)) - return; - super.onCardSelected(c, triggerEvent); + if (firstCard != null && !CardPredicates.sharesColorWith(firstCard).apply(c)) { + return false; + } + return super.onCardSelected(c, triggerEvent); } }; inp.setMessage("Select " + Lang.nounWithAmount(num, "card" ) + " of same color to reveal."); @@ -817,9 +818,9 @@ public class HumanCostDecision extends CostDecisionMakerBase { } @Override - protected void onCardSelected(Card c, ITriggerEvent triggerEvent) { + protected boolean onCardSelected(Card c, ITriggerEvent triggerEvent) { if (!isValidChoice(c) || c.getCounters(counterType) <= getTimesSelected(c)) { - return; + return false; } int tc = getTimesSelected(c); @@ -827,6 +828,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { onSelectStateChanged(c, true); refresh(); + return true; }; @Override