mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
Refactor confirmTrigger into controller class
This commit is contained in:
@@ -10,6 +10,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import forge.card.ColorSet;
|
||||
import forge.deck.Deck;
|
||||
import forge.game.Game;
|
||||
@@ -27,6 +28,7 @@ import forge.game.spellability.AbilitySub;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.spellability.TargetChoices;
|
||||
import forge.game.trigger.Trigger;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.item.PaperCard;
|
||||
|
||||
@@ -135,8 +137,9 @@ public abstract class PlayerController {
|
||||
public abstract SpellAbility chooseSingleSpellForEffect(List<SpellAbility> spells, SpellAbility sa, String title);
|
||||
|
||||
public abstract boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message);
|
||||
public abstract boolean getWillPlayOnFirstTurn(boolean isFirstGame);
|
||||
public abstract boolean confirmStaticApplication(Card hostCard, GameEntity affected, String logic, String message);
|
||||
public abstract boolean confirmTrigger(SpellAbility sa, Trigger regtrig, Map<String, String> triggerParams, boolean isMandatory);
|
||||
public abstract boolean getWillPlayOnFirstTurn(boolean isFirstGame);
|
||||
|
||||
public abstract List<Card> orderBlockers(Card attacker, List<Card> blockers);
|
||||
public abstract List<Card> orderAttackers(Card blocker, List<Card> attackers);
|
||||
|
||||
@@ -47,6 +47,7 @@ import forge.game.spellability.Spell;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.spellability.TargetChoices;
|
||||
import forge.game.trigger.Trigger;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.item.PaperCard;
|
||||
import forge.util.Aggregates;
|
||||
@@ -73,11 +74,13 @@ public class PlayerControllerAi extends PlayerController {
|
||||
public SpellAbility getAbilityToPlay(List<SpellAbility> abilities, MouseEvent triggerEvent) {
|
||||
if (abilities.size() == 0) {
|
||||
return null;
|
||||
} else
|
||||
}
|
||||
else {
|
||||
return abilities.get(0);
|
||||
// } else {
|
||||
// return GuiChoose.oneOrNone("Choose ability for AI to play", abilities); // some day network interaction will be here
|
||||
// }
|
||||
}
|
||||
// else {
|
||||
// return GuiChoose.oneOrNone("Choose ability for AI to play", abilities); // some day network interaction will be here
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,7 +147,7 @@ public class PlayerControllerAi extends PlayerController {
|
||||
@Override
|
||||
public Card chooseSingleCardForEffect(Collection<Card> options, SpellAbility sa, String title, boolean isOptional) {
|
||||
ApiType api = sa.getApi();
|
||||
if ( null == api ) {
|
||||
if (null == api) {
|
||||
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
||||
}
|
||||
return api.getAi().chooseSingleCard(player, sa, options, isOptional);
|
||||
@@ -153,7 +156,7 @@ public class PlayerControllerAi extends PlayerController {
|
||||
@Override
|
||||
public Player chooseSinglePlayerForEffect(List<Player> options, SpellAbility sa, String title) {
|
||||
ApiType api = sa.getApi();
|
||||
if ( null == api ) {
|
||||
if (null == api) {
|
||||
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
||||
}
|
||||
return api.getAi().chooseSinglePlayer(player, sa, options);
|
||||
@@ -162,27 +165,67 @@ public class PlayerControllerAi extends PlayerController {
|
||||
@Override
|
||||
public SpellAbility chooseSingleSpellForEffect(java.util.List<SpellAbility> spells, SpellAbility sa, String title) {
|
||||
ApiType api = sa.getApi();
|
||||
if ( null == api ) {
|
||||
if (null == api) {
|
||||
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
||||
}
|
||||
return api.getAi().chooseSingleSpellAbility(player, sa, spells);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
||||
return getAi().confirmAction(sa, mode, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getWillPlayOnFirstTurn(boolean isFirstGame) {
|
||||
return true; // AI is brave :)
|
||||
}
|
||||
@Override
|
||||
public boolean confirmStaticApplication(Card hostCard, GameEntity affected, String logic, String message) {
|
||||
return getAi().confirmStaticApplication(hostCard, affected, logic, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean confirmTrigger(SpellAbility sa, Trigger regtrig, Map<String, String> triggerParams, boolean isMandatory) {
|
||||
if (triggerParams.containsKey("DelayedTrigger")) {
|
||||
//TODO: The only card with an optional delayed trigger is Shirei, Shizo's Caretaker,
|
||||
// needs to be expanded when a more difficult cards comes up
|
||||
return true;
|
||||
}
|
||||
// Store/replace target choices more properly to get this SA cleared.
|
||||
TargetChoices tc = null;
|
||||
TargetChoices subtc = null;
|
||||
boolean storeChoices = sa.getTargetRestrictions() != null;
|
||||
final SpellAbility sub = sa.getSubAbility();
|
||||
boolean storeSubChoices = sub != null && sub.getTargetRestrictions() != null;
|
||||
boolean ret = true;
|
||||
|
||||
if (storeChoices) {
|
||||
tc = sa.getTargets();
|
||||
sa.resetTargets();
|
||||
}
|
||||
if (storeSubChoices) {
|
||||
subtc = sub.getTargets();
|
||||
sub.resetTargets();
|
||||
}
|
||||
// There is no way this doTrigger here will have the same target as stored above
|
||||
// So it's possible it's making a different decision here than will actually happen
|
||||
if (!sa.doTrigger(isMandatory, player)) {
|
||||
ret = false;
|
||||
}
|
||||
if (storeChoices) {
|
||||
sa.resetTargets();
|
||||
sa.setTargets(tc);
|
||||
}
|
||||
if (storeSubChoices) {
|
||||
sub.resetTargets();
|
||||
sub.setTargets(subtc);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getWillPlayOnFirstTurn(boolean isFirstGame) {
|
||||
return true; // AI is brave :)
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> orderBlockers(Card attacker, List<Card> blockers) {
|
||||
return AiBlockController.orderBlockers(attacker, blockers);
|
||||
@@ -207,10 +250,12 @@ public class PlayerControllerAi extends PlayerController {
|
||||
List<Card> toTop = new ArrayList<Card>();
|
||||
|
||||
for (Card c: topN) {
|
||||
if (ComputerUtil.scryWillMoveCardToBottomOfLibrary(player, c))
|
||||
if (ComputerUtil.scryWillMoveCardToBottomOfLibrary(player, c)) {
|
||||
toBottom.add(c);
|
||||
else
|
||||
}
|
||||
else {
|
||||
toTop.add(c);
|
||||
}
|
||||
}
|
||||
|
||||
// put the rest on top in random order
|
||||
@@ -218,7 +263,6 @@ public class PlayerControllerAi extends PlayerController {
|
||||
return ImmutablePair.of(toTop, toBottom);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean willPutCardOnTop(Card c) {
|
||||
return true; // AI does not know what will happen next (another clash or that would become his topdeck)
|
||||
@@ -232,8 +276,9 @@ public class PlayerControllerAi extends PlayerController {
|
||||
|
||||
@Override
|
||||
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> validCards, int min, int max) {
|
||||
if ( p == player )
|
||||
if (p == player) {
|
||||
return brains.getCardsToDiscard(min, max, validCards, sa);
|
||||
}
|
||||
|
||||
boolean isTargetFriendly = !p.isOpponentOf(player);
|
||||
|
||||
@@ -253,13 +298,14 @@ public class PlayerControllerAi extends PlayerController {
|
||||
@Override
|
||||
public void playSpellAbilityForFree(SpellAbility copySA, boolean mayChooseNewTargets) {
|
||||
// Ai is known to set targets in doTrigger, so if it cannot choose new targets, we won't call canPlays
|
||||
if( mayChooseNewTargets ) {
|
||||
if (mayChooseNewTargets) {
|
||||
if (copySA instanceof Spell) {
|
||||
Spell spell = (Spell) copySA;
|
||||
if (!spell.canPlayFromEffectAI(player, true, true)) {
|
||||
return; // is this legal at all?
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
copySA.canPlayAI(player);
|
||||
}
|
||||
}
|
||||
@@ -268,7 +314,7 @@ public class PlayerControllerAi extends PlayerController {
|
||||
|
||||
@Override
|
||||
public void playSpellAbilityNoStack(SpellAbility effectSA, boolean canSetupTargets) {
|
||||
if ( canSetupTargets )
|
||||
if (canSetupTargets)
|
||||
effectSA.doTrigger(true, player); // first parameter does not matter, since return value won't be used
|
||||
ComputerUtil.playNoStack(player, effectSA, game);
|
||||
}
|
||||
@@ -320,10 +366,10 @@ public class PlayerControllerAi extends PlayerController {
|
||||
@Override
|
||||
public String chooseSomeType(String kindOfType, SpellAbility sa, List<String> validTypes, List<String> invalidTypes) {
|
||||
String chosen = ComputerUtil.chooseSomeType(player, kindOfType, sa.getParam("AILogic"), invalidTypes);
|
||||
if( StringUtils.isBlank(chosen) && !validTypes.isEmpty() )
|
||||
if (StringUtils.isBlank(chosen) && !validTypes.isEmpty())
|
||||
{
|
||||
chosen = validTypes.get(0);
|
||||
Log.warn("AI has no idea how to choose " + kindOfType +", defaulting to 1st element: chosen" );
|
||||
Log.warn("AI has no idea how to choose " + kindOfType +", defaulting to 1st element: chosen");
|
||||
}
|
||||
game.getAction().nofityOfValue(sa, null, "Computer picked: " + chosen, player);
|
||||
return chosen;
|
||||
@@ -339,13 +385,16 @@ public class PlayerControllerAi extends PlayerController {
|
||||
|
||||
@Override
|
||||
public List<Card> getCardsToMulligan(boolean isCommander, Player firstPlayer) {
|
||||
if( !ComputerUtil.wantMulligan(player) )
|
||||
if (!ComputerUtil.wantMulligan(player)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isCommander)
|
||||
if (!isCommander) {
|
||||
return player.getCardsIn(ZoneType.Hand);
|
||||
else
|
||||
}
|
||||
else {
|
||||
return ComputerUtil.getPartialParisCandidates(player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -353,7 +402,6 @@ public class PlayerControllerAi extends PlayerController {
|
||||
brains.declareAttackers(attacker, combat);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void declareBlockers(Player defender, Combat combat) {
|
||||
brains.declareBlockersFor(defender, combat);
|
||||
@@ -361,8 +409,9 @@ public class PlayerControllerAi extends PlayerController {
|
||||
|
||||
@Override
|
||||
public void takePriority() {
|
||||
if ( !game.isGameOver() )
|
||||
if (!game.isGameOver()) {
|
||||
brains.onPriorityRecieved();
|
||||
}
|
||||
// use separate thread for AI?
|
||||
}
|
||||
|
||||
@@ -436,7 +485,7 @@ public class PlayerControllerAi extends PlayerController {
|
||||
|
||||
@Override
|
||||
public boolean chooseBinary(SpellAbility sa, String question, BinaryChoiceType kindOfChoice) {
|
||||
if(kindOfChoice == BinaryChoiceType.TapOrUntap) return true;
|
||||
if (kindOfChoice == BinaryChoiceType.TapOrUntap) { return true; }
|
||||
return MyRandom.getRandom().nextBoolean();
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.spellability.TargetChoices;
|
||||
import forge.game.spellability.TargetSelection;
|
||||
import forge.game.trigger.Trigger;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
@@ -403,6 +404,36 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
return GuiDialog.confirm(hostCard, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean confirmTrigger(SpellAbility sa, Trigger regtrig, Map<String, String> triggerParams, boolean isMandatory) {
|
||||
if (this.shouldAlwaysAcceptTrigger(regtrig.getId())) {
|
||||
return true;
|
||||
}
|
||||
if (this.shouldAlwaysDeclineTrigger(regtrig.getId())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String triggerDesc = triggerParams.get("TriggerDescription").replace("CARDNAME", regtrig.getHostCard().getName());
|
||||
final StringBuilder buildQuestion = new StringBuilder("Use triggered ability of ");
|
||||
buildQuestion.append(regtrig.getHostCard().toString()).append("?");
|
||||
buildQuestion.append("\r\n(").append(triggerDesc).append(")\r\n");
|
||||
HashMap<String, Object> tos = sa.getTriggeringObjects();
|
||||
if (tos.containsKey("Attacker")) {
|
||||
buildQuestion.append("[Attacker: " + tos.get("Attacker") + "]");
|
||||
}
|
||||
if (tos.containsKey("Card")) {
|
||||
Card card = (Card) tos.get("Card");
|
||||
if (card != null && (card.getController() == player || game.getZoneOf(card) == null
|
||||
|| game.getZoneOf(card).getZoneType().isKnown())) {
|
||||
buildQuestion.append("[Triggering card: " + tos.get("Card") + "]");
|
||||
}
|
||||
}
|
||||
if (!GuiDialog.confirm(regtrig.getHostCard(), buildQuestion.toString())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getWillPlayOnFirstTurn(boolean isFirstGame) {
|
||||
InputPlayOrDraw inp = new InputPlayOrDraw(player, isFirstGame);
|
||||
@@ -869,10 +900,10 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
default:
|
||||
String[] colorNames = new String[cntColors];
|
||||
int i = 0;
|
||||
for(byte b : colors) {
|
||||
for (byte b : colors) {
|
||||
colorNames[i++] = MagicColor.toLongString(b);
|
||||
}
|
||||
if(colorNames.length > 2) {
|
||||
if (colorNames.length > 2) {
|
||||
return MagicColor.fromName(GuiChoose.one(message, colorNames));
|
||||
}
|
||||
int idxChosen = GuiDialog.confirm(sa.getSourceCard(), message, colorNames) ? 0 : 1;
|
||||
@@ -890,8 +921,9 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
|
||||
@Override
|
||||
public CounterType chooseCounterType(Collection<CounterType> options, SpellAbility sa, String prompt) {
|
||||
if( options.size() <= 1)
|
||||
if (options.size() <= 1) {
|
||||
return Iterables.getFirst(options, null);
|
||||
}
|
||||
return GuiChoose.one(prompt, options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityRestriction;
|
||||
import forge.game.spellability.TargetChoices;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.gui.GuiDialog;
|
||||
|
||||
// Wrapper ability that checks the requirements again just before
|
||||
// resolving, for intervening if clauses.
|
||||
@@ -356,8 +355,9 @@ public class WrappedAbility extends Ability implements ISpellAbility {
|
||||
TriggerHandler th = game.getTriggerHandler();
|
||||
Map<String, String> triggerParams = regtrig.getMapParams();
|
||||
|
||||
if (decider != null && !confirmTrigger(decider, triggerParams))
|
||||
if (decider != null && !decider.getController().confirmTrigger(sa, regtrig, triggerParams, this.isMandatory())) {
|
||||
return;
|
||||
}
|
||||
|
||||
getActivatingPlayer().getController().playSpellAbilityNoStack(sa, false);
|
||||
|
||||
@@ -370,71 +370,4 @@ public class WrappedAbility extends Ability implements ISpellAbility {
|
||||
th.registerDelayedTrigger(deltrig);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean confirmTrigger(Player decider, Map<String, String> triggerParams) {
|
||||
if (decider.isHuman()) {
|
||||
if(decider.getController().shouldAlwaysAcceptTrigger(regtrig.getId()))
|
||||
return true;
|
||||
else if(decider.getController().shouldAlwaysDeclineTrigger(regtrig.getId()))
|
||||
return false;
|
||||
|
||||
String triggerDesc = triggerParams.get("TriggerDescription").replace("CARDNAME", regtrig.getHostCard().getName());
|
||||
final StringBuilder buildQuestion = new StringBuilder("Use triggered ability of ");
|
||||
buildQuestion.append(regtrig.getHostCard().toString()).append("?");
|
||||
buildQuestion.append("\r\n(").append(triggerDesc).append(")\r\n");
|
||||
HashMap<String, Object> tos = sa.getTriggeringObjects();
|
||||
if (tos.containsKey("Attacker")) {
|
||||
buildQuestion.append("[Attacker: " + tos.get("Attacker") + "]");
|
||||
}
|
||||
if (tos.containsKey("Card")) {
|
||||
Card card = (Card) tos.get("Card");
|
||||
if (card != null && (card.getController() == decider || decider.getGame().getZoneOf(card) == null
|
||||
|| decider.getGame().getZoneOf(card).getZoneType().isKnown())) {
|
||||
buildQuestion.append("[Triggering card: " + tos.get("Card") + "]");
|
||||
}
|
||||
}
|
||||
if (!GuiDialog.confirm(regtrig.getHostCard(), buildQuestion.toString())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // human end
|
||||
|
||||
if (triggerParams.containsKey("DelayedTrigger")) {
|
||||
//TODO: The only card with an optional delayed trigger is Shirei, Shizo's Caretaker,
|
||||
// needs to be expanded when a more difficult cards comes up
|
||||
return true;
|
||||
}
|
||||
// Store/replace target choices more properly to get this SA cleared.
|
||||
TargetChoices tc = null;
|
||||
TargetChoices subtc = null;
|
||||
boolean storeChoices = sa.getTargetRestrictions() != null;
|
||||
final SpellAbility sub = sa.getSubAbility();
|
||||
boolean storeSubChoices = sub != null && sub.getTargetRestrictions() != null;
|
||||
boolean ret = true;
|
||||
|
||||
if (storeChoices) {
|
||||
tc = sa.getTargets();
|
||||
sa.resetTargets();
|
||||
}
|
||||
if (storeSubChoices) {
|
||||
subtc = sub.getTargets();
|
||||
sub.resetTargets();
|
||||
}
|
||||
// There is no way this doTrigger here will have the same target as stored above
|
||||
// So it's possible it's making a different decision here than will actually happen
|
||||
if (!sa.doTrigger(this.isMandatory(), decider)) {
|
||||
ret = false;
|
||||
}
|
||||
if (storeChoices) {
|
||||
sa.resetTargets();
|
||||
sa.setTargets(tc);
|
||||
}
|
||||
if (storeSubChoices) {
|
||||
sub.resetTargets();
|
||||
sub.setTargets(subtc);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ import forge.game.spellability.AbilitySub;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.spellability.TargetChoices;
|
||||
import forge.game.trigger.Trigger;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gamesimulationtests.util.card.CardSpecification;
|
||||
import forge.gamesimulationtests.util.card.CardSpecificationHandler;
|
||||
@@ -64,11 +65,11 @@ import forge.item.PaperCard;
|
||||
public class PlayerControllerForTests extends PlayerController {
|
||||
private PlayerActions playerActions;
|
||||
|
||||
public PlayerControllerForTests( Game game, Player player, LobbyPlayer lobbyPlayer ) {
|
||||
super( game, player, lobbyPlayer );
|
||||
public PlayerControllerForTests(Game game, Player player, LobbyPlayer lobbyPlayer) {
|
||||
super(game, player, lobbyPlayer);
|
||||
}
|
||||
|
||||
public void setPlayerActions( PlayerActions playerActions ) {
|
||||
public void setPlayerActions(PlayerActions playerActions) {
|
||||
this.playerActions = playerActions;
|
||||
}
|
||||
|
||||
@@ -85,210 +86,215 @@ public class PlayerControllerForTests extends PlayerController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellAbility getAbilityToPlay( List<SpellAbility> abilities ) {
|
||||
System.out.println( "getAbilityToPlay " + StringUtils.join( abilities, ", " ) );
|
||||
public SpellAbility getAbilityToPlay(List<SpellAbility> abilities) {
|
||||
System.out.println("getAbilityToPlay " + StringUtils.join(abilities, ", "));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSpellAbilityForFree( SpellAbility copySA, boolean mayChoseNewTargets ) {
|
||||
throw new IllegalStateException( "Callers of this method currently assume that it performs extra functionality!" );
|
||||
public void playSpellAbilityForFree(SpellAbility copySA, boolean mayChoseNewTargets) {
|
||||
throw new IllegalStateException("Callers of this method currently assume that it performs extra functionality!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSpellAbilityNoStack( SpellAbility effectSA, boolean mayChoseNewTargets ) {
|
||||
public void playSpellAbilityNoStack(SpellAbility effectSA, boolean mayChoseNewTargets) {
|
||||
//TODO: eventually (when the real code is refactored) this should be handled normally...
|
||||
if( effectSA.getDescription().equals( "At the beginning of your upkeep, if you have exactly 1 life, you win the game." ) ) {//test_104_2b_effect_may_state_that_player_wins_the_game
|
||||
HumanPlay.playSpellAbilityNoStack( player, effectSA, !mayChoseNewTargets );
|
||||
if (effectSA.getDescription().equals("At the beginning of your upkeep, if you have exactly 1 life, you win the game.")) {//test_104_2b_effect_may_state_that_player_wins_the_game
|
||||
HumanPlay.playSpellAbilityNoStack(player, effectSA, !mayChoseNewTargets);
|
||||
return;
|
||||
}
|
||||
if(
|
||||
( effectSA.getSourceCard().getName().equals( "Nefarious Lich" ) && effectSA.getApi().getAi() instanceof DrawAi ) ||
|
||||
( effectSA.getSourceCard().getName().equals( "Laboratory Maniac" ) && effectSA.getApi().getAi() instanceof GameWinAi ) ||
|
||||
( effectSA.getSourceCard().getName().equals( "Nefarious Lich" ) && effectSA.getApi().getAi() instanceof ChangeZoneAi )
|
||||
if (
|
||||
(effectSA.getSourceCard().getName().equals("Nefarious Lich") && effectSA.getApi().getAi() instanceof DrawAi) ||
|
||||
(effectSA.getSourceCard().getName().equals("Laboratory Maniac") && effectSA.getApi().getAi() instanceof GameWinAi) ||
|
||||
(effectSA.getSourceCard().getName().equals("Nefarious Lich") && effectSA.getApi().getAi() instanceof ChangeZoneAi)
|
||||
) {//test_104_3f_if_a_player_would_win_and_lose_simultaneously_he_loses
|
||||
HumanPlay.playSpellAbilityNoStack( player, effectSA, !mayChoseNewTargets );
|
||||
HumanPlay.playSpellAbilityNoStack(player, effectSA, !mayChoseNewTargets);
|
||||
return;
|
||||
}
|
||||
throw new IllegalStateException( "Callers of this method currently assume that it performs extra functionality!" );
|
||||
throw new IllegalStateException("Callers of this method currently assume that it performs extra functionality!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Deck sideboard( Deck deck, GameType gameType ) {
|
||||
public Deck sideboard(Deck deck, GameType gameType) {
|
||||
return deck;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Card, Integer> assignCombatDamage( Card attacker, List<Card> blockers, int damageDealt, GameEntity defender, boolean overrideOrder ) {
|
||||
if( blockers.size() == 1 && damageDealt == 2 && (
|
||||
( attacker.getName().equals( "Grizzly Bears" ) && blockers.get( 0 ).getName().equals( "Ajani's Sunstriker" ) ) ||
|
||||
( attacker.getName().equals( "Ajani's Sunstriker" ) && blockers.get( 0 ).getName().equals( "Grizzly Bears" ) )
|
||||
) ) {//test_104_3b_player_with_less_than_zero_life_loses_the_game_only_when_a_player_receives_priority_variant_with_combat
|
||||
public Map<Card, Integer> assignCombatDamage(Card attacker, List<Card> blockers, int damageDealt, GameEntity defender, boolean overrideOrder) {
|
||||
if (blockers.size() == 1 && damageDealt == 2 && (
|
||||
(attacker.getName().equals("Grizzly Bears") && blockers.get(0).getName().equals("Ajani's Sunstriker")) ||
|
||||
(attacker.getName().equals("Ajani's Sunstriker") && blockers.get(0).getName().equals("Grizzly Bears"))
|
||||
)) {//test_104_3b_player_with_less_than_zero_life_loses_the_game_only_when_a_player_receives_priority_variant_with_combat
|
||||
Map<Card, Integer> result = new HashMap<Card, Integer>();
|
||||
result.put( blockers.get( 0 ), damageDealt );
|
||||
result.put(blockers.get(0), damageDealt);
|
||||
return result;
|
||||
}
|
||||
throw new IllegalStateException( "Erring on the side of caution here..." );
|
||||
throw new IllegalStateException("Erring on the side of caution here...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer announceRequirements( SpellAbility ability, String announce, boolean allowZero ) {
|
||||
throw new IllegalStateException( "Erring on the side of caution here..." );
|
||||
public Integer announceRequirements(SpellAbility ability, String announce, boolean allowZero) {
|
||||
throw new IllegalStateException("Erring on the side of caution here...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> choosePermanentsToSacrifice( SpellAbility sa, int min, int max, List<Card> validTargets, String message ) {
|
||||
return chooseItems( validTargets, min );
|
||||
public List<Card> choosePermanentsToSacrifice(SpellAbility sa, int min, int max, List<Card> validTargets, String message) {
|
||||
return chooseItems(validTargets, min);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> choosePermanentsToDestroy( SpellAbility sa, int min, int max, List<Card> validTargets, String message ) {
|
||||
return chooseItems( validTargets, min );
|
||||
public List<Card> choosePermanentsToDestroy(SpellAbility sa, int min, int max, List<Card> validTargets, String message) {
|
||||
return chooseItems(validTargets, min);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetChoices chooseNewTargetsFor( SpellAbility ability ) {
|
||||
throw new IllegalStateException( "Erring on the side of caution here..." );
|
||||
public TargetChoices chooseNewTargetsFor(SpellAbility ability) {
|
||||
throw new IllegalStateException("Erring on the side of caution here...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<SpellAbilityStackInstance, GameObject> chooseTarget( SpellAbility sa, List<Pair<SpellAbilityStackInstance, GameObject>> allTargets ) {
|
||||
return chooseItem( allTargets );
|
||||
public Pair<SpellAbilityStackInstance, GameObject> chooseTarget(SpellAbility sa, List<Pair<SpellAbilityStackInstance, GameObject>> allTargets) {
|
||||
return chooseItem(allTargets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> chooseCardsForEffect( List<Card> sourceList, SpellAbility sa, String title, int amount, boolean isOptional ) {
|
||||
return chooseItems( sourceList, amount );
|
||||
public List<Card> chooseCardsForEffect(List<Card> sourceList, SpellAbility sa, String title, int amount, boolean isOptional) {
|
||||
return chooseItems(sourceList, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Card chooseSingleCardForEffect( Collection<Card> sourceList, SpellAbility sa, String title, boolean isOptional ) {
|
||||
return chooseItem( sourceList );
|
||||
public Card chooseSingleCardForEffect(Collection<Card> sourceList, SpellAbility sa, String title, boolean isOptional) {
|
||||
return chooseItem(sourceList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player chooseSinglePlayerForEffect( List<Player> options, SpellAbility sa, String title ) {
|
||||
return chooseItem( options );
|
||||
public Player chooseSinglePlayerForEffect(List<Player> options, SpellAbility sa, String title) {
|
||||
return chooseItem(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellAbility chooseSingleSpellForEffect( List<SpellAbility> spells, SpellAbility sa, String title ) {
|
||||
return chooseItem( spells );
|
||||
public SpellAbility chooseSingleSpellForEffect(List<SpellAbility> spells, SpellAbility sa, String title) {
|
||||
return chooseItem(spells);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean confirmAction( SpellAbility sa, PlayerActionConfirmMode mode, String message ) {
|
||||
public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getWillPlayOnFirstTurn( boolean isFirstGame ) {
|
||||
public boolean confirmStaticApplication(Card hostCard, GameEntity affected, String logic, String message) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean confirmStaticApplication( Card hostCard, GameEntity affected, String logic, String message ) {
|
||||
return true;
|
||||
}
|
||||
public boolean confirmTrigger(SpellAbility sa, Trigger regtrig, Map<String, String> triggerParams, boolean isMandatory) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getWillPlayOnFirstTurn(boolean isFirstGame) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> orderBlockers( Card attacker, List<Card> blockers ) {
|
||||
public List<Card> orderBlockers(Card attacker, List<Card> blockers) {
|
||||
return blockers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> orderAttackers( Card blocker, List<Card> attackers ) {
|
||||
public List<Card> orderAttackers(Card blocker, List<Card> attackers) {
|
||||
return attackers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reveal( String string, Collection<Card> cards, ZoneType zone, Player owner ) {
|
||||
public void reveal(String string, Collection<Card> cards, ZoneType zone, Player owner) {
|
||||
//nothing needs to be done here
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyOfValue( SpellAbility saSource, GameObject realtedTarget, String value ) {
|
||||
public void notifyOfValue(SpellAbility saSource, GameObject realtedTarget, String value) {
|
||||
//nothing needs to be done here
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutablePair<List<Card>, List<Card>> arrangeForScry( List<Card> topN ) {
|
||||
return ImmutablePair.of( topN, null );
|
||||
public ImmutablePair<List<Card>, List<Card>> arrangeForScry(List<Card> topN) {
|
||||
return ImmutablePair.of(topN, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willPutCardOnTop( Card c ) {
|
||||
public boolean willPutCardOnTop(Card c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> orderMoveToZoneList( List<Card> cards, ZoneType destinationZone ) {
|
||||
public List<Card> orderMoveToZoneList(List<Card> cards, ZoneType destinationZone) {
|
||||
return cards;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> chooseCardsToDiscardFrom( Player playerDiscard, SpellAbility sa, List<Card> validCards, int min, int max ) {
|
||||
return chooseItems( validCards, min );
|
||||
public List<Card> chooseCardsToDiscardFrom(Player playerDiscard, SpellAbility sa, List<Card> validCards, int min, int max) {
|
||||
return chooseItems(validCards, min);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Card chooseCardToDredge( List<Card> dredgers ) {
|
||||
public Card chooseCardToDredge(List<Card> dredgers) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playMiracle( SpellAbility miracle, Card card ) {
|
||||
throw new IllegalStateException( "Callers of this method currently assume that it performs extra functionality!" );
|
||||
public void playMiracle(SpellAbility miracle, Card card) {
|
||||
throw new IllegalStateException("Callers of this method currently assume that it performs extra functionality!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> chooseCardsToDelve( int colorLessAmount, List<Card> grave ) {
|
||||
public List<Card> chooseCardsToDelve(int colorLessAmount, List<Card> grave) {
|
||||
return Collections.<Card>emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> chooseCardsToRevealFromHand( int min, int max, List<Card> valid ) {
|
||||
return chooseItems( valid, min );
|
||||
public List<Card> chooseCardsToRevealFromHand(int min, int max, List<Card> valid) {
|
||||
return chooseItems(valid, min);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> chooseCardsToDiscardUnlessType( int min, List<Card> hand, String param, SpellAbility sa ) {
|
||||
throw new IllegalStateException( "Erring on the side of caution here..." );
|
||||
public List<Card> chooseCardsToDiscardUnlessType(int min, List<Card> hand, String param, SpellAbility sa) {
|
||||
throw new IllegalStateException("Erring on the side of caution here...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpellAbility> chooseSaToActivateFromOpeningHand( List<SpellAbility> usableFromOpeningHand ) {
|
||||
public List<SpellAbility> chooseSaToActivateFromOpeningHand(List<SpellAbility> usableFromOpeningHand) {
|
||||
return usableFromOpeningHand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mana chooseManaFromPool( List<Mana> manaChoices ) {
|
||||
return chooseItem( manaChoices );
|
||||
public Mana chooseManaFromPool(List<Mana> manaChoices) {
|
||||
return chooseItem(manaChoices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<CounterType, String> chooseAndRemoveOrPutCounter( Card cardWithCounter ) {
|
||||
throw new IllegalStateException( "Erring on the side of caution here..." );
|
||||
public Pair<CounterType, String> chooseAndRemoveOrPutCounter(Card cardWithCounter) {
|
||||
throw new IllegalStateException("Erring on the side of caution here...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean confirmReplacementEffect( ReplacementEffect replacementEffect, SpellAbility effectSA, String question ) {
|
||||
public boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, String question) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> getCardsToMulligan( boolean isCommander, Player firstPlayer ) {
|
||||
public List<Card> getCardsToMulligan(boolean isCommander, Player firstPlayer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void declareAttackers( Player attacker, Combat combat ) {
|
||||
public void declareAttackers(Player attacker, Combat combat) {
|
||||
//Doing nothing is safe in most cases, but not all (creatures that must attack etc). TODO: introduce checks?
|
||||
if( playerActions == null ) {
|
||||
if (playerActions == null) {
|
||||
return;
|
||||
}
|
||||
DeclareAttackersAction declareAttackers = playerActions.getNextActionIfApplicable( player, game, DeclareAttackersAction.class );
|
||||
if( declareAttackers == null ) {
|
||||
DeclareAttackersAction declareAttackers = playerActions.getNextActionIfApplicable(player, game, DeclareAttackersAction.class);
|
||||
if (declareAttackers == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -296,47 +302,47 @@ public class PlayerControllerForTests extends PlayerController {
|
||||
//TODO: check that the chosen attack configuration was a complete match to what was requested?
|
||||
//TODO: banding (don't really care at the moment...)
|
||||
|
||||
for( Map.Entry<CardSpecification, PlayerSpecification> playerAttackAssignment : declareAttackers.getPlayerAttackAssignments().entrySet() ) {
|
||||
Player defender = getPlayerBeingAttacked( game, player, playerAttackAssignment.getValue() );
|
||||
attack( combat, playerAttackAssignment.getKey(), defender );
|
||||
for (Map.Entry<CardSpecification, PlayerSpecification> playerAttackAssignment : declareAttackers.getPlayerAttackAssignments().entrySet()) {
|
||||
Player defender = getPlayerBeingAttacked(game, player, playerAttackAssignment.getValue());
|
||||
attack(combat, playerAttackAssignment.getKey(), defender);
|
||||
}
|
||||
for( Map.Entry<CardSpecification, CardSpecification> planeswalkerAttackAssignment: declareAttackers.getPlaneswalkerAttackAssignments().entrySet() ) {
|
||||
Card defender = CardSpecificationHandler.INSTANCE.find( game.getCardsInGame(), planeswalkerAttackAssignment.getKey() );
|
||||
attack( combat, planeswalkerAttackAssignment.getKey(), defender );
|
||||
for (Map.Entry<CardSpecification, CardSpecification> planeswalkerAttackAssignment: declareAttackers.getPlaneswalkerAttackAssignments().entrySet()) {
|
||||
Card defender = CardSpecificationHandler.INSTANCE.find(game.getCardsInGame(), planeswalkerAttackAssignment.getKey());
|
||||
attack(combat, planeswalkerAttackAssignment.getKey(), defender);
|
||||
}
|
||||
}
|
||||
|
||||
private Player getPlayerBeingAttacked( Game game, Player attacker, PlayerSpecification defenderSpecification ) {
|
||||
if( defenderSpecification != null ) {
|
||||
return PlayerSpecificationHandler.INSTANCE.find( game.getPlayers(), defenderSpecification );
|
||||
private Player getPlayerBeingAttacked(Game game, Player attacker, PlayerSpecification defenderSpecification) {
|
||||
if (defenderSpecification != null) {
|
||||
return PlayerSpecificationHandler.INSTANCE.find(game.getPlayers(), defenderSpecification);
|
||||
}
|
||||
if( game.getPlayers().size() != 2 ) {
|
||||
throw new IllegalStateException( "Can't use implicit defender specification in this situation!" );
|
||||
if (game.getPlayers().size() != 2) {
|
||||
throw new IllegalStateException("Can't use implicit defender specification in this situation!");
|
||||
}
|
||||
for( Player player : game.getPlayers() ) {
|
||||
if( !attacker.equals( player ) ) {
|
||||
for (Player player : game.getPlayers()) {
|
||||
if (!attacker.equals(player)) {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException( "Couldn't find implicit defender!" );
|
||||
throw new IllegalStateException("Couldn't find implicit defender!");
|
||||
}
|
||||
|
||||
private void attack( Combat combat, CardSpecification attackerSpecification, GameEntity defender ) {
|
||||
Card attacker = CardSpecificationHandler.INSTANCE.find( combat.getAttackingPlayer().getCreaturesInPlay(), attackerSpecification );
|
||||
if ( !CombatUtil.canAttack( attacker, defender, combat ) ) {
|
||||
throw new IllegalStateException( attacker + " can't attack " + defender );
|
||||
private void attack(Combat combat, CardSpecification attackerSpecification, GameEntity defender) {
|
||||
Card attacker = CardSpecificationHandler.INSTANCE.find(combat.getAttackingPlayer().getCreaturesInPlay(), attackerSpecification);
|
||||
if (!CombatUtil.canAttack(attacker, defender, combat)) {
|
||||
throw new IllegalStateException(attacker + " can't attack " + defender);
|
||||
}
|
||||
combat.addAttacker( attacker, defender );
|
||||
combat.addAttacker(attacker, defender);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void declareBlockers( Player defender, Combat combat ) {
|
||||
public void declareBlockers(Player defender, Combat combat) {
|
||||
//Doing nothing is safe in most cases, but not all (creatures that must block, attackers that must be blocked etc). TODO: legality checks?
|
||||
if( playerActions == null ) {
|
||||
if (playerActions == null) {
|
||||
return;
|
||||
}
|
||||
DeclareBlockersAction declareBlockers = playerActions.getNextActionIfApplicable( player, game, DeclareBlockersAction.class );
|
||||
if( declareBlockers == null ) {
|
||||
DeclareBlockersAction declareBlockers = playerActions.getNextActionIfApplicable(player, game, DeclareBlockersAction.class);
|
||||
if (declareBlockers == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -344,106 +350,106 @@ public class PlayerControllerForTests extends PlayerController {
|
||||
//TODO: check that the chosen block configuration was a 100% match to what was requested?
|
||||
//TODO: where do damage assignment orders get handled?
|
||||
|
||||
for( Map.Entry<CardSpecification, Collection<CardSpecification>> blockingAssignment : declareBlockers.getBlockingAssignments().asMap().entrySet() ) {
|
||||
Card attacker = CardSpecificationHandler.INSTANCE.find( combat.getAttackers(), blockingAssignment.getKey() );
|
||||
for( CardSpecification blockerSpecification : blockingAssignment.getValue() ) {
|
||||
Card blocker = CardSpecificationHandler.INSTANCE.find( game, blockerSpecification );
|
||||
if( !CombatUtil.canBlock( attacker, blocker ) ) {
|
||||
throw new IllegalStateException( blocker + " can't block " + blocker );
|
||||
for (Map.Entry<CardSpecification, Collection<CardSpecification>> blockingAssignment : declareBlockers.getBlockingAssignments().asMap().entrySet()) {
|
||||
Card attacker = CardSpecificationHandler.INSTANCE.find(combat.getAttackers(), blockingAssignment.getKey());
|
||||
for (CardSpecification blockerSpecification : blockingAssignment.getValue()) {
|
||||
Card blocker = CardSpecificationHandler.INSTANCE.find(game, blockerSpecification);
|
||||
if (!CombatUtil.canBlock(attacker, blocker)) {
|
||||
throw new IllegalStateException(blocker + " can't block " + blocker);
|
||||
}
|
||||
combat.addBlocker( attacker, blocker );
|
||||
combat.addBlocker(attacker, blocker);
|
||||
}
|
||||
}
|
||||
String blockValidation = CombatUtil.validateBlocks( combat, player );
|
||||
if( blockValidation != null ) {
|
||||
throw new IllegalStateException( blockValidation );
|
||||
String blockValidation = CombatUtil.validateBlocks(combat, player);
|
||||
if (blockValidation != null) {
|
||||
throw new IllegalStateException(blockValidation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void takePriority() {
|
||||
//TODO: just about everything...
|
||||
if( playerActions != null ) {
|
||||
CastSpellFromHandAction castSpellFromHand = playerActions.getNextActionIfApplicable( player, game, CastSpellFromHandAction.class );
|
||||
if( castSpellFromHand != null ) {
|
||||
castSpellFromHand.castSpellFromHand( player, game );
|
||||
if (playerActions != null) {
|
||||
CastSpellFromHandAction castSpellFromHand = playerActions.getNextActionIfApplicable(player, game, CastSpellFromHandAction.class);
|
||||
if (castSpellFromHand != null) {
|
||||
castSpellFromHand.castSpellFromHand(player, game);
|
||||
}
|
||||
|
||||
ActivateAbilityAction activateAbilityAction = playerActions.getNextActionIfApplicable( player, game, ActivateAbilityAction.class );
|
||||
if( activateAbilityAction != null ) {
|
||||
activateAbilityAction.activateAbility( player, game );
|
||||
ActivateAbilityAction activateAbilityAction = playerActions.getNextActionIfApplicable(player, game, ActivateAbilityAction.class);
|
||||
if (activateAbilityAction != null) {
|
||||
activateAbilityAction.activateAbility(player, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> chooseCardsToDiscardToMaximumHandSize( int numDiscard ) {
|
||||
return chooseItems( player.getZone( ZoneType.Hand ).getCards(), numDiscard );
|
||||
public List<Card> chooseCardsToDiscardToMaximumHandSize(int numDiscard) {
|
||||
return chooseItems(player.getZone(ZoneType.Hand).getCards(), numDiscard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean payManaOptional( Card card, Cost cost, SpellAbility sa, String prompt, ManaPaymentPurpose purpose ) {
|
||||
throw new IllegalStateException( "Callers of this method currently assume that it performs extra functionality!" );
|
||||
public boolean payManaOptional(Card card, Cost cost, SpellAbility sa, String prompt, ManaPaymentPurpose purpose) {
|
||||
throw new IllegalStateException("Callers of this method currently assume that it performs extra functionality!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int chooseNumber( SpellAbility sa, String title, int min, int max ) {
|
||||
public int chooseNumber(SpellAbility sa, String title, int min, int max) {
|
||||
return min;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean chooseBinary( SpellAbility sa, String question, BinaryChoiceType kindOfChoice ) {
|
||||
public boolean chooseBinary(SpellAbility sa, String question, BinaryChoiceType kindOfChoice) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean chooseFlipResult( SpellAbility sa, Player flipper, boolean[] results, boolean call ) {
|
||||
public boolean chooseFlipResult(SpellAbility sa, Player flipper, boolean[] results, boolean call) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Card chooseProtectionShield( GameEntity entityBeingDamaged, List<String> options, Map<String, Card> choiceMap ) {
|
||||
return choiceMap.get( options.get( 0 ) );
|
||||
public Card chooseProtectionShield(GameEntity entityBeingDamaged, List<String> options, Map<String, Card> choiceMap) {
|
||||
return choiceMap.get(options.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AbilitySub> chooseModeForAbility( SpellAbility sa, int min, int num ) {
|
||||
throw new IllegalStateException( "Erring on the side of caution here..." );
|
||||
public List<AbilitySub> chooseModeForAbility(SpellAbility sa, int min, int num) {
|
||||
throw new IllegalStateException("Erring on the side of caution here...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte chooseColor( String message, SpellAbility sa, ColorSet colors ) {
|
||||
public byte chooseColor(String message, SpellAbility sa, ColorSet colors) {
|
||||
return Iterables.getFirst(colors, MagicColor.WHITE);
|
||||
}
|
||||
|
||||
private <T> List<T> chooseItems( Collection<T> items, int amount ) {
|
||||
if( items == null || items.isEmpty() ) {
|
||||
return new ArrayList<T>( items );
|
||||
private <T> List<T> chooseItems(Collection<T> items, int amount) {
|
||||
if (items == null || items.isEmpty()) {
|
||||
return new ArrayList<T>(items);
|
||||
}
|
||||
return new ArrayList<T>( items ).subList( 0, Math.max( amount, items.size() ) );
|
||||
return new ArrayList<T>(items).subList(0, Math.max(amount, items.size()));
|
||||
}
|
||||
|
||||
private <T> T chooseItem( Collection<T> items ) {
|
||||
if( items == null || items.isEmpty() ) {
|
||||
private <T> T chooseItem(Collection<T> items) {
|
||||
if (items == null || items.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return Iterables.getFirst( items, null );
|
||||
return Iterables.getFirst(items, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellAbility getAbilityToPlay( List<SpellAbility> abilities, MouseEvent triggerEvent ) {
|
||||
return getAbilityToPlay( abilities );
|
||||
public SpellAbility getAbilityToPlay(List<SpellAbility> abilities, MouseEvent triggerEvent) {
|
||||
return getAbilityToPlay(abilities);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String chooseSomeType( String kindOfType, SpellAbility sa, List<String> validTypes, List<String> invalidTypes ) {
|
||||
return chooseItem( validTypes );
|
||||
public String chooseSomeType(String kindOfType, SpellAbility sa, List<String> validTypes, List<String> invalidTypes) {
|
||||
return chooseItem(validTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaperCard chooseSinglePaperCard( SpellAbility sa, String message, Predicate<PaperCard> cpp, String name ) {
|
||||
throw new IllegalStateException( "Erring on the side of caution here..." );
|
||||
public PaperCard chooseSinglePaperCard(SpellAbility sa, String message, Predicate<PaperCard> cpp, String name) {
|
||||
throw new IllegalStateException("Erring on the side of caution here...");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user