Search in sources :

Example 86 with StackObject

use of mage.game.stack.StackObject in project mage by magefree.

the class TomikDistinguishedAdvokistRestrictionEffect method applies.

@Override
public boolean applies(GameEvent event, Ability source, Game game) {
    Card targetCard = game.getCard(event.getTargetId());
    StackObject stackObject = game.getStack().getStackObject(event.getSourceId());
    Player player = game.getPlayer(source.getControllerId());
    return targetCard != null && stackObject != null && player != null && player.hasOpponent(stackObject.getControllerId(), game) && game.getState().getZone(targetCard.getId()) == Zone.GRAVEYARD && targetCard.isLand(game);
}
Also used : Player(mage.players.Player) ObjectSourcePlayer(mage.filter.predicate.ObjectSourcePlayer) FilterStackObject(mage.filter.FilterStackObject) StackObject(mage.game.stack.StackObject) Card(mage.cards.Card)

Example 87 with StackObject

use of mage.game.stack.StackObject in project mage by magefree.

the class ExileTargetEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player controller = game.getPlayer(source.getControllerId());
    if (controller != null) {
        Set<Card> toExile = new LinkedHashSet<>();
        if (multitargetHandling && targetPointer instanceof FirstTargetPointer && (source.getTargets().size() > 1 || (source.getTargets().size() > 0 && source.getTargets().get(0).getTargets().size() > 1))) {
            for (Target target : source.getTargets()) {
                for (UUID targetId : target.getTargets()) {
                    Permanent permanent = game.getPermanent(targetId);
                    if (permanent != null && permanent.isPhasedIn()) {
                        Zone currentZone = game.getState().getZone(permanent.getId());
                        if (currentZone != Zone.EXILED && (onlyFromZone == null || onlyFromZone == Zone.BATTLEFIELD)) {
                            toExile.add(permanent);
                        }
                    } else {
                        Card card = game.getCard(targetId);
                        if (card != null) {
                            Zone currentZone = game.getState().getZone(card.getId());
                            if (currentZone != Zone.EXILED && (onlyFromZone == null || onlyFromZone == currentZone)) {
                                toExile.add(card);
                            }
                        } else {
                            StackObject stackObject = game.getStack().getStackObject(targetId);
                            if (stackObject instanceof Spell) {
                                toExile.add((Spell) stackObject);
                            }
                        }
                    }
                }
            }
        } else {
            for (UUID targetId : getTargetPointer().getTargets(game, source)) {
                Permanent permanent = game.getPermanent(targetId);
                if (permanent != null && permanent.isPhasedIn()) {
                    Zone currentZone = game.getState().getZone(permanent.getId());
                    if (currentZone != Zone.EXILED && (onlyFromZone == null || onlyFromZone == Zone.BATTLEFIELD)) {
                        toExile.add(permanent);
                    }
                } else {
                    Card card = game.getCard(targetId);
                    if (card != null) {
                        Zone currentZone = game.getState().getZone(card.getId());
                        if (currentZone != Zone.EXILED && (onlyFromZone == null || onlyFromZone == currentZone)) {
                            toExile.add(card);
                        }
                    } else {
                        StackObject stackObject = game.getStack().getStackObject(targetId);
                        if (stackObject instanceof Spell) {
                            toExile.add((Spell) stackObject);
                        }
                    }
                }
            }
        }
        if (toSourceExileZone) {
            MageObject sourceObject = source.getSourceObject(game);
            exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
            if (sourceObject != null) {
                exileZone = sourceObject.getIdName();
            }
        }
        controller.moveCardsToExile(toExile, source, game, withName, exileId, exileZone);
        return true;
    }
    return false;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Player(mage.players.Player) Target(mage.target.Target) Permanent(mage.game.permanent.Permanent) Zone(mage.constants.Zone) StackObject(mage.game.stack.StackObject) MageObject(mage.MageObject) FirstTargetPointer(mage.target.targetpointer.FirstTargetPointer) UUID(java.util.UUID) Spell(mage.game.stack.Spell) Card(mage.cards.Card)

Example 88 with StackObject

use of mage.game.stack.StackObject in project mage by magefree.

the class PermanentImpl method doDamage.

/**
 * @param damageAmount
 * @param attackerId   id of the permanent or player who make damage (source.getSourceId() in most cases)
 * @param source
 * @param game
 * @param preventable
 * @param combat
 * @param markDamage   If true, damage will be dealt later in applyDamage
 *                     method, uses only in inner markDamage.
 * @return
 */
