Search in sources :

Example 1 with PermanentMeld

use of mage.game.permanent.PermanentMeld in project mage by magefree.

the class ZonesHandler method maybeRemoveFromSourceZone.

private static boolean maybeRemoveFromSourceZone(ZoneChangeInfo info, Game game, Ability source) {
    ZoneChangeEvent event = info.event;
    // Handle Unmelded Cards
    if (info instanceof ZoneChangeInfo.Unmelded) {
        ZoneChangeInfo.Unmelded unmelded = (ZoneChangeInfo.Unmelded) info;
        MeldCard meld = game.getMeldCard(event.getTargetId());
        for (Iterator<ZoneChangeInfo> itr = unmelded.subInfo.iterator(); itr.hasNext(); ) {
            ZoneChangeInfo subInfo = itr.next();
            if (!maybeRemoveFromSourceZone(subInfo, game, source)) {
                itr.remove();
            } else if (Objects.equals(subInfo.event.getTargetId(), meld.getTopHalfCard().getId())) {
                meld.setTopLastZoneChangeCounter(meld.getTopHalfCard().getZoneChangeCounter(game));
            } else if (Objects.equals(subInfo.event.getTargetId(), meld.getBottomHalfCard().getId())) {
                meld.setBottomLastZoneChangeCounter(meld.getBottomHalfCard().getZoneChangeCounter(game));
            }
        }
        if (unmelded.subInfo.isEmpty()) {
            return false;
        }
        // We arbitrarily prefer the bottom half card. This should never be relevant.
        meld.updateZoneChangeCounter(game, unmelded.subInfo.get(unmelded.subInfo.size() - 1).event);
        return true;
    }
    // Handle all normal cases
    Card card = getTargetCard(game, event.getTargetId());
    if (card == null) {
        // If we can't find the card we can't remove it.
        return false;
    }
    boolean success = false;
    if (info.faceDown) {
        card.setFaceDown(true, game);
    } else if (event.getToZone().equals(Zone.BATTLEFIELD)) {
        if (!card.isPermanent(game) && (!card.isTransformable() || Boolean.FALSE.equals(game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId())))) {
            // Non permanents (Instants, Sorceries, ... stay in the zone they are if an abilty/effect tries to move it to the battlefield
            return false;
        }
    }
    if (!game.replaceEvent(event)) {
        Zone fromZone = event.getFromZone();
        if (event.getToZone() == Zone.BATTLEFIELD) {
            // prepare card and permanent
            // If needed take attributes from the spell (e.g. color of spell was changed)
            card = takeAttributesFromSpell(card, event, game);
            // controlling player can be replaced so use event player now
            Permanent permanent;
            if (card instanceof MeldCard) {
                permanent = new PermanentMeld(card, event.getPlayerId(), game);
            } else if (card instanceof ModalDoubleFacesCard) {
                // main mdf card must be processed before that call (e.g. only halfes can be moved to battlefield)
                throw new IllegalStateException("Unexpected trying of move mdf card to battlefield instead half");
            } else if (card instanceof Permanent) {
                throw new IllegalStateException("Unexpected trying of move permanent to battlefield instead card");
            } else {
                permanent = new PermanentCard(card, event.getPlayerId(), game);
            }
            // put onto battlefield with possible counters
            game.getPermanentsEntering().put(permanent.getId(), permanent);
            card.checkForCountersToAdd(permanent, source, game);
            permanent.setTapped(info instanceof ZoneChangeInfo.Battlefield && ((ZoneChangeInfo.Battlefield) info).tapped);
            permanent.setFaceDown(info.faceDown, game);
            if (info.faceDown) {
                card.setFaceDown(false, game);
            }
            // make sure the controller of all continuous effects of this card are switched to the current controller
            game.setScopeRelevant(true);
            game.getContinuousEffects().setController(permanent.getId(), permanent.getControllerId());
            if (permanent.entersBattlefield(source, game, fromZone, true) && card.removeFromZone(game, fromZone, source)) {
                success = true;
                event.setTarget(permanent);
            } else {
                // revert controller to owner if permanent does not enter
                game.getContinuousEffects().setController(permanent.getId(), permanent.getOwnerId());
                game.getPermanentsEntering().remove(permanent.getId());
            }
            game.setScopeRelevant(false);
        } else if (event.getTarget() != null) {
            card.setFaceDown(info.faceDown, game);
            Permanent target = event.getTarget();
            success = target.removeFromZone(game, fromZone, source) && game.getPlayer(target.getControllerId()).removeFromBattlefield(target, source, game);
        } else {
            card.setFaceDown(info.faceDown, game);
            success = card.removeFromZone(game, fromZone, source);
        }
    }
    if (success) {
        // KickerTest do many tests for token's zcc
        if (event.getToZone() == Zone.BATTLEFIELD && event.getTarget() != null) {
            event.getTarget().updateZoneChangeCounter(game, event);
        } else if (!(card instanceof Permanent)) {
            card.updateZoneChangeCounter(game, event);
        }
    }
    return success;
}
Also used : Permanent(mage.game.permanent.Permanent) Zone(mage.constants.Zone) FilterCard(mage.filter.FilterCard) TargetCard(mage.target.TargetCard) PermanentCard(mage.game.permanent.PermanentCard) ZoneChangeEvent(mage.game.events.ZoneChangeEvent) PermanentMeld(mage.game.permanent.PermanentMeld) PermanentCard(mage.game.permanent.PermanentCard)

