Пример #1
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;
 }
Пример #2
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;
 }
Пример #3
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);
  }
Пример #4
0
 /**
  * Checks if there are enough {@link Permanent} or {@link Player} that can be chosen. Should only
  * be used for Ability targets since this checks for protection, shroud etc.
  *
  * @param sourceId - the target event source
  * @param sourceControllerId - controller of the target event source
  * @param game
  * @return - true if enough valid {@link Permanent} or {@link Player} exist
  */
 @Override
 public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
   int count = 0;
   MageObject targetSource = game.getObject(sourceId);
   for (UUID playerId : game.getPlayer(sourceControllerId).getInRange()) {
     Player player = game.getPlayer(playerId);
     if (player != null
         && player.canBeTargetedBy(targetSource, game)
         && filter.match(player, game)) {
       count++;
       if (count >= this.minNumberOfTargets) {
         return true;
       }
     }
   }
   for (Permanent permanent :
       game.getBattlefield()
           .getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
     if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game)
         && filter.match(permanent, sourceId, sourceControllerId, game)) {
       count++;
       if (count >= this.minNumberOfTargets) {
         return true;
       }
     }
   }
   return false;
 }
Пример #5
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;
 }
Пример #6
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;
 }
Пример #7
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;
 }
Пример #8
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;
 }
Пример #9
0
 @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;
 }
Пример #10
0
 @Override
 public void setSourceObject(MageObject sourceObject, Game game) {
   if (sourceObject == null) {
     this.sourceObject = game.getObject(sourceId);
   } else {
     this.sourceObject = sourceObject;
   }
   this.sourceObjectZoneChangeCounter = game.getState().getZoneChangeCounter(sourceId);
 }
Пример #11
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;
 }
Пример #12
0
 @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;
 }
Пример #13
0
 private MageObject getMageObject(GameEvent event, Game game, TriggeredAbility ability) {
   MageObject object = game.getPermanent(ability.getSourceId());
   if (object == null) {
     object = game.getLastKnownInformation(ability.getSourceId(), event.getZone());
     if (object == null) {
       object = game.getObject(ability.getSourceId());
     }
   }
   return object;
 }
Пример #14
0
 @Override
 public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) {
   Permanent permanent = game.getPermanent(id);
   if (permanent != null) {
     if (source != null) {
       // 1. TODO: check for replacement effects
       // 2. We need to check both source.getId() and source.getSourceId()
       // first for protection from spells or abilities (e.g. protection from colored spells,
       // r1753)
       // second for protection from sources (e.g. protection from artifacts + equip ability)
       return permanent.canBeTargetedBy(game.getObject(source.getId()), controllerId, game)
           && permanent.canBeTargetedBy(game.getObject(source.getSourceId()), controllerId, game)
           && filter.match(permanent, source.getSourceId(), controllerId, game);
     } else {
       return filter.match(permanent, null, controllerId, game);
     }
   }
   return false;
 }
Пример #15
0
 @Override
 public void watch(GameEvent event, Game game) {
   if (event.getType() == GameEvent.EventType.SPELL_CAST
       && game.getActivePlayerId().equals(event.getPlayerId())
       && game.getOpponents(controllerId).contains(event.getPlayerId())) {
     Spell spell = (Spell) game.getObject(event.getTargetId());
     if (spell.getCardType().contains(CardType.CREATURE)) {
       condition = true;
     }
   }
 }
Пример #16
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;
 }
Пример #17
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;
 }
Пример #18
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;
 }
Пример #19
0
 @Override
 public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
   Set<UUID> possibleTargets = new HashSet<UUID>();
   MageObject targetSource = game.getObject(sourceId);
   for (Permanent permanent :
       game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game)) {
     if (!targets.containsKey(permanent.getId())
         && permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) {
       possibleTargets.add(permanent.getId());
     }
   }
   return possibleTargets;
 }
Пример #20
0
 @Override
 public boolean canTarget(UUID id, Ability source, Game game) {
   Player player = game.getPlayer(id);
   if (player != null) {
     if (source != null) {
       return player.canBeTargetedBy(game.getObject(source.getSourceId()), game)
           && filter.match(player, source.getSourceId(), source.getControllerId(), game);
     } else {
       return filter.match(player, game);
     }
   }
   return false;
 }
Пример #21
0
 @Override
 public boolean replaceEvent(GameEvent event, Ability source, Game game) {
   MageObject object = game.getObject(event.getSourceId());
   if (object != null) {
     Card card = (Card) object;
     Ability ability = new AffinityForArtifactsAbility();
     card.addAbility(ability);
     ability.setControllerId(source.getControllerId());
     ability.setSourceId(card.getId());
     game.getState().addAbility(ability, source.getSourceId(), card);
   }
   return false;
 }
Пример #22
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;
 }
Пример #23
0
 @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());
     }
   }
 }
Пример #24
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;
  }
Пример #25
0
 @Override
 public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
   Set<UUID> possibleTargets = new HashSet<UUID>();
   MageObject targetSource = game.getObject(sourceId);
   for (UUID playerId : game.getPlayer(sourceControllerId).getInRange()) {
     Player player = game.getPlayer(playerId);
     if (player != null
         && !player.hasLeft()
         && filter.match(player, sourceId, sourceControllerId, game)) {
       if (player.canBeTargetedBy(targetSource, game)) possibleTargets.add(playerId);
     }
   }
   return possibleTargets;
 }
Пример #26
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;
 }
Пример #27
0
 @Override
 public MageObject getSourceObjectIfItStillExists(Game game) {
   MageObject currentObject = game.getObject(getSourceId());
   if (currentObject != null) {
     if (sourceObject == null) {
       setSourceObject(currentObject, game);
     }
     MageObjectReference mor = new MageObjectReference(currentObject, game);
     if (mor.getZoneChangeCounter() == getSourceObjectZoneChangeCounter()) {
       // source object has meanwhile not changed zone
       return currentObject;
     }
   }
   return null;
 }
Пример #28
0
 /**
  * Checks if there are enough {@link Player} that can be chosen. Should only be used for Ability
  * targets since this checks for protection, shroud etc.
  *
  * @param sourceId - the target event source
  * @param sourceControllerId - controller of the target event source
  * @param game
  * @return - true if enough valid {@link Player} exist
  */
 @Override
 public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
   int count = 0;
   MageObject targetSource = game.getObject(sourceId);
   for (UUID playerId : game.getPlayer(sourceControllerId).getInRange()) {
     Player player = game.getPlayer(playerId);
     if (player != null
         && !player.hasLeft()
         && filter.match(player, sourceId, sourceControllerId, game)) {
       if (player.canBeTargetedBy(targetSource, game)) {
         count++;
         if (count >= this.minNumberOfTargets) return true;
       }
     }
   }
   return false;
 }
Пример #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;
 }