示例#1
0
  @Override
  public void resolve(final SpellAbility sa) {
    final Card host = sa.getHostCard();
    final Map<String, String> svars = host.getSVars();

    // AF specific sa
    int power = -1;
    if (sa.hasParam("Power")) {
      power = AbilityUtils.calculateAmount(host, sa.getParam("Power"), sa);
    }
    int toughness = -1;
    if (sa.hasParam("Toughness")) {
      toughness = AbilityUtils.calculateAmount(host, sa.getParam("Toughness"), sa);
    }
    final Game game = sa.getActivatingPlayer().getGame();

    // Every Animate event needs a unique time stamp
    final long timestamp = game.getNextTimestamp();

    final boolean permanent = sa.hasParam("Permanent");

    final CardType types = new CardType();
    if (sa.hasParam("Types")) {
      types.addAll(Arrays.asList(sa.getParam("Types").split(",")));
    }

    final CardType removeTypes = new CardType();
    if (sa.hasParam("RemoveTypes")) {
      removeTypes.addAll(Arrays.asList(sa.getParam("RemoveTypes").split(",")));
    }

    // allow ChosenType - overrides anything else specified
    if (types.hasSubtype("ChosenType")) {
      types.clear();
      types.add(host.getChosenType());
    }

    final List<String> keywords = new ArrayList<String>();
    if (sa.hasParam("Keywords")) {
      keywords.addAll(Arrays.asList(sa.getParam("Keywords").split(" & ")));
    }

    final List<String> removeKeywords = new ArrayList<String>();
    if (sa.hasParam("RemoveKeywords")) {
      removeKeywords.addAll(Arrays.asList(sa.getParam("RemoveKeywords").split(" & ")));
    }

    final List<String> hiddenKeywords = new ArrayList<String>();
    if (sa.hasParam("HiddenKeywords")) {
      hiddenKeywords.addAll(Arrays.asList(sa.getParam("HiddenKeywords").split(" & ")));
    }
    // allow SVar substitution for keywords
    for (int i = 0; i < keywords.size(); i++) {
      final String k = keywords.get(i);
      if (svars.containsKey(k)) {
        keywords.add(svars.get(k));
        keywords.remove(k);
      }
    }

    // colors to be added or changed to
    String tmpDesc = "";
    if (sa.hasParam("Colors")) {
      final String colors = sa.getParam("Colors");
      if (colors.equals("ChosenColor")) {
        tmpDesc = CardUtil.getShortColorsString(host.getChosenColors());
      } else {
        tmpDesc =
            CardUtil.getShortColorsString(new ArrayList<String>(Arrays.asList(colors.split(","))));
      }
    }
    final String finalDesc = tmpDesc;

    // abilities to add to the animated being
    final List<String> abilities = new ArrayList<String>();
    if (sa.hasParam("Abilities")) {
      abilities.addAll(Arrays.asList(sa.getParam("Abilities").split(",")));
    }
    // replacement effects to add to the animated being
    final List<String> replacements = new ArrayList<String>();
    if (sa.hasParam("Replacements")) {
      replacements.addAll(Arrays.asList(sa.getParam("Replacements").split(",")));
    }
    // triggers to add to the animated being
    final List<String> triggers = new ArrayList<String>();
    if (sa.hasParam("Triggers")) {
      triggers.addAll(Arrays.asList(sa.getParam("Triggers").split(",")));
    }

    // sVars to add to the animated being
    final List<String> sVars = new ArrayList<String>();
    if (sa.hasParam("sVars")) {
      sVars.addAll(Arrays.asList(sa.getParam("sVars").split(",")));
    }

    String valid = "";

    if (sa.hasParam("ValidCards")) {
      valid = sa.getParam("ValidCards");
    }

    CardCollectionView list;
    List<Player> tgtPlayers = getTargetPlayers(sa);

    if (!sa.usesTargeting() && !sa.hasParam("Defined")) {
      list = game.getCardsIn(ZoneType.Battlefield);
    } else {
      list = tgtPlayers.get(0).getCardsIn(ZoneType.Battlefield);
    }

    list = CardLists.getValidCards(list, valid.split(","), host.getController(), host);

    for (final Card c : list) {
      doAnimate(
          c,
          sa,
          power,
          toughness,
          types,
          removeTypes,
          finalDesc,
          keywords,
          removeKeywords,
          hiddenKeywords,
          timestamp);

      // give abilities
      final List<SpellAbility> addedAbilities = new ArrayList<SpellAbility>();
      if (abilities.size() > 0) {
        for (final String s : abilities) {
          final String actualAbility = host.getSVar(s);
          final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, c);
          addedAbilities.add(grantedAbility);
          c.addSpellAbility(grantedAbility);
        }
      }

      // remove abilities
      final List<SpellAbility> removedAbilities = new ArrayList<SpellAbility>();
      if (sa.hasParam("OverwriteAbilities") || sa.hasParam("RemoveAllAbilities")) {
        for (final SpellAbility ab : c.getSpellAbilities()) {
          if (ab.isAbility()) {
            c.removeSpellAbility(ab);
            removedAbilities.add(ab);
          }
        }
      }
      // give replacement effects
      final List<ReplacementEffect> addedReplacements = new ArrayList<ReplacementEffect>();
      if (replacements.size() > 0) {
        for (final String s : replacements) {
          final String actualReplacement = host.getSVar(s);
          final ReplacementEffect parsedReplacement =
              ReplacementHandler.parseReplacement(actualReplacement, c, false);
          addedReplacements.add(c.addReplacementEffect(parsedReplacement));
        }
      }
      // Grant triggers
      final List<Trigger> addedTriggers = new ArrayList<Trigger>();
      if (triggers.size() > 0) {
        for (final String s : triggers) {
          final String actualTrigger = host.getSVar(s);
          final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, c, false);
          addedTriggers.add(c.addTrigger(parsedTrigger));
        }
      }

      // suppress triggers from the animated card
      final List<Trigger> removedTriggers = new ArrayList<Trigger>();
      if (sa.hasParam("OverwriteTriggers") || sa.hasParam("RemoveAllAbilities")) {
        final FCollectionView<Trigger> triggersToRemove = c.getTriggers();
        for (final Trigger trigger : triggersToRemove) {
          trigger.setSuppressed(true);
          removedTriggers.add(trigger);
        }
      }

      // suppress static abilities from the animated card
      final List<StaticAbility> removedStatics = new ArrayList<StaticAbility>();
      if (sa.hasParam("OverwriteStatics") || sa.hasParam("RemoveAllAbilities")) {
        final FCollectionView<StaticAbility> staticsToRemove = c.getStaticAbilities();
        for (final StaticAbility stAb : staticsToRemove) {
          stAb.setTemporarilySuppressed(true);
          removedStatics.add(stAb);
        }
      }

      // suppress static abilities from the animated card
      final List<ReplacementEffect> removedReplacements = new ArrayList<ReplacementEffect>();
      if (sa.hasParam("OverwriteReplacements") || sa.hasParam("RemoveAllAbilities")) {
        final FCollectionView<ReplacementEffect> replacementsToRemove = c.getReplacementEffects();
        for (final ReplacementEffect re : replacementsToRemove) {
          re.setTemporarilySuppressed(true);
          removedReplacements.add(re);
        }
      }

      // give sVars
      if (sVars.size() > 0) {
        for (final String s : sVars) {
          final String actualsVar = host.getSVar(s);
          c.setSVar(s, actualsVar);
        }
      }
      game.fireEvent(new GameEventCardStatsChanged(c));

      final GameCommand unanimate =
          new GameCommand() {
            private static final long serialVersionUID = -5861759814760561373L;

            @Override
            public void run() {
              doUnanimate(
                  c,
                  sa,
                  finalDesc,
                  hiddenKeywords,
                  addedAbilities,
                  addedTriggers,
                  addedReplacements,
                  false,
                  removedAbilities,
                  timestamp);

              // give back suppressed triggers
              for (final Trigger t : removedTriggers) {
                t.setSuppressed(false);
              }

              // give back suppressed static abilities
              for (final StaticAbility s : removedStatics) {
                s.setTemporarilySuppressed(false);
              }

              // give back suppressed replacement effects
              for (final ReplacementEffect re : removedReplacements) {
                re.setTemporarilySuppressed(false);
              }
              game.fireEvent(new GameEventCardStatsChanged(c));
            }
          };

      if (!permanent) {
        if (sa.hasParam("UntilEndOfCombat")) {
          game.getEndOfCombat().addUntil(unanimate);
        } else {
          game.getEndOfTurn().addUntil(unanimate);
        }
      }
    }
  } // animateAllResolve
  /** {@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;
  }
  @Override
  public void resolve(SpellAbility sa) {
    final Card card = sa.getHostCard();
    final Game game = card.getGame();

    final boolean remDestroyed = sa.hasParam("RememberDestroyed");
    final boolean remAttached = sa.hasParam("RememberAttached");
    if (remDestroyed || remAttached) {
      card.clearRemembered();
    }

    final boolean noRegen = sa.hasParam("NoRegen");
    final boolean sac = sa.hasParam("Sacrifice");

    final List<Card> tgtCards = getTargetCards(sa);
    final List<Card> untargetedCards = new ArrayList<Card>();

    final TargetRestrictions tgt = sa.getTargetRestrictions();

    if (sa.hasParam("Radiance")) {
      for (final Card c :
          CardUtil.getRadiance(card, tgtCards.get(0), sa.getParam("ValidTgts").split(","))) {
        untargetedCards.add(c);
      }
    }

    for (final Card tgtC : tgtCards) {
      if (tgtC.isInPlay() && ((tgt == null) || tgtC.canBeTargetedBy(sa))) {
        boolean destroyed = false;
        final Card lki = CardUtil.getLKICopy(tgtC);
        if (remAttached) {
          card.addRemembered(tgtC.getEnchantedBy(false));
          card.addRemembered(tgtC.getEquippedBy(false));
          card.addRemembered(tgtC.getFortifiedBy(false));
        }
        if (sac) {
          destroyed = game.getAction().sacrifice(tgtC, sa) != null;
        } else if (noRegen) {
          destroyed = game.getAction().destroyNoRegeneration(tgtC, sa);
        } else {
          destroyed = game.getAction().destroy(tgtC, sa);
        }
        if (destroyed && remDestroyed) {
          card.addRemembered(tgtC);
        }
        if (destroyed && sa.hasParam("RememberLKI")) {
          card.addRemembered(lki);
        }
      }
    }

    for (final Card unTgtC : untargetedCards) {
      if (unTgtC.isInPlay()) {
        boolean destroyed = false;
        if (sac) {
          destroyed = game.getAction().sacrifice(unTgtC, sa) != null;
        } else if (noRegen) {
          destroyed = game.getAction().destroyNoRegeneration(unTgtC, sa);
        } else {
          destroyed = game.getAction().destroy(unTgtC, sa);
        }
        if (destroyed && remDestroyed) {
          card.addRemembered(unTgtC);
        }
      }
    }
  }
示例#4
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