Example 2 with PermanentMeld

use of mage.game.permanent.PermanentMeld in project mage by magefree.

the class YorionSkyNomadEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player controller = game.getPlayer(source.getControllerId());
    MageObject sourceObject = source.getSourceObject(game);
    if (sourceObject == null || controller == null) {
        return false;
    }
    TargetPermanent target = new TargetPermanent(0, Integer.MAX_VALUE, filter, true);
    controller.choose(outcome, target, source.getSourceId(), game);
    Set<Card> toExile = target.getTargets().stream().map(game::getPermanent).collect(Collectors.toSet());
    UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
    controller.moveCardsToExile(toExile, source, game, true, exileId, sourceObject.getIdName());
    Cards cardsToReturn = new CardsImpl();
    for (Card exiled : toExile) {
        if (exiled instanceof PermanentMeld) {
            MeldCard meldCard = (MeldCard) ((PermanentCard) exiled).getCard();
            Card topCard = meldCard.getTopHalfCard();
            Card bottomCard = meldCard.getBottomHalfCard();
            if (topCard.getZoneChangeCounter(game) == meldCard.getTopLastZoneChangeCounter()) {
                cardsToReturn.add(topCard);
            }
            if (bottomCard.getZoneChangeCounter(game) == meldCard.getBottomLastZoneChangeCounter()) {
                cardsToReturn.add(bottomCard);
            }
        } else if (exiled.getZoneChangeCounter(game) == game.getState().getZoneChangeCounter(exiled.getId()) - 1) {
            cardsToReturn.add(exiled);
        }
    }
    Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false);
    effect.setTargetPointer(new FixedTargets(cardsToReturn, game));
    AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect);
    game.addDelayedTriggeredAbility(delayedAbility, source);
    return true;
}
Also used : Player(mage.players.Player) FixedTargets(mage.target.targetpointer.FixedTargets) MageObject(mage.MageObject) ReturnToBattlefieldUnderOwnerControlTargetEffect(mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect) PermanentCard(mage.game.permanent.PermanentCard) AtTheBeginOfNextEndStepDelayedTriggeredAbility(mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility) PermanentMeld(mage.game.permanent.PermanentMeld) ReturnToBattlefieldUnderOwnerControlTargetEffect(mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect) OneShotEffect(mage.abilities.effects.OneShotEffect) Effect(mage.abilities.effects.Effect) TargetPermanent(mage.target.TargetPermanent) UUID(java.util.UUID)

Example 3 with PermanentMeld

use of mage.game.permanent.PermanentMeld in project mage by magefree.

the class CardUtil method putCardOntoBattlefieldWithEffects.

/**
 * Put card to battlefield without resolve (for cheats and tests only)
 *
 * @param source  must be non null (if you need it empty then use fakeSourceAbility)
 * @param game
 * @param newCard
 * @param player
 */
public static void putCardOntoBattlefieldWithEffects(Ability source, Game game, Card newCard, Player player) {
    // same logic as ZonesHandler->maybeRemoveFromSourceZone
    // workaround to put real permanent from one side (example: you call mdf card by cheats)
    Card permCard = getDefaultCardSideForBattlefield(game, newCard);
    // prepare card and permanent
    permCard.setZone(Zone.BATTLEFIELD, game);
    permCard.setOwnerId(player.getId());
    PermanentCard permanent;
    if (permCard instanceof MeldCard) {
        permanent = new PermanentMeld(permCard, player.getId(), game);
    } else {
        permanent = new PermanentCard(permCard, player.getId(), game);
    }
    // put onto battlefield with possible counters
    game.getPermanentsEntering().put(permanent.getId(), permanent);
    permCard.checkForCountersToAdd(permanent, source, game);
    permanent.entersBattlefield(source, game, Zone.OUTSIDE, false);
    game.addPermanent(permanent, game.getState().getNextPermanentOrderNumber());
    game.getPermanentsEntering().remove(permanent.getId());
    // workaround for special tapped status from test framework's command (addCard)
    if (permCard instanceof PermanentCard && ((PermanentCard) permCard).isTapped()) {
        permanent.setTapped(true);
    }
    // remove sickness
    permanent.removeSummoningSickness();
    // init effects on static abilities (init continuous effects; warning, game state contains copy)
    for (ContinuousEffect effect : game.getState().getContinuousEffects().getLayeredEffects(game)) {
        Optional<Ability> ability = game.getState().getContinuousEffects().getLayeredEffectAbilities(effect).stream().findFirst();
        if (ability.isPresent() && permanent.getId().equals(ability.get().getSourceId())) {
            effect.init(ability.get(), game, player.getId());
        }
    }
}
Also used : SpellAbility(mage.abilities.SpellAbility) Ability(mage.abilities.Ability) PermanentMeld(mage.game.permanent.PermanentMeld) ContinuousEffect(mage.abilities.effects.ContinuousEffect) PermanentCard(mage.game.permanent.PermanentCard) PermanentCard(mage.game.permanent.PermanentCard)

