private Card chooseCardOnStack(SpellAbility sa, Player ai, Game game) { for (SpellAbilityStackInstance si : game.getStack()) { final Card source = si.getSourceCard(); final SpellAbility abilityOnStack = si.getSpellAbility(true); if (sa.hasParam("Choices") && !abilityOnStack.getHostCard().isValid(sa.getParam("Choices"), ai, sa.getHostCard())) { continue; } final ApiType threatApi = abilityOnStack.getApi(); if (threatApi != ApiType.DealDamage && threatApi != ApiType.DamageAll) { continue; } List<? extends GameObject> objects = getTargets(abilityOnStack); if (!abilityOnStack.usesTargeting() && !abilityOnStack.hasParam("Defined") && abilityOnStack.hasParam("ValidPlayers")) objects = AbilityUtils.getDefinedPlayers( source, abilityOnStack.getParam("ValidPlayers"), abilityOnStack); if (!objects.contains(ai) || abilityOnStack.hasParam("NoPrevention")) { continue; } int dmg = AbilityUtils.calculateAmount(source, abilityOnStack.getParam("NumDmg"), abilityOnStack); if (ComputerUtilCombat.predictDamageTo(ai, dmg, source, false) <= 0) { continue; } return source; } return null; }
@Override public PaymentDecision visit(CostExileFromStack cost) { Integer c = cost.convertAmount(); if (c == null) { final String sVar = ability.getSVar(cost.getAmount()); // Generalize cost if (sVar.equals("XChoice")) { return null; } c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability); } List<SpellAbility> chosen = new ArrayList<SpellAbility>(); for (SpellAbilityStackInstance si : source.getGame().getStack()) { SpellAbility sp = si.getSpellAbility().getRootAbility(); if (si.getSourceCard().isValid(cost.getType().split(";"), source.getController(), source)) { chosen.add(sp); } } return chosen.isEmpty() ? null : PaymentDecision.spellabilities(chosen); }