private int doDamage(int damageAmount, UUID attackerId, Ability source, Game game, boolean preventable, boolean combat, boolean markDamage, List<UUID> appliedEffects) {
    int damageDone = 0;
    if (damageAmount < 1 || !canDamage(game.getObject(attackerId), game)) {
        return 0;
    }
    DamageEvent event = new DamagePermanentEvent(objectId, attackerId, controllerId, damageAmount, preventable, combat);
    event.setAppliedEffects(appliedEffects);
    if (game.replaceEvent(event)) {
        return 0;
    }
    int actualDamage = checkProtectionAbilities(event, attackerId, source, game);
    if (actualDamage < 1) {
        return 0;
    }
    int lethal = getLethalDamage(attackerId, game);
    MageObject attacker = game.getObject(attackerId);
    if (this.isCreature(game)) {
        if (checkWither(event, attacker, game)) {
            if (markDamage) {
                // mark damage only
                markDamage(CounterType.M1M1.createInstance(actualDamage), attacker, true);
            } else {
                Ability damageSourceAbility = null;
                if (attacker instanceof Permanent) {
                    damageSourceAbility = ((Permanent) attacker).getSpellAbility();
                }
                // deal damage immediately
                addCounters(CounterType.M1M1.createInstance(actualDamage), game.getControllerId(attackerId), damageSourceAbility, game);
            }
        } else {
            this.damage = CardUtil.overflowInc(this.damage, actualDamage);
        }
    }
    if (this.isPlaneswalker(game)) {
        int loyalty = getCounters(game).getCount(CounterType.LOYALTY);
        int countersToRemove = Math.min(actualDamage, loyalty);
        if (attacker != null && markDamage) {
            markDamage(CounterType.LOYALTY.createInstance(countersToRemove), attacker, false);
        } else {
            removeCounters(CounterType.LOYALTY.getName(), countersToRemove, source, game);
        }
    }
    DamagedEvent damagedEvent = new DamagedPermanentEvent(this.getId(), attackerId, this.getControllerId(), actualDamage, combat);
    damagedEvent.setExcess(actualDamage - lethal);
    game.fireEvent(damagedEvent);
    game.getState().addSimultaneousDamage(damagedEvent, game);
    damageDone = actualDamage;
    if (damageDone < 1) {
        return 0;
    }
    UUID sourceControllerId = null;
    Abilities sourceAbilities = null;
    attacker = game.getPermanentOrLKIBattlefield(attackerId);
    if (attacker == null) {
        StackObject stackObject = game.getStack().getStackObject(attackerId);
        if (stackObject != null) {
            attacker = stackObject.getStackAbility().getSourceObject(game);
        } else {
            attacker = game.getObject(attackerId);
        }
        if (attacker instanceof Spell) {
            sourceAbilities = ((Spell) attacker).getAbilities(game);
            sourceControllerId = ((Spell) attacker).getControllerId();
        } else if (attacker instanceof Card) {
            sourceAbilities = ((Card) attacker).getAbilities(game);
            sourceControllerId = ((Card) attacker).getOwnerId();
        } else if (attacker instanceof CommandObject) {
            sourceControllerId = ((CommandObject) attacker).getControllerId();
            sourceAbilities = attacker.getAbilities();
        } else {
            attacker = null;
        }
    } else {
        sourceAbilities = ((Permanent) attacker).getAbilities(game);
        sourceControllerId = ((Permanent) attacker).getControllerId();
    }
    if (attacker != null && sourceAbilities != null) {
        if (sourceAbilities.containsKey(LifelinkAbility.getInstance().getId())) {
            if (markDamage) {
                game.getPermanent(attackerId).markLifelink(damageDone);
            } else {
                Player player = game.getPlayer(sourceControllerId);
                player.gainLife(damageDone, game, source);
            }
        }
        if (sourceAbilities.containsKey(DeathtouchAbility.getInstance().getId())) {
            deathtouched = true;
        }
        if (dealtDamageByThisTurn == null) {
            dealtDamageByThisTurn = new HashSet<>();
        }
        // Unstable ability - Earl of Squirrel
        if (sourceAbilities.containsKey(SquirrellinkAbility.getInstance().getId())) {
            Player player = game.getPlayer(sourceControllerId);
            new SquirrelToken().putOntoBattlefield(damageDone, game, source, player.getId());
        }
        dealtDamageByThisTurn.add(new MageObjectReference(attacker, game));
    }
    if (attacker == null) {
        game.informPlayers(getLogName() + " gets " + damageDone + " damage");
    } else {
        game.informPlayers(attacker.getLogName() + " deals " + damageDone + " damage to " + getLogName());
    }
    return damageDone;
}
Also used : SpellAbility(mage.abilities.SpellAbility) Ability(mage.abilities.Ability) Player(mage.players.Player) Abilities(mage.abilities.Abilities) MageObject(mage.MageObject) StackObject(mage.game.stack.StackObject) Hint(mage.abilities.hint.Hint) Spell(mage.game.stack.Spell) TargetCard(mage.target.TargetCard) Card(mage.cards.Card) CommandObject(mage.game.command.CommandObject) SquirrelToken(mage.game.permanent.token.SquirrelToken) MageObjectReference(mage.MageObjectReference)

