Search in sources :

Example 6 with AttachEffect

use of mage.abilities.effects.common.AttachEffect in project mage by magefree.

the class TokenImpl method putOntoBattlefieldHelper.

private static void putOntoBattlefieldHelper(CreateTokenEvent event, Game game, Ability source, boolean tapped, boolean attacking, UUID attackedPlayer, boolean created) {
    Player controller = game.getPlayer(event.getPlayerId());
    if (controller == null) {
        return;
    }
    for (Map.Entry<Token, Integer> entry : event.getTokens().entrySet()) {
        Token token = entry.getKey();
        int amount = entry.getValue();
        String setCode = token instanceof TokenImpl ? ((TokenImpl) token).getSetCode(game, event.getSourceId()) : null;
        List<Permanent> needTokens = new ArrayList<>();
        List<Permanent> allowedTokens = new ArrayList<>();
        // prepare tokens to enter
        for (int i = 0; i < amount; i++) {
            // use event.getPlayerId() as controller cause it can be replaced by replacement effect
            PermanentToken newPermanent = new PermanentToken(token, event.getPlayerId(), setCode, game);
            game.getState().addCard(newPermanent);
            needTokens.add(newPermanent);
            game.getPermanentsEntering().put(newPermanent.getId(), newPermanent);
            newPermanent.setTapped(tapped);
            ZoneChangeEvent emptyEvent = new ZoneChangeEvent(newPermanent, newPermanent.getControllerId(), Zone.OUTSIDE, Zone.BATTLEFIELD);
            // tokens zcc must simulate card's zcc too keep copied card/spell settings
            // (example: etb's kicker ability of copied creature spell, see tests with Deathforge Shaman)
            newPermanent.updateZoneChangeCounter(game, emptyEvent);
        }
        // check ETB effects
        game.setScopeRelevant(true);
        for (Permanent permanent : needTokens) {
            if (permanent.entersBattlefield(source, game, Zone.OUTSIDE, true)) {
                allowedTokens.add(permanent);
            } else {
                game.getPermanentsEntering().remove(permanent.getId());
            }
        }
        game.setScopeRelevant(false);
        // put allowed tokens to play
        int createOrder = game.getState().getNextPermanentOrderNumber();
        for (Permanent permanent : allowedTokens) {
            game.addPermanent(permanent, createOrder);
            permanent.setZone(Zone.BATTLEFIELD, game);
            game.getPermanentsEntering().remove(permanent.getId());
            // keep tokens ids
            if (token instanceof TokenImpl) {
                ((TokenImpl) token).lastAddedTokenIds.add(permanent.getId());
                ((TokenImpl) token).lastAddedTokenId = permanent.getId();
            }
            // created token events
            ZoneChangeEvent zccEvent = new ZoneChangeEvent(permanent, permanent.getControllerId(), Zone.OUTSIDE, Zone.BATTLEFIELD);
            game.addSimultaneousEvent(zccEvent);
            if (permanent instanceof PermanentToken && created) {
                game.addSimultaneousEvent(new CreatedTokenEvent(source, (PermanentToken) permanent));
            }
            // code refactored from CopyPermanentEffect
            if (permanent.getSubtype().contains(SubType.AURA)) {
                Outcome auraOutcome = Outcome.BoostCreature;
                Target auraTarget = null;
                // attach - search effect in spell ability (example: cast Utopia Sprawl, cast Estrid's Invocation on it)
                for (Ability ability : permanent.getAbilities()) {
                    if (!(ability instanceof SpellAbility)) {
                        continue;
                    }
                    auraOutcome = ability.getEffects().getOutcome(ability);
                    for (Effect effect : ability.getEffects()) {
                        if (!(effect instanceof AttachEffect)) {
                            continue;
                        }
                        if (permanent.getSpellAbility().getTargets().size() > 0) {
                            auraTarget = permanent.getSpellAbility().getTargets().get(0);
                        }
                    }
                }
                // enchant - search in all abilities (example: cast Estrid's Invocation on enchanted creature by Estrid, the Masked second ability, cast Estrid's Invocation on it)
                if (auraTarget == null) {
                    for (Ability ability : permanent.getAbilities()) {
                        if (!(ability instanceof EnchantAbility)) {
                            continue;
                        }
                        auraOutcome = ability.getEffects().getOutcome(ability);
                        if (ability.getTargets().size() > 0) {
                            // Animate Dead don't have targets
                            auraTarget = ability.getTargets().get(0);
                        }
                    }
                }
                // if this is a copy of a copy, the copy's target has been copied and needs to be cleared
                if (auraTarget == null) {
                    break;
                }
                // clear selected target
                if (auraTarget.getFirstTarget() != null) {
                    auraTarget.remove(auraTarget.getFirstTarget());
                }
                // select new target
                auraTarget.setNotTarget(true);
                if (!controller.choose(auraOutcome, auraTarget, source.getSourceId(), game)) {
                    break;
                }
                UUID targetId = auraTarget.getFirstTarget();
                Permanent targetPermanent = game.getPermanent(targetId);
                Player targetPlayer = game.getPlayer(targetId);
                if (targetPermanent != null) {
                    targetPermanent.addAttachment(permanent.getId(), source, game);
                } else if (targetPlayer != null) {
                    targetPlayer.addAttachment(permanent.getId(), source, game);
                }
            }
            // must attack
            if (attacking && game.getCombat() != null && game.getActivePlayerId().equals(permanent.getControllerId())) {
                game.getCombat().addAttackingCreature(permanent.getId(), game, attackedPlayer);
            }
            // game logs
            if (created) {
                game.informPlayers(controller.getLogName() + " creates a " + permanent.getLogName() + " token");
            } else {
                game.informPlayers(permanent.getLogName() + " enters the battlefield as a token under " + controller.getLogName() + "'s control'");
            }
        }
    }
    // Needed to do it here without LKIReset i.e. do get SwordOfTheMeekTest running correctly.
    game.getState().applyEffects(game);
}
Also used : EnchantAbility(mage.abilities.keyword.EnchantAbility) SpellAbility(mage.abilities.SpellAbility) Ability(mage.abilities.Ability) Player(mage.players.Player) Permanent(mage.game.permanent.Permanent) CreatedTokenEvent(mage.game.events.CreatedTokenEvent) PermanentToken(mage.game.permanent.PermanentToken) PermanentToken(mage.game.permanent.PermanentToken) SpellAbility(mage.abilities.SpellAbility) EnchantAbility(mage.abilities.keyword.EnchantAbility) AttachEffect(mage.abilities.effects.common.AttachEffect) ZoneChangeEvent(mage.game.events.ZoneChangeEvent) Target(mage.target.Target) Outcome(mage.constants.Outcome) Effect(mage.abilities.effects.Effect) AttachEffect(mage.abilities.effects.common.AttachEffect)

