@Override public void resolve(SpellAbility sa) { final int numTurns = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("NumTurns"), sa); List<Player> tgtPlayers = getTargetPlayers(sa); for (final Player p : tgtPlayers) { if ((sa.getTargetRestrictions() == null) || p.canBeTargetedBy(sa)) { for (int i = 0; i < numTurns; i++) { ExtraTurn extra = p.getGame().getPhaseHandler().addExtraTurn(p); if (sa.hasParam("LoseAtEndStep")) { extra.setLoseAtEndStep(true); } if (sa.hasParam("SkipUntap")) { extra.setSkipUntap(true); } if (sa.hasParam("NoSchemes")) { extra.setCantSetSchemesInMotion(true); } if (sa.hasParam("ShowMessage")) { p.getGame().getAction().nofityOfValue(sa, p, p + " takes an extra turn.", null); } } } } }
@Override public void resolve(SpellAbility sa) { final Card host = sa.getHostCard(); final String[] choices = sa.getParam("Choices").split(","); final List<SpellAbility> abilities = new ArrayList<SpellAbility>(); for (String s : choices) { abilities.add(AbilityFactory.getAbility(host.getSVar(s), host)); } final List<Player> tgtPlayers = getDefinedPlayersOrTargeted(sa); final TargetRestrictions tgt = sa.getTargetRestrictions(); for (final Player p : tgtPlayers) { if (tgt != null && !p.canBeTargetedBy(sa)) { continue; } int idxChosen = 0; String chosenName; if (sa.hasParam("AtRandom")) { idxChosen = MyRandom.getRandom().nextInt(choices.length); chosenName = choices[idxChosen]; } else { SpellAbility saChosen = p.getController().chooseSingleSpellForEffect(abilities, sa, "Choose one"); idxChosen = abilities.indexOf(saChosen); chosenName = choices[idxChosen]; } SpellAbility chosenSA = AbilityFactory.getAbility(host.getSVar(chosenName), host); if (sa.hasParam("ShowChoice")) { p.getGame() .getAction() .nofityOfValue(sa, p, abilities.get(idxChosen).getDescription(), null); } chosenSA.setActivatingPlayer(sa.getActivatingPlayer()); ((AbilitySub) chosenSA).setParent(sa); AbilityUtils.resolve(chosenSA); } }
protected boolean revealHandTargetAI(final Player ai, final SpellAbility sa) { final TargetRestrictions tgt = sa.getTargetRestrictions(); Player opp = ai.getOpponent(); final int humanHandSize = opp.getCardsIn(ZoneType.Hand).size(); if (tgt != null) { // ability is targeted sa.resetTargets(); final boolean canTgtHuman = opp.canBeTargetedBy(sa); if (!canTgtHuman || (humanHandSize == 0)) { return false; } else { sa.getTargets().add(opp); } } else { // if it's just defined, no big deal } return true; } // revealHandTargetAI()
@Override public void resolve(SpellAbility sa) { final Card card = sa.getHostCard(); AbilityManaPart abMana = sa.getManaPart(); // Spells are not undoable sa.setUndoable(sa.isAbility() && sa.isUndoable()); final List<Player> tgtPlayers = getTargetPlayers(sa); final TargetRestrictions tgt = sa.getTargetRestrictions(); final boolean optional = sa.hasParam("Optional"); final Game game = sa.getActivatingPlayer().getGame(); if (optional && !sa.getActivatingPlayer() .getController() .confirmAction(sa, null, "Do you want to add mana to your mana pool?")) { return; } if (abMana.isComboMana()) { for (Player p : tgtPlayers) { int amount = sa.hasParam("Amount") ? AbilityUtils.calculateAmount(card, sa.getParam("Amount"), sa) : 1; if (tgt == null || p.canBeTargetedBy(sa)) { Player activator = sa.getActivatingPlayer(); // String colorsNeeded = abMana.getExpressChoice(); String[] colorsProduced = abMana.getComboColors().split(" "); final StringBuilder choiceString = new StringBuilder(); ColorSet colorOptions = null; if (!abMana.isAnyMana()) { colorOptions = ColorSet.fromNames(colorsProduced); } else { colorOptions = ColorSet.fromNames(MagicColor.Constant.ONLY_COLORS); } for (int nMana = 1; nMana <= amount; nMana++) { String choice = ""; byte chosenColor = activator.getController().chooseColor("Select Mana to Produce", sa, colorOptions); if (chosenColor == 0) throw new RuntimeException( "ManaEffect::resolve() /*combo mana*/ - " + activator + " color mana choice is empty for " + card.getName()); choice = MagicColor.toShortString(chosenColor); if (nMana != 1) { choiceString.append(" "); } choiceString.append(choice); } game.action.nofityOfValue(sa, card, activator + " picked " + choiceString, activator); abMana.setExpressChoice(choiceString.toString()); } } } else if (abMana.isAnyMana()) { for (Player p : tgtPlayers) { if (tgt == null || p.canBeTargetedBy(sa)) { Player act = sa.getActivatingPlayer(); // AI color choice is set in ComputerUtils so only human players need to make a choice String colorsNeeded = abMana.getExpressChoice(); String choice = ""; ColorSet colorMenu = null; byte mask = 0; // loop through colors to make menu for (int nChar = 0; nChar < colorsNeeded.length(); nChar++) { mask |= MagicColor.fromName(colorsNeeded.charAt(nChar)); } colorMenu = mask == 0 ? ColorSet.ALL_COLORS : ColorSet.fromMask(mask); byte val = act.getController().chooseColor("Select Mana to Produce", sa, colorMenu); if (0 == val) { throw new RuntimeException( "ManaEffect::resolve() /*any mana*/ - " + act + " color mana choice is empty for " + card.getName()); } choice = MagicColor.toShortString(val); game.action.nofityOfValue(sa, card, act + " picked " + choice, act); abMana.setExpressChoice(choice); } } } else if (abMana.isSpecialMana()) { for (Player p : tgtPlayers) { if (tgt == null || p.canBeTargetedBy(sa)) { String type = abMana.getOrigProduced().split("Special ")[1]; if (type.equals("EnchantedManaCost")) { Card enchanted = card.getEnchantingCard(); if (enchanted == null) continue; StringBuilder sb = new StringBuilder(); int generic = enchanted.getManaCost().getGenericCost(); if (generic > 0) sb.append(generic); for (ManaCostShard s : enchanted.getManaCost()) { ColorSet cs = ColorSet.fromMask(s.getColorMask()); if (cs.isColorless()) continue; sb.append(' '); if (cs.isMonoColor()) sb.append(MagicColor.toShortString(s.getColorMask())); else /* (cs.isMulticolor()) */ { byte chosenColor = sa.getActivatingPlayer() .getController() .chooseColor("Choose a single color from " + s.toString(), sa, cs); sb.append(MagicColor.toShortString(chosenColor)); } } abMana.setExpressChoice(sb.toString().trim()); } else if (type.equals("LastNotedType")) { Mana manaType = (Mana) Iterables.getFirst(card.getRemembered(), null); if (manaType == null) { return; } String cs = manaType.toString(); abMana.setExpressChoice(cs); } if (abMana.getExpressChoice().isEmpty()) { System.out.println( "AbilityFactoryMana::manaResolve() - special mana effect is empty for " + sa.getHostCard().getName()); } } } } for (final Player player : tgtPlayers) { abMana.produceMana(GameActionUtil.generatedMana(sa), player, sa); } // Only clear express choice after mana has been produced abMana.clearExpressChoice(); // resolveDrawback(sa); }
private boolean sacrificeTgtAI(final Player ai, final SpellAbility sa) { final Card source = sa.getHostCard(); final TargetRestrictions tgt = sa.getTargetRestrictions(); final boolean destroy = sa.hasParam("Destroy"); Player opp = ai.getOpponent(); if (tgt != null) { sa.resetTargets(); if (!opp.canBeTargetedBy(sa)) { return false; } sa.getTargets().add(opp); final String valid = sa.getParam("SacValid"); String num = sa.getParam("Amount"); num = (num == null) ? "1" : num; final int amount = AbilityUtils.calculateAmount(sa.getHostCard(), num, sa); List<Card> list = CardLists.getValidCards( ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getHostCard()); for (Card c : list) { if (c.hasSVar("SacMe") && Integer.parseInt(c.getSVar("SacMe")) > 3) { return false; } } if (!destroy) { list = CardLists.filter(list, CardPredicates.canBeSacrificedBy(sa)); } else { if (!CardLists.getKeyword(list, "Indestructible").isEmpty()) { // human can choose to destroy indestructibles return false; } } if (list.isEmpty()) { return false; } if (num.equals("X") && source.getSVar(num).equals("Count$xPaid")) { // Set PayX here to maximum value. final int xPay = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), amount); source.setSVar("PayX", Integer.toString(xPay)); } final int half = (amount / 2) + (amount % 2); // Half of amount // rounded up // If the Human has at least half rounded up of the amount to be // sacrificed, cast the spell if (!sa.isTrigger() && list.size() < half) { return false; } } final String defined = sa.getParam("Defined"); final String valid = sa.getParam("SacValid"); if (defined == null) { // Self Sacrifice. } else if (defined.equals("Each") || (defined.equals("Opponent") && !sa.isTrigger())) { // If Sacrifice hits both players: // Only cast it if Human has the full amount of valid // Only cast it if AI doesn't have the full amount of Valid // TODO: Cast if the type is favorable: my "worst" valid is // worse than his "worst" valid final String num = sa.hasParam("Amount") ? sa.getParam("Amount") : "1"; int amount = AbilityUtils.calculateAmount(source, num, sa); if (num.equals("X") && source.getSVar(num).equals("Count$xPaid")) { // Set PayX here to maximum value. amount = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), amount); } List<Card> humanList = CardLists.getValidCards( opp.getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getHostCard()); // Since all of the cards have remAIDeck:True, I enabled 1 for 1 // (or X for X) trades for special decks if (humanList.size() < amount) { return false; } } else if (defined.equals("You")) { List<Card> computerList = CardLists.getValidCards( ai.getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getHostCard()); for (Card c : computerList) { if (c.hasSVar("SacMe") || ComputerUtilCard.evaluateCreature(c) <= 135) { return true; } } return false; } return true; }
@Override public void resolve(SpellAbility sa) { final Card host = sa.getHostCard(); final Player player = sa.getActivatingPlayer(); final Game game = player.getGame(); Player chooser = player; int numToDig = AbilityUtils.calculateAmount(host, sa.getParam("DigNum"), sa); final ZoneType srcZone = sa.hasParam("SourceZone") ? ZoneType.smartValueOf(sa.getParam("SourceZone")) : ZoneType.Library; final ZoneType destZone1 = sa.hasParam("DestinationZone") ? ZoneType.smartValueOf(sa.getParam("DestinationZone")) : ZoneType.Hand; final ZoneType destZone2 = sa.hasParam("DestinationZone2") ? ZoneType.smartValueOf(sa.getParam("DestinationZone2")) : ZoneType.Library; int libraryPosition = sa.hasParam("LibraryPosition") ? Integer.parseInt(sa.getParam("LibraryPosition")) : -1; int destZone1ChangeNum = 1; final boolean mitosis = sa.hasParam("Mitosis"); String changeValid = sa.hasParam("ChangeValid") ? sa.getParam("ChangeValid") : ""; // andOrValid is for cards with "creature card and/or a land card" String andOrValid = sa.hasParam("AndOrValid") ? sa.getParam("AndOrValid") : ""; final boolean anyNumber = sa.hasParam("AnyNumber"); final int libraryPosition2 = sa.hasParam("LibraryPosition2") ? Integer.parseInt(sa.getParam("LibraryPosition2")) : -1; final boolean optional = sa.hasParam("Optional"); final boolean noMove = sa.hasParam("NoMove"); final boolean skipReorder = sa.hasParam("SkipReorder"); // A hack for cards like Explorer's Scope that need to ensure that a card is revealed to the // player activating the ability final boolean forceRevealToController = sa.hasParam("ForceRevealToController"); // These parameters are used to indicate that a dialog box must be show to the player asking if // the player wants to proceed // with an optional ability, otherwise the optional ability is skipped. final boolean mayBeSkipped = sa.hasParam("PromptToSkipOptionalAbility"); final String optionalAbilityPrompt = sa.hasParam("OptionalAbilityPrompt") ? sa.getParam("OptionalAbilityPrompt") : ""; boolean changeAll = false; boolean allButOne = false; final List<String> keywords = new ArrayList<String>(); if (sa.hasParam("Keywords")) { keywords.addAll(Arrays.asList(sa.getParam("Keywords").split(" & "))); } if (sa.hasParam("ChangeNum")) { if (sa.getParam("ChangeNum").equalsIgnoreCase("All")) { changeAll = true; } else if (sa.getParam("ChangeNum").equalsIgnoreCase("AllButOne")) { allButOne = true; } else { destZone1ChangeNum = AbilityUtils.calculateAmount(host, sa.getParam("ChangeNum"), sa); } } final TargetRestrictions tgt = sa.getTargetRestrictions(); final List<Player> tgtPlayers = getTargetPlayers(sa); if (sa.hasParam("Choser")) { final List<Player> choosers = AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Choser"), sa); if (!choosers.isEmpty()) { chooser = choosers.get(0); } } for (final Player p : tgtPlayers) { if (tgt != null && !p.canBeTargetedBy(sa)) { continue; } final CardCollection top = new CardCollection(); final CardCollection rest = new CardCollection(); final PlayerZone sourceZone = p.getZone(srcZone); numToDig = Math.min(numToDig, sourceZone.size()); for (int i = 0; i < numToDig; i++) { top.add(sourceZone.get(i)); } if (!top.isEmpty()) { DelayedReveal delayedReveal = null; boolean hasRevealed = true; if (sa.hasParam("Reveal")) { game.getAction().reveal(top, p, false); } else if (sa.hasParam("RevealOptional")) { String question = "Reveal: " + Lang.joinHomogenous(top) + "?"; hasRevealed = p.getController().confirmAction(sa, null, question); if (hasRevealed) { game.getAction().reveal(top, p); } } else if (sa.hasParam("RevealValid")) { final String revealValid = sa.getParam("RevealValid"); final CardCollection toReveal = CardLists.getValidCards(top, revealValid, host.getController(), host); if (!toReveal.isEmpty()) { game.getAction().reveal(toReveal, host.getController()); if (sa.hasParam("RememberRevealed")) { for (final Card one : toReveal) { host.addRemembered(one); } } } // Singletons.getModel().getGameAction().revealToCopmuter(top.toArray()); // - for when it exists } else if (!sa.hasParam("NoLooking")) { // show the user the revealed cards delayedReveal = new DelayedReveal(top, srcZone, PlayerView.get(p)); if (noMove) { // Let the activating player see the cards even if they're not moved game.getAction().revealTo(top, player); } } if (sa.hasParam("RememberRevealed") && !sa.hasParam("RevealValid") && hasRevealed) { for (final Card one : top) { host.addRemembered(one); } } if (!noMove) { CardCollection movedCards; CardCollection andOrCards; for (final Card c : top) { rest.add(c); } CardCollection valid; if (mitosis) { valid = sharesNameWithCardOnBattlefield(game, top); andOrCards = new CardCollection(); } else if (!changeValid.isEmpty()) { if (changeValid.contains("ChosenType")) { changeValid = changeValid.replace("ChosenType", host.getChosenType()); } valid = CardLists.getValidCards(top, changeValid.split(","), host.getController(), host); if (!andOrValid.equals("")) { andOrCards = CardLists.getValidCards(top, andOrValid.split(","), host.getController(), host); andOrCards.removeAll((Collection<?>) valid); valid.addAll(andOrCards); } else { andOrCards = new CardCollection(); } } else { valid = top; andOrCards = new CardCollection(); } if (forceRevealToController) { // Force revealing the card to the player activating the ability (e.g. Explorer's Scope) game.getAction().revealTo(top, player); } // Optional abilities that use a dialog box to prompt the user to skip the ability (e.g. // Explorer's Scope, Quest for Ula's Temple) if (optional && mayBeSkipped && !valid.isEmpty()) { String prompt = !optionalAbilityPrompt.isEmpty() ? optionalAbilityPrompt : "Would you like to proceed with the optional ability for " + sa.getHostCard() + "?\n\n(" + sa.getDescription() + ")"; if (!p.getController() .confirmAction(sa, null, prompt.replace("CARDNAME", sa.getHostCard().getName()))) { return; } } if (changeAll) { movedCards = new CardCollection(valid); } else if (sa.hasParam("RandomChange")) { int numChanging = Math.min(destZone1ChangeNum, valid.size()); movedCards = CardLists.getRandomSubList(valid, numChanging); } else if (allButOne) { movedCards = new CardCollection(valid); String prompt; if (destZone2.equals(ZoneType.Library) && libraryPosition2 == 0) { prompt = "Choose a card to leave on top of {player's} library"; } else { prompt = "Choose a card to leave in {player's} " + destZone2.name(); } Card chosen = chooser .getController() .chooseSingleEntityForEffect(valid, delayedReveal, sa, prompt, false, p); movedCards.remove(chosen); if (sa.hasParam("RandomOrder")) { CardLists.shuffle(movedCards); } } else { int j = 0; String prompt; if (sa.hasParam("PrimaryPrompt")) { prompt = sa.getParam("PrimaryPrompt"); } else { prompt = "Choose a card to put into " + destZone1.name(); if (destZone1.equals(ZoneType.Library)) { if (libraryPosition == -1) { prompt = "Choose a card to put on the bottom of {player's} library"; } else if (libraryPosition == 0) { prompt = "Choose a card to put on top of {player's} library"; } } } movedCards = new CardCollection(); while (j < destZone1ChangeNum || (anyNumber && j < numToDig)) { // let user get choice Card chosen = null; if (!valid.isEmpty()) { chosen = chooser .getController() .chooseSingleEntityForEffect( valid, delayedReveal, sa, prompt, anyNumber || optional, p); } else { chooser.getController().notifyOfValue(sa, null, "No valid cards"); } if (chosen == null) { break; } movedCards.add(chosen); valid.remove(chosen); if (!andOrValid.equals("")) { andOrCards.remove(chosen); if (!chosen.isValid(andOrValid.split(","), host.getController(), host)) { valid = new CardCollection(andOrCards); } else if (!chosen.isValid(changeValid.split(","), host.getController(), host)) { valid.removeAll((Collection<?>) andOrCards); } } j++; } if (!changeValid.isEmpty()) { game.getAction() .reveal( movedCards, chooser, true, chooser + " picked " + (movedCards.size() == 1 ? "this card" : "these cards") + " from "); } } if (sa.hasParam("ForgetOtherRemembered")) { host.clearRemembered(); } Collections.reverse(movedCards); for (Card c : movedCards) { final PlayerZone zone = c.getOwner().getZone(destZone1); if (zone.is(ZoneType.Library) || zone.is(ZoneType.PlanarDeck) || zone.is(ZoneType.SchemeDeck)) { if (libraryPosition == -1 || libraryPosition > zone.size()) { libraryPosition = zone.size(); } c = game.getAction().moveTo(zone, c, libraryPosition); } else { c = game.getAction().moveTo(zone, c); if (destZone1.equals(ZoneType.Battlefield)) { for (final String kw : keywords) { c.addExtrinsicKeyword(kw); } if (sa.hasParam("Tapped")) { c.setTapped(true); } } } if (sa.hasParam("ExileFaceDown")) { c.setState(CardStateName.FaceDown, true); } if (sa.hasParam("Imprint")) { host.addImprintedCard(c); } if (sa.hasParam("ForgetOtherRemembered")) { host.clearRemembered(); } if (sa.hasParam("RememberChanged")) { host.addRemembered(c); } rest.remove(c); } // now, move the rest to destZone2 if (destZone2 == ZoneType.Library || destZone2 == ZoneType.PlanarDeck || destZone2 == ZoneType.SchemeDeck) { CardCollection afterOrder = rest; if (sa.hasParam("RestRandomOrder")) { CardLists.shuffle(afterOrder); } else if (!skipReorder && rest.size() > 1) { afterOrder = (CardCollection) chooser.getController().orderMoveToZoneList(rest, destZone2); } if (libraryPosition2 != -1) { // Closest to top Collections.reverse(afterOrder); } for (final Card c : afterOrder) { if (destZone2 == ZoneType.Library) { game.getAction().moveToLibrary(c, libraryPosition2); } else { game.getAction().moveToVariantDeck(c, destZone2, libraryPosition2); } } } else { // just move them randomly for (int i = 0; i < rest.size(); i++) { Card c = rest.get(i); final PlayerZone toZone = c.getOwner().getZone(destZone2); c = game.getAction().moveTo(toZone, c); if (destZone2.equals(ZoneType.Battlefield) && !keywords.isEmpty()) { for (final String kw : keywords) { c.addExtrinsicKeyword(kw); } } } } } } } }
@Override public void resolve(SpellAbility sa) { final Card card = sa.getHostCard(); // final int min = sa.containsKey("Min") ? Integer.parseInt(sa.get("Min")) : 0; // final int max = sa.containsKey("Max") ? Integer.parseInt(sa.get("Max")) : 99; final boolean random = sa.hasParam("Random"); final boolean anyNumber = sa.hasParam("ChooseAnyNumber"); final boolean secretlyChoose = sa.hasParam("SecretlyChoose"); final String sMin = sa.getParamOrDefault("Min", "0"); final int min = AbilityUtils.calculateAmount(card, sMin, sa); final String sMax = sa.getParamOrDefault("Max", "99"); final int max = AbilityUtils.calculateAmount(card, sMax, sa); final List<Player> tgtPlayers = getTargetPlayers(sa); final TargetRestrictions tgt = sa.getTargetRestrictions(); final Map<Player, Integer> chooseMap = new HashMap<Player, Integer>(); for (final Player p : tgtPlayers) { if ((tgt == null) || p.canBeTargetedBy(sa)) { int chosen; if (random) { final Random randomGen = new Random(); chosen = randomGen.nextInt(max - min) + min; p.getGame().getAction().nofityOfValue(sa, p, Integer.toString(chosen), null); } else { String title = sa.hasParam("ListTitle") ? sa.getParam("ListTitle") : "Choose a number"; if (anyNumber) { chosen = p.getController().announceRequirements(sa, title, true); } else { chosen = p.getController().chooseNumber(sa, title, min, max); } // don't notify here, because most scripts I've seen don't store that number in a long // term } if (secretlyChoose) { chooseMap.put(p, chosen); } else { card.setChosenNumber(chosen); } if (sa.hasParam("Notify")) { p.getGame().getAction().nofityOfValue(sa, card, p.getName() + " picked " + chosen, p); } } } if (secretlyChoose) { StringBuilder sb = new StringBuilder(); List<Player> highestNum = new ArrayList<Player>(); List<Player> lowestNum = new ArrayList<Player>(); int highest = 0; int lowest = Integer.MAX_VALUE; for (Entry<Player, Integer> ev : chooseMap.entrySet()) { int num = ev.getValue(); Player player = ev.getKey(); sb.append(player).append(" chose ").append(num); sb.append("\r\n"); if (num > highest) { highestNum.clear(); highest = num; } if (num == highest) { highestNum.add(player); } if (num < lowest) { lowestNum.clear(); lowest = num; } if (num == lowest) { lowestNum.add(player); } } card.getGame().getAction().nofityOfValue(sa, card, sb.toString(), null); if (sa.hasParam("ChooseNumberSubAbility")) { SpellAbility sub = AbilityFactory.getAbility(card.getSVar(sa.getParam("ChooseNumberSubAbility")), card); sub.setActivatingPlayer(sa.getActivatingPlayer()); ((AbilitySub) sub).setParent(sa); for (Player p : chooseMap.keySet()) { card.addRemembered(p); card.setChosenNumber(chooseMap.get(p)); AbilityUtils.resolve(sub); card.clearRemembered(); } } if (sa.hasParam("Lowest")) { SpellAbility action = AbilityFactory.getAbility(card.getSVar(sa.getParam("Lowest")), card); action.setActivatingPlayer(sa.getActivatingPlayer()); ((AbilitySub) action).setParent(sa); for (Player p : lowestNum) { card.addRemembered(p); card.setChosenNumber(lowest); AbilityUtils.resolve(action); card.clearRemembered(); } } if (sa.hasParam("Highest")) { SpellAbility action = AbilityFactory.getAbility(card.getSVar(sa.getParam("Highest")), card); action.setActivatingPlayer(sa.getActivatingPlayer()); ((AbilitySub) action).setParent(sa); for (Player p : highestNum) { card.addRemembered(p); card.setChosenNumber(highest); AbilityUtils.resolve(action); card.clearRemembered(); } if (sa.hasParam("RememberHighest")) { card.addRemembered(highestNum); } } } }
/* (non-Javadoc) * @see forge.card.abilityfactory.SpellEffect#resolve(java.util.Map, forge.card.spellability.SpellAbility) */ @Override public void resolve(SpellAbility sa) { Card host = sa.getHostCard(); int numDam = AbilityUtils.calculateAmount(host, sa.getParam("Amount"), sa); final List<GameObject> tgts = getTargets(sa); final List<Card> untargetedCards = new ArrayList<Card>(); if (sa.hasParam("Radiance") && (sa.usesTargeting())) { Card origin = null; for (int i = 0; i < tgts.size(); i++) { if (tgts.get(i) instanceof Card) { origin = (Card) tgts.get(i); break; } } if (origin != null) { // Can't radiate from a player for (final Card c : CardUtil.getRadiance(host, origin, sa.getParam("ValidTgts").split(","))) { untargetedCards.add(c); } } } final boolean targeted = (sa.usesTargeting()); final boolean preventionWithEffect = sa.hasParam("PreventionSubAbility"); for (final Object o : tgts) { numDam = (sa.usesTargeting() && sa.hasParam("DividedAsYouChoose")) ? sa.getTargetRestrictions().getDividedValue(o) : numDam; if (o instanceof Card) { final Card c = (Card) o; if (c.isInPlay() && (!targeted || c.canBeTargetedBy(sa))) { if (preventionWithEffect) { Map<String, String> effectMap = new TreeMap<String, String>(); effectMap.put("EffectString", sa.getSVar(sa.getParam("PreventionSubAbility"))); effectMap.put("ShieldAmount", String.valueOf(numDam)); if (sa.hasParam("ShieldEffectTarget")) { String effTgtString = ""; List<GameObject> effTgts = new ArrayList<GameObject>(); effTgts = AbilityUtils.getDefinedObjects(host, sa.getParam("ShieldEffectTarget"), sa); for (final Object effTgt : effTgts) { if (effTgt instanceof Card) { effTgtString = String.valueOf(((Card) effTgt).getId()); effectMap.put("ShieldEffectTarget", "CardUID_" + effTgtString); } else if (effTgt instanceof Player) { effTgtString = ((Player) effTgt).getName(); effectMap.put("ShieldEffectTarget", "PlayerNamed_" + effTgtString); } } } c.addPreventNextDamageWithEffect(host, effectMap); } else { c.addPreventNextDamage(numDam); } } } else if (o instanceof Player) { final Player p = (Player) o; if (!targeted || p.canBeTargetedBy(sa)) { if (preventionWithEffect) { Map<String, String> effectMap = new TreeMap<String, String>(); effectMap.put("EffectString", sa.getSVar(sa.getParam("PreventionSubAbility"))); effectMap.put("ShieldAmount", String.valueOf(numDam)); if (sa.hasParam("ShieldEffectTarget")) { String effTgtString = ""; List<GameObject> effTgts = new ArrayList<GameObject>(); effTgts = AbilityUtils.getDefinedObjects(host, sa.getParam("ShieldEffectTarget"), sa); for (final Object effTgt : effTgts) { if (effTgt instanceof Card) { effTgtString = String.valueOf(((Card) effTgt).getId()); effectMap.put("ShieldEffectTarget", "CardUID_" + effTgtString); } else if (effTgt instanceof Player) { effTgtString = ((Player) effTgt).getName(); effectMap.put("ShieldEffectTarget", "PlayerNamed_" + effTgtString); } } } p.addPreventNextDamageWithEffect(host, effectMap); } else { p.addPreventNextDamage(numDam); } } } } for (final Card c : untargetedCards) { if (c.isInPlay()) { c.addPreventNextDamage(numDam); } } } // preventDamageResolve