예제 #1
0
  @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);
          }
        }
      }
    }
  }
예제 #2
0
  @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);
    }
  }
예제 #3
0
  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()
예제 #4
0
  @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);
  }
예제 #5
0
  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;
  }
예제 #6
0
  @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);
        }
      }
    }
  }
예제 #8
0
  /* (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