@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; }
@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; }
@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; }
@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; }
@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()); } } }
@Override public boolean resolve(Game game) { if (optional) { Player player = game.getPlayer(this.getControllerId()); MageObject object = game.getObject(sourceId); StringBuilder sb = new StringBuilder(); if (object != null) { sb.append("Use the following ability from ").append(object.getName()).append("? "); sb.append(this.getRule(object.getName())); } else { sb.append("Use the following ability? ").append(this.getRule()); } if (!player.chooseUse(getEffects().get(0).getOutcome(), sb.toString(), game)) { return false; } } // 20091005 - 603.4 if (checkInterveningIfClause(game)) { return super.resolve(game); } return false; }
@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; }
public Map<String, String> getReplacementEffectsTexts( HashMap<ReplacementEffect, HashSet<Ability>> rEffects, Game game) { Map<String, String> texts = new LinkedHashMap<>(); for (Map.Entry<ReplacementEffect, HashSet<Ability>> entry : rEffects.entrySet()) { if (entry.getValue() != null) { for (Ability ability : entry.getValue()) { MageObject object = game.getObject(ability.getSourceId()); if (object != null) { texts.put( ability.getId().toString() + "_" + entry.getKey().getId().toString(), object.getName() + ": " + ability.getRule(object.getName())); } else { texts.put( ability.getId().toString() + "_" + entry.getKey().getId().toString(), entry.getKey().getText(null)); } } } else { logger.error("Replacement effect without ability: " + entry.getKey().toString()); } } return texts; }
@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) { return false; } Permanent faceDownCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); if (faceDownCreature != null) { Permanent copyFaceDown = faceDownCreature.copy(); copyFaceDown.setFaceDown(false, game); Cards cards = new CardsImpl(); cards.add(copyFaceDown); Player player = game.getPlayer(faceDownCreature.getControllerId()); controller.lookAtCards("face down card - " + mageObject.getName(), cards, game); if (player != null) { game.informPlayers( controller.getLogName() + " looks at a face down creature of " + player.getLogName()); } } else { return false; } return true; }
@Override public Token apply(Card source) { if (target == null) { throw new IllegalArgumentException("Target can't be null"); } // A copy contains only the attributes of the basic card or basic Token that's the base of the // permanent // else gained abililies would be copied too. MageObject sourceObj = source; if (source instanceof PermanentToken) { sourceObj = ((PermanentToken) source).getToken(); // to show the source image, the original values have to be used target.setOriginalExpansionSetCode(((Token) sourceObj).getOriginalExpansionSetCode()); target.setOriginalCardNumber(((Token) sourceObj).getOriginalCardNumber()); target.setCopySourceCard(((PermanentToken) source).getToken().getCopySourceCard()); } else if (source instanceof PermanentCard) { if (((PermanentCard) source).isMorphed() || ((PermanentCard) source).isManifested()) { MorphAbility.setPermanentToFaceDownCreature(target); return target; } else { if (((PermanentCard) source).isTransformed() && source.getSecondCardFace() != null) { sourceObj = ((PermanentCard) source).getSecondCardFace(); } else { sourceObj = ((PermanentCard) source).getCard(); } target.setOriginalExpansionSetCode(source.getExpansionSetCode()); target.setOriginalCardNumber(source.getCardNumber()); target.setCopySourceCard((Card) sourceObj); } } else { target.setOriginalExpansionSetCode(source.getExpansionSetCode()); target.setOriginalCardNumber(source.getCardNumber()); if (source instanceof Card) { target.setCopySourceCard(source); } } target.setName(sourceObj.getName()); target.getColor(null).setColor(sourceObj.getColor(null)); target.getManaCost().clear(); target.getManaCost().add(sourceObj.getManaCost()); target.getCardType().clear(); for (CardType type : sourceObj.getCardType()) { target.getCardType().add(type); } target.getSubtype().clear(); for (String type : sourceObj.getSubtype()) { target.getSubtype().add(type); } target.getSupertype().clear(); for (String type : sourceObj.getSupertype()) { target.getSupertype().add(type); } target.getAbilities().clear(); for (Ability ability0 : sourceObj.getAbilities()) { Ability ability = ability0.copy(); ability.newId(); ability.setSourceId(target.getId()); target.addAbility(ability); } target.getPower().modifyBaseValue(sourceObj.getPower().getBaseValueModified()); target.getToughness().modifyBaseValue(sourceObj.getToughness().getBaseValueModified()); return target; }
@Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (player == null || sourceObject == null) { return false; } int xValue; xValue = source.getManaCostsToPay().getX(); Cards cards = new CardsImpl(Zone.PICK); int count = Math.min(player.getLibrary().size(), xValue); for (int i = 0; i < count; i++) { Card card = player.getLibrary().removeFromTop(game); if (card != null) { cards.add(card); game.setZone(card.getId(), Zone.PICK); } } player.lookAtCards(sourceObject.getName(), cards, game); TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put into your hand")); if (player.choose(Outcome.DrawCard, cards, target, game)) { Card card = cards.get(target.getFirstTarget(), game); if (card != null) { cards.remove(card); card.moveToZone(Zone.HAND, source.getSourceId(), game, false); game.informPlayers( sourceObject.getName() + ": " + player.getLogName() + " puts a card into his or her hand"); } } target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library")); if (cards.size() > 0) { game.informPlayers( new StringBuilder(sourceObject.getName()) .append(": ") .append(player.getLogName()) .append(" puts ") .append(cards.size() == 1 ? "a" : cards.size()) .append(" card") .append(cards.size() > 1 ? "s" : "") .append(" on the bottom of his or her library") .toString()); } while (player.isInGame() && cards.size() > 1) { player.choose(Outcome.Neutral, cards, target, game); Card card = cards.get(target.getFirstTarget(), game); if (card != null) { cards.remove(card); card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false); } target.clearChosen(); } if (cards.size() == 1) { Card card = cards.get(cards.iterator().next(), game); card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false); } return true; }
/** * @param game * @param playerId * @param forceChange - does only work for targets with maximal one targetId * @param onlyOneTarget - 114.6b one target must be changed to another target * @return */ public boolean chooseNewTargets( Game game, UUID playerId, boolean forceChange, boolean onlyOneTarget) { Player player = game.getPlayer(playerId); if (player != null) { for (SpellAbility spellAbility : spellAbilities) { for (Target target : spellAbility.getTargets()) { Target newTarget = target.copy(); newTarget.clearChosen(); for (UUID targetId : target.getTargets()) { MageObject object = game.getObject(targetId); String name = null; if (object == null) { Player targetPlayer = game.getPlayer(targetId); if (targetPlayer != null) { name = targetPlayer.getName(); } } else { name = object.getName(); } if (name != null && (forceChange || player.chooseUse( spellAbility.getEffects().get(0).getOutcome(), "Change target from " + name + "?", game))) { if (forceChange && target.possibleTargets(this.getSourceId(), playerId, game).size() > 1) { int iteration = 0; do { if (iteration > 0) { game.informPlayer( player, "You may only select exactly one target that must be different from the origin target!"); } iteration++; newTarget.clearChosen(); player.chooseTarget( spellAbility.getEffects().get(0).getOutcome(), newTarget, spellAbility, game); } while (targetId.equals(newTarget.getFirstTarget()) || newTarget.getTargets().size() != 1); } else { if (!player.chooseTarget( spellAbility.getEffects().get(0).getOutcome(), newTarget, spellAbility, game)) { newTarget.addTarget(targetId, spellAbility, game, false); } } } else { newTarget.addTarget(targetId, spellAbility, game, false); } } target.clearChosen(); for (UUID newTargetId : newTarget.getTargets()) { target.addTarget(newTargetId, spellAbility, game, false); } } } return true; } return false; }