Example 89 with StackObject

use of mage.game.stack.StackObject in project mage by magefree.

the class DjinnIlluminatusGainReplicateEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Permanent djinn = game.getPermanent(source.getSourceId());
    if (djinn == null) {
        return false;
    }
    for (StackObject stackObject : game.getStack()) {
        // only spells cast, so no copies of spells
        if ((stackObject instanceof Spell) && !stackObject.isCopy() && stackObject.isControlledBy(source.getControllerId()) && // verify that the controller of the djinn cast that spell
        djinn.isControlledBy(source.getControllerId()) && !stackObject.getManaCost().isEmpty()) {
            // handle cases like Ancestral Vision
            Spell spell = (Spell) stackObject;
            if (filter.match(stackObject, game)) {
                ReplicateAbility replicateAbility = replicateAbilities.computeIfAbsent(spell.getId(), k -> new ReplicateAbility(spell.getCard(), spell.getSpellAbility().getManaCosts().getText()));
                // Do not copy because paid and # of activations state is handled in the baility
                game.getState().addOtherAbility(spell.getCard(), replicateAbility, false);
            }
        }
    }
    if (game.getStack().isEmpty()) {
        replicateAbilities.clear();
    }
    return true;
}
Also used : Permanent(mage.game.permanent.Permanent) StackObject(mage.game.stack.StackObject) FilterInstantOrSorcerySpell(mage.filter.common.FilterInstantOrSorcerySpell) Spell(mage.game.stack.Spell) ReplicateAbility(mage.abilities.keyword.ReplicateAbility)

Example 90 with StackObject

use of mage.game.stack.StackObject in project mage by magefree.

the class ForceChokeEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player player = game.getPlayer(source.getControllerId());
    StackObject stackObject = (StackObject) game.getObject(getTargetPointer().getFirst(game, source));
    Player objectController = game.getPlayer(stackObject.getControllerId());
    if (player != null) {
        Cost cost = new PayLifeCost(stackObject.getManaValue());
        if (cost.canPay(source, source, objectController.getId(), game) && objectController.chooseUse(Outcome.LoseLife, "Pay " + stackObject.getManaValue() + " life?", source, game) && cost.pay(source, game, source, objectController.getId(), false, null)) {
            objectController.moveCards((Card) stackObject, Zone.HAND, source, game);
        } else {
            game.getStack().counter(stackObject.getId(), source, game);
        }
        return true;
    }
    return false;
}
Also used : Player(mage.players.Player) StackObject(mage.game.stack.StackObject) PayLifeCost(mage.abilities.costs.common.PayLifeCost) PayLifeCost(mage.abilities.costs.common.PayLifeCost) Cost(mage.abilities.costs.Cost)

Aggregations

StackObject (mage.game.stack.StackObject)130 Player (mage.players.Player)63 Permanent (mage.game.permanent.Permanent)57 Spell (mage.game.stack.Spell)41 MageObject (mage.MageObject)37 UUID (java.util.UUID)36 Card (mage.cards.Card)29 Target (mage.target.Target)17 TargetPermanent (mage.target.TargetPermanent)15 FilterCard (mage.filter.FilterCard)14 Ability (mage.abilities.Ability)13 FilterPermanent (mage.filter.FilterPermanent)13 StackAbility (mage.game.stack.StackAbility)13 FixedTarget (mage.target.targetpointer.FixedTarget)12 FilterCreaturePermanent (mage.filter.common.FilterCreaturePermanent)11 HashSet (java.util.HashSet)10 Effect (mage.abilities.effects.Effect)9 Game (mage.game.Game)9 MageObjectReference (mage.MageObjectReference)8 Cost (mage.abilities.costs.Cost)8