Example 4 with PermanentMeld

use of mage.game.permanent.PermanentMeld in project mage by magefree.

the class EerieInterludeEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player controller = game.getPlayer(source.getControllerId());
    MageObject sourceObject = source.getSourceObject(game);
    if (sourceObject != null && controller != null) {
        Set<Card> toExile = new HashSet<>();
        for (UUID targetId : getTargetPointer().getTargets(game, source)) {
            Permanent targetCreature = game.getPermanent(targetId);
            if (targetCreature != null) {
                toExile.add(targetCreature);
            }
        }
        UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
        controller.moveCardsToExile(toExile, source, game, true, exileId, sourceObject.getIdName());
        Cards cardsToReturn = new CardsImpl();
        for (Card exiled : toExile) {
            if (exiled instanceof PermanentMeld) {
                MeldCard meldCard = (MeldCard) ((PermanentCard) exiled).getCard();
                Card topCard = meldCard.getTopHalfCard();
                Card bottomCard = meldCard.getBottomHalfCard();
                if (topCard.getZoneChangeCounter(game) == meldCard.getTopLastZoneChangeCounter()) {
                    cardsToReturn.add(topCard);
                }
                if (bottomCard.getZoneChangeCounter(game) == meldCard.getBottomLastZoneChangeCounter()) {
                    cardsToReturn.add(bottomCard);
                }
            } else if (exiled.getZoneChangeCounter(game) == game.getState().getZoneChangeCounter(exiled.getId()) - 1) {
                cardsToReturn.add(exiled);
            }
        }
        Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false);
        effect.setTargetPointer(new FixedTargets(cardsToReturn, game));
        AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect);
        game.addDelayedTriggeredAbility(delayedAbility, source);
        return true;
    }
    return false;
}
Also used : Player(mage.players.Player) Permanent(mage.game.permanent.Permanent) FilterControlledCreaturePermanent(mage.filter.common.FilterControlledCreaturePermanent) TargetControlledCreaturePermanent(mage.target.common.TargetControlledCreaturePermanent) FixedTargets(mage.target.targetpointer.FixedTargets) MageObject(mage.MageObject) ReturnToBattlefieldUnderOwnerControlTargetEffect(mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect) PermanentCard(mage.game.permanent.PermanentCard) AtTheBeginOfNextEndStepDelayedTriggeredAbility(mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility) PermanentMeld(mage.game.permanent.PermanentMeld) ReturnToBattlefieldUnderOwnerControlTargetEffect(mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect) OneShotEffect(mage.abilities.effects.OneShotEffect) Effect(mage.abilities.effects.Effect) UUID(java.util.UUID) HashSet(java.util.HashSet)

Aggregations

PermanentCard (mage.game.permanent.PermanentCard)4 PermanentMeld (mage.game.permanent.PermanentMeld)4 UUID (java.util.UUID)2 MageObject (mage.MageObject)2 AtTheBeginOfNextEndStepDelayedTriggeredAbility (mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility)2 Effect (mage.abilities.effects.Effect)2 OneShotEffect (mage.abilities.effects.OneShotEffect)2 ReturnToBattlefieldUnderOwnerControlTargetEffect (mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect)2 Permanent (mage.game.permanent.Permanent)2 Player (mage.players.Player)2 FixedTargets (mage.target.targetpointer.FixedTargets)2 HashSet (java.util.HashSet)1 Ability (mage.abilities.Ability)1 SpellAbility (mage.abilities.SpellAbility)1 ContinuousEffect (mage.abilities.effects.ContinuousEffect)1 Zone (mage.constants.Zone)1 FilterCard (mage.filter.FilterCard)1 FilterControlledCreaturePermanent (mage.filter.common.FilterControlledCreaturePermanent)1 ZoneChangeEvent (mage.game.events.ZoneChangeEvent)1 TargetCard (mage.target.TargetCard)1