Example #1
0
  private boolean pumpMandatoryTarget(
      final Player ai, final SpellAbility sa, final boolean mandatory) {
    final Game game = ai.getGame();
    List<Card> list = game.getCardsIn(ZoneType.Battlefield);
    final TargetRestrictions tgt = sa.getTargetRestrictions();
    final Player opp = ai.getOpponent();
    list =
        CardLists.getValidCards(
            list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard());
    list = CardLists.getTargetableCards(list, sa);

    if (list.size() < tgt.getMinTargets(sa.getHostCard(), sa)) {
      sa.resetTargets();
      return false;
    }

    // Remove anything that's already been targeted
    for (final Card c : sa.getTargets().getTargetCards()) {
      list.remove(c);
    }

    List<Card> pref;
    List<Card> forced;
    final Card source = sa.getHostCard();

    if (sa.isCurse()) {
      pref = CardLists.filterControlledBy(list, opp);
      forced = CardLists.filterControlledBy(list, ai);
    } else {
      pref = CardLists.filterControlledBy(list, ai);
      forced = CardLists.filterControlledBy(list, opp);
    }

    while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
      if (pref.isEmpty()) {
        break;
      }

      Card c;
      if (CardLists.getNotType(pref, "Creature").isEmpty()) {
        c = ComputerUtilCard.getBestCreatureAI(pref);
      } else {
        c = ComputerUtilCard.getMostExpensivePermanentAI(pref, sa, true);
      }

      pref.remove(c);

      sa.getTargets().add(c);
    }

    while (sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa)) {
      if (forced.isEmpty()) {
        break;
      }

      Card c;
      if (CardLists.getNotType(forced, "Creature").isEmpty()) {
        c = ComputerUtilCard.getWorstCreatureAI(forced);
      } else {
        c = ComputerUtilCard.getCheapestPermanentAI(forced, sa, true);
      }

      forced.remove(c);

      sa.getTargets().add(c);
    }

    if (sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa)) {
      sa.resetTargets();
      return false;
    }

    return true;
  } // pumpMandatoryTarget()
  /** {@inheritDoc} */
  @Override
  public final boolean performTest(final java.util.Map<String, Object> runParams2) {
    final SpellAbility spellAbility = (SpellAbility) runParams2.get("CastSA");
    if (spellAbility == null) {
      System.out.println(
          "TriggerSpellAbilityCast performTest encountered spellAbility == null. runParams2 = "
              + runParams2);
      return false;
    }
    final Card cast = spellAbility.getHostCard();
    final Game game = cast.getGame();
    final SpellAbilityStackInstance si = game.getStack().getInstanceFromSpellAbility(spellAbility);

    if (this.getMode() == TriggerType.SpellCast) {
      if (!spellAbility.isSpell()) {
        return false;
      }
    } else if (this.getMode() == TriggerType.AbilityCast) {
      if (!spellAbility.isAbility()) {
        return false;
      }
    } else if (this.getMode() == TriggerType.SpellAbilityCast) {
      // Empty block for readability.
    }

    if (this.mapParams.containsKey("ActivatedOnly")) {
      if (spellAbility.isTrigger()) {
        return false;
      }
    }

    if (this.mapParams.containsKey("ValidControllingPlayer")) {
      if (!matchesValid(
          cast.getController(),
          this.mapParams.get("ValidControllingPlayer").split(","),
          this.getHostCard())) {
        return false;
      }
    }

    if (this.mapParams.containsKey("ValidActivatingPlayer")) {
      if (si == null
          || !matchesValid(
              si.getSpellAbility(true).getActivatingPlayer(),
              this.mapParams.get("ValidActivatingPlayer").split(","),
              this.getHostCard())) {
        return false;
      }
      if (this.mapParams.containsKey("ActivatorThisTurnCast")) {
        String compare = this.mapParams.get("ActivatorThisTurnCast");
        List<Card> thisTurnCast =
            CardUtil.getThisTurnCast(
                this.mapParams.containsKey("ValidCard") ? this.mapParams.get("ValidCard") : "Card",
                this.getHostCard());
        thisTurnCast =
            CardLists.filterControlledBy(
                thisTurnCast, si.getSpellAbility(true).getActivatingPlayer());
        int left = thisTurnCast.size();
        int right = Integer.parseInt(compare.substring(2));
        if (!Expressions.compare(left, compare, right)) {
          return false;
        }
      }
    }

    if (this.mapParams.containsKey("ValidCard")) {
      if (!matchesValid(cast, this.mapParams.get("ValidCard").split(","), this.getHostCard())) {
        return false;
      }
    }

    if (this.mapParams.containsKey("TargetsValid")) {
      SpellAbility sa = spellAbility;
      if (si != null) {
        sa = si.getSpellAbility(true);
      }

      boolean validTgtFound = false;
      while (sa != null && !validTgtFound) {
        for (final Card tgt : sa.getTargets().getTargetCards()) {
          if (tgt.isValid(
              this.mapParams.get("TargetsValid").split(","),
              this.getHostCard().getController(),
              this.getHostCard())) {
            validTgtFound = true;
            break;
          }
        }

        for (final Player p : sa.getTargets().getTargetPlayers()) {
          if (matchesValid(p, this.mapParams.get("TargetsValid").split(","), this.getHostCard())) {
            validTgtFound = true;
            break;
          }
        }
        sa = sa.getSubAbility();
      }
      if (!validTgtFound) {
        return false;
      }
    }

    if (this.mapParams.containsKey("NonTapCost")) {
      final Cost cost = (Cost) (runParams2.get("Cost"));
      if (cost.hasTapCost()) {
        return false;
      }
    }

    if (this.mapParams.containsKey("Conspire")) {
      if (!spellAbility.isOptionalCostPaid(OptionalCost.Conspire)) {
        return false;
      }
      if (spellAbility.getConspireInstances() == 0) {
        return false;
      } else {
        spellAbility.subtractConspireInstance();
        // System.out.println("Conspire instances left = " + spellAbility.getConspireInstances());
      }
    }

    if (this.mapParams.containsKey("Outlast")) {
      if (!spellAbility.isOutlast()) {
        return false;
      }
    }

    if (this.mapParams.containsKey("IsSingleTarget")) {
      int numTargeted = 0;
      for (TargetChoices tc : spellAbility.getAllTargetChoices()) {
        numTargeted += tc.getNumTargeted();
      }
      if (numTargeted != 1) {
        return false;
      }
    }

    if (this.mapParams.containsKey("SpellSpeed")) {
      if (this.mapParams.get("SpellSpeed").equals("NotSorcerySpeed")) {
        if (this.getHostCard().getController().couldCastSorcery(spellAbility)) {
          return false;
        }
        if (this.getHostCard()
            .hasKeyword(
                "You may cast CARDNAME as though it had flash. If you cast it any time a "
                    + "sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning"
                    + " of the next cleanup step.")) {
          // for these cards the trigger must only fire if using their own ability to cast at
          // instant speed
          if (this.getHostCard().hasKeyword("Flash")
              || this.getHostCard()
                  .getController()
                  .hasKeyword("You may cast nonland cards as though they had flash.")) {
            return false;
          }
        }
        return true;
      }
    }

    return true;
  }