Example 7 with AttachEffect

use of mage.abilities.effects.common.AttachEffect in project mage by magefree.

the class AuraReplacementEffect method replaceEvent.

@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
    Zone fromZone = ((ZoneChangeEvent) event).getFromZone();
    Card card = game.getCard(event.getTargetId());
    if (card == null) {
        return false;
    }
    Card firstCardFace = null;
    if (game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId()) != null) {
        firstCardFace = card;
        card = card.getSecondCardFace();
        if (!card.isEnchantment(game) || !card.hasSubtype(SubType.AURA, game)) {
            return false;
        }
    }
    // Aura cards that go to battlefield face down (Manifest) don't have to select targets
    if (card.isFaceDown(game)) {
        return false;
    }
    // Aura enters the battlefield attached
    Object object = game.getState().getValue("attachTo:" + card.getId());
    if (object != null) {
        if (object instanceof Permanent) {
            // Aura is attached to a permanent on the battlefield
            return false;
        }
        if (object instanceof UUID) {
            Player player = game.getPlayer((UUID) object);
            if (player != null) {
                // Aura is attached to a player
                return false;
            }
        }
    }
    UUID targetId = null;
    MageObject sourceObject = game.getObject(event.getSourceId());
    boolean enchantCardInGraveyard = false;
    if (sourceObject instanceof StackAbility) {
        StackAbility stackAbility = (StackAbility) sourceObject;
        if (!stackAbility.getEffects().isEmpty()) {
            targetId = stackAbility.getEffects().get(0).getTargetPointer().getFirst(game, stackAbility);
        }
    }
    // So continuousEffects are removed if previous effect of the same ability did move objects that cause continuous effects
    game.applyEffects();
    Player controllingPlayer = null;
    if (targetId == null) {
        SpellAbility spellAbility = card.getSpellAbility();
        if (spellAbility.getTargets().isEmpty()) {
            for (Ability ability : card.getAbilities(game)) {
                if ((ability instanceof SpellAbility) && SpellAbilityType.BASE_ALTERNATE == ((SpellAbility) ability).getSpellAbilityType() && !ability.getTargets().isEmpty()) {
                    spellAbility = (SpellAbility) ability;
                    break;
                }
            }
        }
        if (spellAbility.getTargets().isEmpty()) {
            return false;
        }
        Target target = spellAbility.getTargets().get(0).copy();
        Outcome auraOutcome = Outcome.BoostCreature;
        for (Effect effect : spellAbility.getEffects()) {
            if (effect instanceof AttachEffect) {
                auraOutcome = effect.getOutcome();
                break;
            }
        }
        enchantCardInGraveyard = target instanceof TargetCardInGraveyard;
        if (target != null) {
            // always not target because this way it's not handled targeted
            target.setNotTarget(true);
            // necessary if e.g. aura is blinked multiple times
            target.clearChosen();
        }
        if (event.getPlayerId() != null) {
            controllingPlayer = game.getPlayer(event.getPlayerId());
        } else {
            controllingPlayer = game.getPlayer(card.getOwnerId());
        }
        if (target != null && controllingPlayer != null && controllingPlayer.choose(auraOutcome, target, card.getId(), game)) {
            targetId = target.getFirstTarget();
        }
    }
    Card targetCard = null;
    Permanent targetPermanent = null;
    if (enchantCardInGraveyard) {
        targetCard = game.getCard(targetId);
    } else {
        targetPermanent = game.getPermanent(targetId);
    }
    Player targetPlayer = game.getPlayer(targetId);
    if (targetCard != null || targetPermanent != null || targetPlayer != null) {
        if (firstCardFace != null) {
            // transforming card. remove first face (original card) from old zone
            firstCardFace.removeFromZone(game, fromZone, source);
        } else {
            card.removeFromZone(game, fromZone, source);
        }
        PermanentCard permanent = new PermanentCard(card, (controllingPlayer == null ? card.getOwnerId() : controllingPlayer.getId()), game);
        ZoneChangeEvent zoneChangeEvent = new ZoneChangeEvent(permanent, event.getPlayerId(), fromZone, Zone.BATTLEFIELD);
        permanent.updateZoneChangeCounter(game, zoneChangeEvent);
        game.addPermanent(permanent, 0);
        card.setZone(Zone.BATTLEFIELD, game);
        if (permanent.entersBattlefield(source, game, fromZone, true)) {
            String attachToName = null;
            if (targetCard != null) {
                permanent.attachTo(targetCard.getId(), source, game);
                attachToName = targetCard.getLogName();
            } else if (targetPermanent != null) {
                targetPermanent.addAttachment(permanent.getId(), source, game);
                attachToName = targetPermanent.getLogName();
            } else if (targetPlayer != null) {
                targetPlayer.addAttachment(permanent.getId(), source, game);
                attachToName = targetPlayer.getLogName();
            }
            game.applyEffects();
            game.fireEvent(zoneChangeEvent);
            if (!game.isSimulation()) {
                if (controllingPlayer != null && fromZone != null && permanent != null) {
                    game.informPlayers(controllingPlayer.getLogName() + " puts " + (card.getLogName()) + " from " + fromZone.toString().toLowerCase(Locale.ENGLISH) + " onto the Battlefield attached to " + attachToName);
                }
            }
            return true;
        }
    }
    return false;
}
Also used : StackAbility(mage.game.stack.StackAbility) SpellAbility(mage.abilities.SpellAbility) TransformAbility(mage.abilities.keyword.TransformAbility) Ability(mage.abilities.Ability) Player(mage.players.Player) Permanent(mage.game.permanent.Permanent) MageObject(mage.MageObject) SpellAbility(mage.abilities.SpellAbility) StackAbility(mage.game.stack.StackAbility) PermanentCard(mage.game.permanent.PermanentCard) Card(mage.cards.Card) AttachEffect(mage.abilities.effects.common.AttachEffect) ZoneChangeEvent(mage.game.events.ZoneChangeEvent) Target(mage.target.Target) TargetCardInGraveyard(mage.target.common.TargetCardInGraveyard) MageObject(mage.MageObject) AttachEffect(mage.abilities.effects.common.AttachEffect) UUID(java.util.UUID) PermanentCard(mage.game.permanent.PermanentCard)

