示例#1
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
  @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);
        }
      }
    }
  }
  /* (non-Javadoc)
   * @see forge.card.ability.SpellAbilityEffect#resolve(forge.card.spellability.SpellAbility)
   */
  @Override
  public void resolve(final SpellAbility sa) {
    final Card hostCard = sa.getHostCard();
    final Game game = hostCard.getGame();
    final List<String> keywords = new ArrayList<String>();
    final List<String> types = new ArrayList<String>();
    final List<String> svars = new ArrayList<String>();
    final List<String> triggers = new ArrayList<String>();
    if (sa.hasParam("Optional")) {
      if (!sa.getActivatingPlayer()
          .getController()
          .confirmAction(sa, null, "Copy this permanent?")) {
        return;
      }
    }
    if (sa.hasParam("Keywords")) {
      keywords.addAll(Arrays.asList(sa.getParam("Keywords").split(" & ")));
    }
    if (sa.hasParam("AddTypes")) {
      types.addAll(Arrays.asList(sa.getParam("AddTypes").split(" & ")));
    }
    if (sa.hasParam("AddSVars")) {
      svars.addAll(Arrays.asList(sa.getParam("AddSVars").split(" & ")));
    }
    if (sa.hasParam("Triggers")) {
      triggers.addAll(Arrays.asList(sa.getParam("Triggers").split(" & ")));
    }
    final int numCopies =
        sa.hasParam("NumCopies")
            ? AbilityUtils.calculateAmount(hostCard, sa.getParam("NumCopies"), sa)
            : 1;

    Player controller = null;
    if (sa.hasParam("Controller")) {
      final FCollectionView<Player> defined =
          AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("Controller"), sa);
      if (!defined.isEmpty()) {
        controller = defined.getFirst();
      }
    }
    if (controller == null) {
      controller = sa.getActivatingPlayer();
    }

    List<Card> tgtCards = getTargetCards(sa);
    final TargetRestrictions tgt = sa.getTargetRestrictions();

    if (sa.hasParam("ValidSupportedCopy")) {
      List<PaperCard> cards =
          Lists.newArrayList(StaticData.instance().getCommonCards().getUniqueCards());
      String valid = sa.getParam("ValidSupportedCopy");
      if (valid.contains("X")) {
        valid =
            valid.replace("X", Integer.toString(AbilityUtils.calculateAmount(hostCard, "X", sa)));
      }
      if (StringUtils.containsIgnoreCase(valid, "creature")) {
        Predicate<PaperCard> cpp =
            Predicates.compose(CardRulesPredicates.Presets.IS_CREATURE, PaperCard.FN_GET_RULES);
        cards = Lists.newArrayList(Iterables.filter(cards, cpp));
      }
      if (StringUtils.containsIgnoreCase(valid, "equipment")) {
        Predicate<PaperCard> cpp =
            Predicates.compose(CardRulesPredicates.Presets.IS_EQUIPMENT, PaperCard.FN_GET_RULES);
        cards = Lists.newArrayList(Iterables.filter(cards, cpp));
      }
      if (sa.hasParam("RandomCopied")) {
        List<PaperCard> copysource = new ArrayList<PaperCard>(cards);
        List<Card> choice = new ArrayList<Card>();
        final String num = sa.hasParam("RandomNum") ? sa.getParam("RandomNum") : "1";
        int ncopied = AbilityUtils.calculateAmount(hostCard, num, sa);
        while (ncopied > 0) {
          final PaperCard cp = Aggregates.random(copysource);
          Card possibleCard =
              Card.fromPaperCard(
                  cp,
                  sa.getActivatingPlayer()); // Need to temporarily set the Owner so the Game is set

          if (possibleCard.isValid(valid, hostCard.getController(), hostCard)) {
            choice.add(possibleCard);
            copysource.remove(cp);
            ncopied -= 1;
          }
        }
        tgtCards = choice;
      } else if (sa.hasParam("DefinedName")) {
        String name = sa.getParam("DefinedName");
        if (name.equals("NamedCard")) {
          if (!hostCard.getNamedCard().isEmpty()) {
            name = hostCard.getNamedCard();
          }
        }

        Predicate<PaperCard> cpp =
            Predicates.compose(
                CardRulesPredicates.name(StringOp.EQUALS, name), PaperCard.FN_GET_RULES);
        cards = Lists.newArrayList(Iterables.filter(cards, cpp));

        tgtCards.clear();
        if (!cards.isEmpty()) {
          tgtCards.add(Card.fromPaperCard(cards.get(0), controller));
        }
      }
    }
    hostCard.clearClones();

    for (final Card c : tgtCards) {
      if ((tgt == null) || c.canBeTargetedBy(sa)) {

        int multiplier = numCopies * hostCard.getController().getTokenDoublersMagnitude();
        final List<Card> crds = new ArrayList<Card>(multiplier);

        for (int i = 0; i < multiplier; i++) {
          final Card copy = CardFactory.copyCopiableCharacteristics(c, sa.getActivatingPlayer());
          copy.setToken(true);
          copy.setCopiedPermanent(c);
          CardFactory.copyCopiableAbilities(c, copy);
          // add keywords from sa
          for (final String kw : keywords) {
            copy.addIntrinsicKeyword(kw);
          }
          for (final String type : types) {
            copy.addType(type);
          }
          for (final String svar : svars) {
            String actualsVar = hostCard.getSVar(svar);
            String name = svar;
            if (actualsVar.startsWith("SVar:")) {
              actualsVar = actualsVar.split("SVar:")[1];
              name = actualsVar.split(":")[0];
              actualsVar = actualsVar.split(":")[1];
            }
            copy.setSVar(name, actualsVar);
          }
          for (final String s : triggers) {
            final String actualTrigger = hostCard.getSVar(s);
            final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, copy, true);
            copy.addTrigger(parsedTrigger);
          }

          // Temporarily register triggers of an object created with CopyPermanent
          // game.getTriggerHandler().registerActiveTrigger(copy, false);
          final Card copyInPlay = game.getAction().moveToPlay(copy);

          // when copying something stolen:
          copyInPlay.setController(controller, 0);
          copyInPlay.setSetCode(c.getSetCode());

          copyInPlay.setCloneOrigin(hostCard);
          sa.getHostCard().addClone(copyInPlay);
          crds.add(copyInPlay);
          if (sa.hasParam("RememberCopied")) {
            hostCard.addRemembered(copyInPlay);
          }
          if (sa.hasParam("Tapped")) {
            copyInPlay.setTapped(true);
          }
          if (sa.hasParam("CopyAttacking") && game.getPhaseHandler().inCombat()) {
            final String attacked = sa.getParam("CopyAttacking");
            GameEntity defender;
            if ("True".equals(attacked)) {
              FCollectionView<GameEntity> defs = game.getCombat().getDefenders();
              defender =
                  c.getController()
                      .getController()
                      .chooseSingleEntityForEffect(
                          defs, sa, "Choose which defender to attack with " + c, false);
            } else {
              defender =
                  AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("CopyAttacking"), sa).get(0);
            }
            game.getCombat().addAttacker(copyInPlay, defender);
            game.fireEvent(new GameEventCombatChanged());
          }

          if (sa.hasParam("AttachedTo")) {
            CardCollectionView list =
                AbilityUtils.getDefinedCards(hostCard, sa.getParam("AttachedTo"), sa);
            if (list.isEmpty()) {
              list = copyInPlay.getController().getGame().getCardsIn(ZoneType.Battlefield);
              list =
                  CardLists.getValidCards(
                      list, sa.getParam("AttachedTo"), copyInPlay.getController(), copyInPlay);
            }
            if (!list.isEmpty()) {
              Card attachedTo =
                  sa.getActivatingPlayer()
                      .getController()
                      .chooseSingleEntityForEffect(
                          list, sa, copyInPlay + " - Select a card to attach to.");
              if (copyInPlay.isAura()) {
                if (attachedTo.canBeEnchantedBy(copyInPlay)) {
                  copyInPlay.enchantEntity(attachedTo);
                } else { // can't enchant
                  continue;
                }
              } else if (copyInPlay.isEquipment()) { // Equipment
                if (attachedTo.canBeEquippedBy(copyInPlay)) {
                  copyInPlay.equipCard(attachedTo);
                } else {
                  continue;
                }
              } else { // Fortification
                copyInPlay.fortifyCard(attachedTo);
              }
            } else {
              continue;
            }
          }
        }

        if (sa.hasParam("AtEOT")) {
          final String location = sa.getParam("AtEOT");
          registerDelayedTrigger(sa, location, crds);
        }
      } // end canBeTargetedBy
    } // end foreach Card
  } // end resolve