示例#1
0
 @Override
 public boolean apply(Game game, Ability source) {
   Player player = game.getPlayer(source.getControllerId());
   MageObject sourceObject = game.getObject(source.getSourceId());
   if (player != null) {
     Choice typeChoice = new ChoiceImpl(true);
     typeChoice.setMessage("Choose a creature type:");
     typeChoice.setChoices(CardRepository.instance.getCreatureTypes());
     while (!player.choose(outcome, typeChoice, game)) {
       if (!player.canRespond()) {
         return false;
       }
     }
     if (typeChoice.getChoice() != null) {
       game.informPlayers(sourceObject.getLogName() + " chosen type: " + typeChoice.getChoice());
     }
     FilterCreaturePermanent filterCreaturePermanent = new FilterCreaturePermanent();
     filterCreaturePermanent.add(new SubtypePredicate(typeChoice.getChoice()));
     for (Permanent creature :
         game.getBattlefield()
             .getActivePermanents(filterCreaturePermanent, source.getSourceId(), game)) {
       creature.untap(game);
     }
     return true;
   }
   return false;
 }
示例#2
0
 @Override
 public boolean hasSourceObjectAbility(Game game, MageObject source, GameEvent event) {
   MageObject object = source;
   // for singleton abilities like Flying we can't rely on abilities' source because it's only once
   // in continuous effects
   // so will use the sourceId of the object itself that came as a parameter if it is not null
   if (object == null) {
     object = game.getPermanentEntering(getSourceId());
     if (object == null) {
       object = game.getObject(getSourceId());
     }
   }
   if (object != null) {
     if (object instanceof Permanent) {
       if (!((Permanent) object).getAbilities(game).contains(this)) {
         return false;
       }
       return ((Permanent) object).isPhasedIn();
     } else if (!object.getAbilities().contains(this)) {
       // check if it's an ability that is temporary gained to a card
       Abilities<Ability> otherAbilities =
           game.getState().getAllOtherAbilities(this.getSourceId());
       if (otherAbilities == null || !otherAbilities.contains(this)) {
         return false;
       }
     }
   }
   return true;
 }
 @Override
 public boolean apply(Game game, Ability source) {
   Player controller = game.getPlayer(source.getControllerId());
   MageObject sourceObject = source.getSourceObject(game);
   if (controller != null && sourceObject != null) {
     Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
     UUID exileId =
         CardUtil.getExileZoneId(
             game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
     if (permanent != null) {
       return controller.moveCardToExileWithInfo(
           permanent,
           exileId,
           sourceObject.getIdName(),
           source.getSourceId(),
           game,
           Zone.BATTLEFIELD,
           true);
     } else {
       Card card = game.getCard(getTargetPointer().getFirst(game, source));
       if (card != null) {
         return controller.moveCardToExileWithInfo(
             card,
             exileId,
             sourceObject.getIdName(),
             source.getSourceId(),
             game,
             game.getState().getZone(card.getId()),
             true);
       }
     }
   }
   return false;
 }
示例#4
0
 @Override
 public boolean apply(Game game, Ability source) {
   Player controller = game.getPlayer(source.getControllerId());
   MageObject sourceObject = source.getSourceObject(game);
   if (sourceObject != null && controller != null) {
     TargetCardInYourGraveyard target =
         new TargetCardInYourGraveyard(
             new FilterInstantOrSorceryCard("instant or sorcery card from your graveyard"));
     if (controller.chooseTarget(outcome, target, source, game)) {
       UUID exileId =
           CardUtil.getExileZoneId(
               game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
       Card card = controller.getGraveyard().get(target.getFirstTarget(), game);
       if (card != null) {
         controller.moveCardToExileWithInfo(
             card,
             exileId,
             sourceObject.getIdName(),
             source.getSourceId(),
             game,
             Zone.GRAVEYARD,
             true);
       }
     }
     return true;
   }
   return false;
 }
示例#5
0
 @Override
 public boolean pay(
     Ability ability,
     Game game,
     UUID sourceId,
     UUID controllerId,
     boolean noMana,
     Cost costToPay) {
   Player controller = game.getPlayer(controllerId);
   MageObject sourceObject = ability.getSourceObject(game);
   if (controller != null && sourceObject != null) {
     if (targets.choose(Outcome.Exile, controllerId, sourceId, game)) {
       UUID exileId =
           CardUtil.getExileZoneId(
               game, ability.getSourceId(), ability.getSourceObjectZoneChangeCounter());
       for (UUID targetId : targets.get(0).getTargets()) {
         Permanent permanent = game.getPermanent(targetId);
         if (permanent == null) {
           return false;
         }
         paid |=
             controller.moveCardToExileWithInfo(
                 permanent,
                 exileId,
                 sourceObject.getIdName() + " championed permanents",
                 sourceId,
                 game,
                 Zone.BATTLEFIELD,
                 true);
       }
     }
   }
   return paid;
 }
示例#6
0
 @Override
 public boolean apply(Game game, Ability source) {
   Player controller = game.getPlayer(source.getControllerId());
   MageObject sourceObject = source.getSourceObject(game);
   if (controller != null && sourceObject != null) {
     Choice choice = new ChoiceImpl(true);
     choice.setMessage("Choose a creature type:");
     choice.setChoices(CardRepository.instance.getCreatureTypes());
     while (!controller.choose(Outcome.BoostCreature, choice, game)) {
       if (!controller.canRespond()) {
         return false;
       }
     }
     Cards revealedCards = new CardsImpl();
     while (controller.getLibrary().size() > 0) {
       Card card = controller.getLibrary().removeFromTop(game);
       if (card.getCardType().contains(CardType.CREATURE)
           && card.getSubtype().contains(choice.getChoice())) {
         controller.moveCards(card, Zone.BATTLEFIELD, source, game);
         break;
       }
       revealedCards.add(card);
     }
     controller.revealCards(sourceObject.getIdName(), revealedCards, game);
     controller.moveCards(revealedCards, Zone.LIBRARY, source, game);
     controller.shuffleLibrary(source, game);
     return true;
   }
   return false;
 }
示例#7
0
 @Override
 public Boolean apply(Game game, MageObject mageObject) {
   if (!mageObject.getCardType().contains(cardType)) {
     mageObject.getCardType().add(cardType);
   }
   return true;
 }
示例#8
0
 @Override
 public boolean apply(Game game, Ability source) {
   Player controller = game.getPlayer(source.getControllerId());
   MageObject mageObject = game.getObject(source.getSourceId());
   if (controller != null && mageObject != null) {
     Choice typeChoice = new ChoiceImpl(true);
     typeChoice.setMessage("Choose creature type");
     typeChoice.setChoices(CardRepository.instance.getCreatureTypes());
     while (!controller.choose(outcome, typeChoice, game)) {
       if (!controller.canRespond()) {
         return false;
       }
     }
     if (!game.isSimulation()) {
       game.informPlayers(
           mageObject.getName()
               + ": "
               + controller.getLogName()
               + " has chosen "
               + typeChoice.getChoice());
     }
     Cards cardsToLibrary = new CardsImpl();
     FilterCreatureCard filter = new FilterCreatureCard();
     filter.add(new SubtypePredicate(typeChoice.getChoice()));
     cardsToLibrary.addAll(
         controller
             .getGraveyard()
             .getCards(filter, source.getSourceId(), source.getControllerId(), game));
     controller.putCardsOnTopOfLibrary(cardsToLibrary, game, source, false);
     controller.shuffleLibrary(game);
     return true;
   }
   return false;
 }
示例#9
0
 @Override
 public boolean apply(Game game, Ability source) {
   Player player = getPayingPlayer(game, source);
   MageObject mageObject = game.getObject(source.getSourceId());
   if (player != null && mageObject != null) {
     String message;
     if (chooseUseText == null) {
       message =
           new StringBuilder(getCostText())
               .append(" and ")
               .append(executingEffect.getText(source.getModes().getMode()))
               .append("?")
               .toString();
     } else {
       message = chooseUseText;
     }
     message = CardUtil.replaceSourceName(message, mageObject.getName());
     if (cost.canPay(source, source.getSourceId(), player.getId(), game)
         && player.chooseUse(executingEffect.getOutcome(), message, game)) {
       cost.clearPaid();
       if (cost.pay(source, game, source.getSourceId(), player.getId(), false)) {
         executingEffect.setTargetPointer(this.targetPointer);
         if (executingEffect instanceof OneShotEffect) {
           if (!(executingEffect instanceof PostResolveEffect)) {
             return executingEffect.apply(game, source);
           }
         } else {
           game.addEffect((ContinuousEffect) executingEffect, source);
         }
       }
     }
     return true;
   }
   return false;
 }
示例#10
0
 @Override
 public boolean apply(Game game, Ability source) {
   Player controller = game.getPlayer(source.getControllerId());
   MageObject sourceObject = source.getSourceObject(game);
   if (controller != null && sourceObject != null) {
     controller.shuffleLibrary(source, game);
     if (controller.getLibrary().size() > 0) {
       Card card = controller.getLibrary().removeFromTop(game);
       if (card != null) {
         controller.moveCardToExileWithInfo(
             card,
             source.getSourceId(),
             sourceObject.getIdName(),
             source.getSourceId(),
             game,
             Zone.LIBRARY,
             true);
         ContinuousEffect effect = new MindsDesireCastFromExileEffect();
         effect.setTargetPointer(new FixedTarget(card.getId()));
         game.addEffect(effect, source);
       }
     }
     return true;
   }
   return false;
 }
示例#11
0
 @Override
 public boolean apply(Game game, Ability source) {
   Player player = game.getPlayer(targetPointer.getFirst(game, source));
   MageObject mageObject = game.getObject(source.getSourceId());
   if (player != null && mageObject != null) {
     String message = userMessage;
     if (message == null) {
       message =
           getCostText()
               + " to prevent "
               + executingEffect.getText(source.getModes().getMode())
               + "?";
     }
     message = CardUtil.replaceSourceName(message, mageObject.getLogName());
     cost.clearPaid();
     if (cost.canPay(source, source.getSourceId(), player.getId(), game)
         && player.chooseUse(executingEffect.getOutcome(), message, source, game)) {
       cost.pay(source, game, source.getSourceId(), player.getId(), false, null);
     }
     if (!cost.isPaid()) {
       executingEffect.setTargetPointer(this.targetPointer);
       return executingEffect.apply(game, source);
     }
     return true;
   }
   return false;
 }
示例#12
0
 @Override
 public boolean apply(Game game, Ability source) {
   MageObject object = game.getObject(source.getSourceId());
   if (object != null && object.hasSubtype("Myr")) {
     return true;
   }
   return false;
 }
示例#13
0
  @Override
  public boolean apply(MageObject input, Game game) {
    if (input.getAbilities().contains(ChangelingAbility.getInstance())) {
      return true;
    }

    return input.getSubtype().contains(subtype);
  }
 @Override
 public String getInfoMessage(Ability source, GameEvent event, Game game) {
   MageObject mageObject = game.getObject(source.getSourceId());
   if (mageObject != null) {
     return "You can't cast a card with that name (" + mageObject.getLogName() + " in play).";
   }
   return null;
 }
示例#15
0
  @Override
  public boolean apply(Game game, Ability source) {
    Cards cardsToCast = new CardsImpl();
    Player targetOpponent = game.getPlayer(targetPointer.getFirst(game, source));
    MageObject sourceObject = source.getSourceObject(game);
    if (targetOpponent != null && sourceObject != null) {
      List<Card> allCards = targetOpponent.getLibrary().getTopCards(game, 7);
      Cards cards = new CardsImpl(Zone.LIBRARY, allCards);
      targetOpponent.revealCards(
          sourceObject.getIdName() + " - " + targetOpponent.getName() + "'s top library cards",
          cards,
          game);
      for (Card card : allCards) {
        if (filter.match(card, game)) {
          cardsToCast.add(card);
        }
      }
      // cast an instant or sorcery for free
      if (cardsToCast.size() > 0) {
        int numberOfSpells = 1;
        if (SpellMasteryCondition.getInstance().apply(game, source)) {
          numberOfSpells++;
        }
        Player controller = game.getPlayer(source.getControllerId());
        if (controller != null) {

          TargetCard target = new TargetCard(Zone.LIBRARY, filter); // zone should be ignored here
          target.setNotTarget(true);
          while (numberOfSpells > 0
              && cardsToCast.size() > 0
              && controller.chooseUse(
                  outcome,
                  "Cast an instant or sorcery card from among them for free?",
                  source,
                  game)
              && controller.choose(outcome, cardsToCast, target, game)) {
            Card card = cardsToCast.get(target.getFirstTarget(), game);
            if (card != null) {
              controller.cast(card.getSpellAbility(), game, true);
              numberOfSpells--;
              cardsToCast.remove(card);
              allCards.remove(card);
            }
            if (!controller.isInGame()) {
              return false;
            }
            target.clearChosen();
          }
        }

        targetOpponent.moveCards(allCards, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
      }
      return true;
    }
    return false;
  }
 @Override
 public String getInfoMessage(Ability source, GameEvent event, Game game) {
   MageObject sourceObject = game.getObject(source.getSourceId());
   if (sourceObject != null) {
     return "This spell can't be countered by spells or abilities ("
         + sourceObject.getName()
         + ").";
   }
   return null;
 }
示例#17
0
 @Override
 public boolean apply(Game game, Ability source, UUID manaProducer, Cost costToPay) {
   if (super.apply(game, source)) {
     MageObject object = game.getObject(source.getSourceId());
     if (object.hasSubtype("Dragon", game) && object.getCardType().contains(CardType.CREATURE)) {
       return true;
     }
   }
   return false;
 }
示例#18
0
 @Override
 public boolean apply(Game game, Ability source) {
   MageObject object = game.getObject(source.getSourceId());
   if (object != null) {
     for (Ability ability : object.getAbilities()) {
       if (ability instanceof DevoidAbility) {
         return true;
       }
     }
   }
   return false;
 }
示例#19
0
 @Override
 public boolean applies(GameEvent event, Ability source, Game game) {
   if (event.getType() == EventType.CAST_SPELL
       && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
     MageObject object = game.getObject(event.getSourceId());
     if (object != null
         && object.getName().equals(game.getState().getValue(source.getSourceId().toString()))) {
       return true;
     }
   }
   return false;
 }
示例#20
0
 private boolean checkAbilityStillExists(
     Ability ability, ContinuousEffect effect, GameEvent event, Game game) {
   switch (effect
       .getDuration()) { // effects with fixed duration don't need an object with the source
                         // ability (e.g. a silence cast with isochronic Scepter has no more a card
                         // object
     case EndOfCombat:
     case EndOfGame:
     case EndOfStep:
     case EndOfTurn:
     case OneUse:
     case Custom: // custom duration means the effect ends itself if needed
       return true;
   }
   if (ability.getSourceId() == null) { // commander replacement effect
     return true;
   }
   MageObject object;
   if (event.getType().equals(EventType.ZONE_CHANGE)
       && ((ZoneChangeEvent) event).getFromZone().equals(Zone.BATTLEFIELD)
       && event.getTargetId().equals(ability.getSourceId())) {
     object = ((ZoneChangeEvent) event).getTarget();
   } else {
     object = game.getObject(ability.getSourceId());
   }
   if (object == null) {
     return false;
   }
   boolean exists = true;
   if (!object.getAbilities().contains(ability)) {
     exists = false;
     if (object instanceof PermanentCard) {
       PermanentCard permanent = (PermanentCard) object;
       if (permanent.canTransform() && event.getType() == GameEvent.EventType.TRANSFORMED) {
         exists = permanent.getCard().getAbilities().contains(ability);
       }
     }
   } else {
     if (object instanceof PermanentCard) {
       PermanentCard permanent = (PermanentCard) object;
       if (permanent.isFaceDown(game) && !ability.getWorksFaceDown()) {
         return false;
       }
     } else if (object instanceof Spell) {
       Spell spell = (Spell) object;
       if (spell.isFaceDown(game) && !ability.getWorksFaceDown()) {
         return false;
       }
     }
   }
   return exists;
 }
示例#21
0
 @Override
 public boolean applies(GameEvent event, Ability source, Game game) {
   if ((event.getType() == GameEvent.EventType.CAST_SPELL)
       && event.getPlayerId() == source.getControllerId()) {
     MageObject spellObject = game.getObject(event.getSourceId());
     if (spellObject != null
         && spellObject.getCardType().contains(CardType.CREATURE)
         && spellObject.getCardType().contains(CardType.ARTIFACT)) {
       return true;
     }
   }
   return false;
 }
 @Override
 public void watch(GameEvent event, Game game) {
   if (event.getType() == GameEvent.EventType.MANA_PAYED) {
     MageObject object = game.getObject(event.getSourceId());
     // TODO: Replace identification by name by better method that also works if ability is copied
     // from other land with other name
     if (object != null
         && object.getName().equals("Boseiju, Who Shelters All")
         && event.getFlag()) {
       spells.add(event.getTargetId());
     }
   }
 }
示例#23
0
  @Override
  public boolean resolve(Game game) {
    boolean result = true;
    // 20100716 - 117.12
    if (checkIfClause(game)) {

      for (Effect effect : getEffects()) {
        if (effect instanceof OneShotEffect) {
          boolean effectResult = effect.apply(game, this);
          result &= effectResult;
          if (logger.isDebugEnabled()) {
            if (!this.getAbilityType().equals(AbilityType.MANA)) {
              if (!effectResult) {
                if (this.getSourceId() != null) {
                  MageObject mageObject = game.getObject(this.getSourceId());
                  if (mageObject != null) {
                    logger.debug("AbilityImpl.resolve: object: " + mageObject.getName());
                  }
                }
                logger.debug(
                    "AbilityImpl.resolve: effect returned false -"
                        + effect.getText(this.getModes().getMode()));
              }
            }
          }
        } else {
          game.addEffect((ContinuousEffect) effect, this);
        }
        /**
         * All restrained trigger events are fired now. To restrain the events is mainly neccessary
         * because of the movement of multiple object at once. If the event is fired directly as one
         * object moved, other objects are not already in the correct zone to check for their
         * effects. (e.g. Valakut, the Molten Pinnacle)
         */
        game.getState().handleSimultaneousEvent(game);
        game.resetShortLivingLKI();
        /**
         * game.applyEffects() has to be done at least for every effect that moves cards/permanent
         * between zones, or changes control of objects so Static effects work as intened if
         * dependant from the moved objects zone it is in Otherwise for example were static
         * abilities with replacement effects deactivated too late Example: {@link
         * org.mage.test.cards.replacement.DryadMilitantTest#testDiesByDestroy testDiesByDestroy}
         */
        if (effect.applyEffectsAfter()) {
          game.applyEffects();
          game.getState().getTriggers().checkStateTriggers(game);
        }
      }
    }
    return result;
  }
示例#24
0
 @Override
 public boolean replaceEvent(GameEvent event, Ability source, Game game) {
   Player controller = game.getPlayer(source.getControllerId());
   MageObject sourceObject = game.getObject(source.getSourceId());
   if (controller != null && sourceObject != null) {
     Card card = game.getCard(event.getTargetId());
     if (card != null) {
       Cards cards = new CardsImpl(card);
       controller.revealCards(sourceObject.getIdName(), cards, game);
       controller.putCardsOnBottomOfLibrary(cards, game, source, false);
       return true;
     }
   }
   return false;
 }
示例#25
0
 private String getKey(TriggeredAbility ability, MageObject target) {
   String key = ability.getId() + "_";
   if (target != null) {
     key += target.getId();
   }
   return key;
 }
示例#26
0
  /**
   * @param game
   * @param source
   * @return
   */
  @Override
  public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
    if (!this.hasSourceObjectAbility(game, source, event)) {
      return false;
    }
    if (zone.equals(Zone.COMMAND)) {
      if (this.getSourceId() == null) { // commander effects
        return true;
      }
      MageObject object = game.getObject(this.getSourceId());
      // emblem are always actual
      if (object != null && object instanceof Emblem) {
        return true;
      }
    }

    UUID parameterSourceId;
    // for singleton abilities like Flying we can't rely on abilities' source because it's only once
    // in continuous effects
    // so will use the sourceId of the object itself that came as a parameter if it is not null
    if (this instanceof MageSingleton && source != null) {
      parameterSourceId = source.getId();
    } else {
      parameterSourceId = getSourceId();
    }
    // check agains shortLKI for effects that move multiple object at the same time (e.g. destroy
    // all)
    if (game.getShortLivingLKI(getSourceId(), getZone())) {
      return true;
    }
    // check against current state
    Zone test = game.getState().getZone(parameterSourceId);
    return test != null && zone.match(test);
  }
示例#27
0
  @Override
  public boolean apply(Game game, Ability source) {
    Player controller = game.getPlayer(source.getControllerId());
    MageObject sourceObject = source.getSourceObject(game);
    if (controller != null && sourceObject != null) {
      if (controller.chooseUse(Outcome.Benefit, choiceText, source, game)) {
        Set<Card> sideboard = controller.getSideboard().getCards(filter, game);
        List<Card> exile = game.getExile().getAllCards(game);
        Cards filteredCards = new CardsImpl();
        Card card = null;

        for (Card sideboardCard : sideboard) {
          filteredCards.add(sideboardCard.getId());
        }
        for (Card exileCard : exile) {
          if (exileCard.getOwnerId().equals(source.getControllerId())
              && exileCard.hasSubtype("Eldrazi")) {
            filteredCards.add(exileCard);
          }
        }

        if (filteredCards.isEmpty()) {
          game.informPlayer(
              controller,
              "You have no "
                  + filter.getMessage()
                  + " outside the game (your sideboard) or in exile.");
        } else {
          TargetCard target = new TargetCard(Zone.OUTSIDE, filter);
          target.setNotTarget(true);
          if (controller.choose(outcome, filteredCards, target, game)) {
            card = controller.getSideboard().get(target.getFirstTarget(), game);
            if (card == null) {
              card = game.getCard(target.getFirstTarget());
            }
          }
        }

        if (card != null) {
          card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
          controller.revealCards(sourceObject.getIdName(), new CardsImpl(card), game);
        }
      }
      return true;
    }
    return false;
  }
示例#28
0
 /**
  * Adds a by sourceId gained triggered ability
  *
  * @param ability - the gained ability
  * @param sourceId - the source that assigned the ability
  * @param attachedTo - the object that gained the ability
  */
 public void add(TriggeredAbility ability, UUID sourceId, MageObject attachedTo) {
   this.add(ability, attachedTo);
   List<UUID> uuidList = new LinkedList<UUID>();
   uuidList.add(sourceId);
   // if the object that gained the ability moves zone, also then the triggered ability must be
   // removed
   uuidList.add(attachedTo.getId());
   sources.put(getKey(ability, attachedTo), uuidList);
 }
示例#29
0
 @Override
 public String getGameLogMessage(Game game) {
   if (game.isSimulation()) {
     return "";
   }
   MageObject object = game.getObject(this.sourceId);
   if (object == null) { // e.g. sacrificed token
     logger.warn("Could get no object: " + this.toString());
   }
   return new StringBuilder(" activates: ")
       .append(
           object != null
               ? this.formatRule(getModes().getText(), object.getLogName())
               : getModes().getText())
       .append(" from ")
       .append(getMessageText(game))
       .toString();
 }
 @Override
 public boolean apply(Game game, Ability source) {
   Card sourceCard = game.getCard(source.getSourceId());
   MageObject sourceObject = game.getObject(source.getSourceId());
   if (sourceCard != null) {
     Player player = game.getPlayer(sourceCard.getOwnerId());
     if (player != null) {
       Zone fromZone = game.getState().getZone(sourceCard.getId());
       Cards cards = new CardsImpl();
       cards.add(sourceCard);
       player.revealCards(sourceObject.getLogName(), cards, game);
       player.moveCardToLibraryWithInfo(
           sourceCard, source.getSourceId(), game, fromZone, true, true);
       player.shuffleLibrary(game);
       return true;
     }
   }
   return false;
 }