Example 8 with AttachEffect

use of mage.abilities.effects.common.AttachEffect in project mage by magefree.

the class BronzehideLionContinuousEffect method apply.

@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
    if (game.getState().getZoneChangeCounter(source.getSourceId()) > zoneChangeCounter) {
        discard();
    }
    Permanent sourceObject = game.getPermanent(source.getSourceId());
    if (sourceObject == null) {
        sourceObject = game.getPermanentEntering(source.getSourceId());
    }
    if (sourceObject == null) {
        return false;
    }
    Permanent lion = sourceObject;
    switch(layer) {
        case TypeChangingEffects_4:
            lion.removeAllCardTypes(game);
            lion.addCardType(game, CardType.ENCHANTMENT);
            lion.removeAllSubTypes(game);
            lion.addSubType(game, SubType.AURA);
            break;
        case AbilityAddingRemovingEffects_6:
            List<Ability> toRemove = new ArrayList<>();
            for (Ability ability : lion.getAbilities(game)) {
                if (!lion.getSpellAbility().equals(ability)) {
                    toRemove.add(ability);
                }
            }
            lion.removeAbilities(toRemove, source.getSourceId(), game);
            lion.getSpellAbility().getTargets().clear();
            lion.getSpellAbility().getEffects().clear();
            TargetPermanent auraTarget = new TargetControlledCreaturePermanent();
            lion.getSpellAbility().addTarget(auraTarget);
            lion.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
            lion.addAbility(new EnchantAbility(auraTarget.getTargetName()), source.getSourceId(), game);
            // add the activated ability
            activatedAbility.setControllerId(source.getControllerId());
            lion.addAbility(activatedAbility, source.getSourceId(), game);
            break;
    }
    return true;
}
Also used : IndestructibleAbility(mage.abilities.keyword.IndestructibleAbility) SimpleActivatedAbility(mage.abilities.common.SimpleActivatedAbility) DiesSourceTriggeredAbility(mage.abilities.common.DiesSourceTriggeredAbility) EnchantAbility(mage.abilities.keyword.EnchantAbility) Ability(mage.abilities.Ability) Permanent(mage.game.permanent.Permanent) TargetControlledCreaturePermanent(mage.target.common.TargetControlledCreaturePermanent) TargetPermanent(mage.target.TargetPermanent) ArrayList(java.util.ArrayList) TargetPermanent(mage.target.TargetPermanent) EnchantAbility(mage.abilities.keyword.EnchantAbility) TargetControlledCreaturePermanent(mage.target.common.TargetControlledCreaturePermanent) AttachEffect(mage.abilities.effects.common.AttachEffect)

Aggregations

AttachEffect (mage.abilities.effects.common.AttachEffect)8 Permanent (mage.game.permanent.Permanent)6 Ability (mage.abilities.Ability)4 Player (mage.players.Player)4 SpellAbility (mage.abilities.SpellAbility)3 Effect (mage.abilities.effects.Effect)3 EnchantAbility (mage.abilities.keyword.EnchantAbility)3 Card (mage.cards.Card)3 Target (mage.target.Target)3 TargetPermanent (mage.target.TargetPermanent)3 FixedTarget (mage.target.targetpointer.FixedTarget)3 UUID (java.util.UUID)2 OneShotEffect (mage.abilities.effects.OneShotEffect)2 ZoneChangeEvent (mage.game.events.ZoneChangeEvent)2 TargetControlledCreaturePermanent (mage.target.common.TargetControlledCreaturePermanent)2 ArrayList (java.util.ArrayList)1 MageObject (mage.MageObject)1 SpecialAction (mage.abilities.SpecialAction)1 DiesSourceTriggeredAbility (mage.abilities.common.DiesSourceTriggeredAbility)1 EntersBattlefieldTriggeredAbility (mage.abilities.common.EntersBattlefieldTriggeredAbility)1