Search in sources :

Example 76 with StackObject

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

the class PlayerImpl method getPlayable.

/**
 * Returns a list of all available spells and abilities the player can
 * currently cast/activate with his available resources.
 * Without target validation.
 *
 * @param game
 * @param hidden                  also from hidden objects (e.g. turned face down cards ?)
 * @param fromZone                of objects from which zone (ALL = from all zones)
 * @param hideDuplicatedAbilities if equal abilities exist return only the
 *                                first instance
 * @return
 */
public List<ActivatedAbility> getPlayable(Game game, boolean hidden, Zone fromZone, boolean hideDuplicatedAbilities) {
    List<ActivatedAbility> playable = new ArrayList<>();
    if (shouldSkipGettingPlayable(game)) {
        return playable;
    }
    boolean previousState = game.inCheckPlayableState();
    game.setCheckPlayableState(true);
    try {
        // get available mana options (mana pool and conditional mana added (but conditional still lose condition))
        ManaOptions availableMana = getManaAvailable(game);
        boolean fromAll = fromZone.equals(Zone.ALL);
        if (hidden && (fromAll || fromZone == Zone.HAND)) {
            for (Card card : hand.getCards(game)) {
                for (Ability ability : card.getAbilities(game)) {
                    // gets this activated ability from hand? (Morph?)
                    if (ability.getZone().match(Zone.HAND)) {
                        boolean isPlaySpell = (ability instanceof SpellAbility);
                        boolean isPlayLand = (ability instanceof PlayLandAbility);
                        // play land restrictions
                        if (isPlayLand && game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, ability.getSourceId(), ability, this.getId()), ability, game, true)) {
                            continue;
                        }
                        // cast spell restrictions 1
                        GameEvent castEvent = GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, ability.getId(), ability, this.getId());
                        castEvent.setZone(fromZone);
                        if (isPlaySpell && game.getContinuousEffects().preventedByRuleModification(castEvent, ability, game, true)) {
                            continue;
                        }
                        // cast spell restrictions 2
                        GameEvent castLateEvent = GameEvent.getEvent(GameEvent.EventType.CAST_SPELL_LATE, ability.getId(), ability, this.getId());
                        castLateEvent.setZone(fromZone);
                        if (isPlaySpell && game.getContinuousEffects().preventedByRuleModification(castLateEvent, ability, game, true)) {
                            continue;
                        }
                        ActivatedAbility playAbility = findActivatedAbilityFromPlayable(card, availableMana, ability, game);
                        if (playAbility != null && !playable.contains(playAbility)) {
                            playable.add(playAbility);
                        }
                    }
                }
            }
        }
        if (fromAll || fromZone == Zone.GRAVEYARD) {
            for (UUID playerId : game.getState().getPlayersInRange(getId(), game)) {
                Player player = game.getPlayer(playerId);
                if (player == null) {
                    continue;
                }
                for (Card card : player.getGraveyard().getCards(game)) {
                    getPlayableFromObjectAll(game, Zone.GRAVEYARD, card, availableMana, playable);
                }
            }
        }
        if (fromAll || fromZone == Zone.EXILED) {
            for (ExileZone exile : game.getExile().getExileZones()) {
                for (Card card : exile.getCards(game)) {
                    getPlayableFromObjectAll(game, Zone.EXILED, card, availableMana, playable);
                }
            }
        }
        // check to play revealed cards
        if (fromAll) {
            for (Cards revealedCards : game.getState().getRevealed().values()) {
                for (Card card : revealedCards.getCards(game)) {
                    // revealed cards can be from any zones
                    getPlayableFromObjectAll(game, game.getState().getZone(card.getId()), card, availableMana, playable);
                }
            }
        }
        // outside cards
        if (fromAll || fromZone == Zone.OUTSIDE) {
            // companion cards
            for (Cards companionCards : game.getState().getCompanion().values()) {
                for (Card card : companionCards.getCards(game)) {
                    getPlayableFromObjectAll(game, Zone.OUTSIDE, card, availableMana, playable);
                }
            }
            // sideboard cards (example: Wish)
            for (UUID sideboardCardId : this.getSideboard()) {
                Card sideboardCard = game.getCard(sideboardCardId);
                if (sideboardCard != null) {
                    getPlayableFromObjectAll(game, Zone.OUTSIDE, sideboardCard, availableMana, playable);
                }
            }
        }
        // check if it's possible to play the top card of a library
        if (fromAll || fromZone == Zone.LIBRARY) {
            for (UUID playerInRangeId : game.getState().getPlayersInRange(getId(), game)) {
                Player player = game.getPlayer(playerInRangeId);
                if (player != null && player.getLibrary().hasCards()) {
                    Card card = player.getLibrary().getFromTop(game);
                    if (card != null) {
                        getPlayableFromObjectAll(game, Zone.LIBRARY, card, availableMana, playable);
                    }
                }
            }
        }
        // AI games: computer can see and play cards from opponent's hand without reveal
        if (fromAll || fromZone == Zone.HAND) {
            for (UUID playerInRangeId : game.getState().getPlayersInRange(getId(), game)) {
                Player player = game.getPlayer(playerInRangeId);
                if (player != null && !player.getHand().isEmpty()) {
                    for (Card card : player.getHand().getCards(game)) {
                        if (card != null) {
                            getPlayableFromObjectAll(game, Zone.HAND, card, availableMana, playable);
                        }
                    }
                }
            }
        }
        // eliminate duplicate activated abilities (uses for AI plays)
        Map<String, ActivatedAbility> activatedUnique = new HashMap<>();
        List<ActivatedAbility> activatedAll = new ArrayList<>();
        // activated abilities from battlefield objects
        if (fromAll || fromZone == Zone.BATTLEFIELD) {
            for (Permanent permanent : game.getBattlefield().getAllActivePermanents()) {
                boolean canUseActivated = permanent.canUseActivatedAbilities(game);
                List<ActivatedAbility> currentPlayable = new ArrayList<>();
                getPlayableFromObjectAll(game, Zone.BATTLEFIELD, permanent, availableMana, currentPlayable);
                for (ActivatedAbility ability : currentPlayable) {
                    if (ability instanceof SpecialAction || canUseActivated) {
                        activatedUnique.putIfAbsent(ability.toString(), ability);
                        activatedAll.add(ability);
                    }
                }
            }
        }
        // activated abilities from stack objects
        if (fromAll || fromZone == Zone.STACK) {
            for (StackObject stackObject : game.getState().getStack()) {
                List<ActivatedAbility> currentPlayable = new ArrayList<>();
                getPlayableFromObjectAll(game, Zone.STACK, stackObject, availableMana, currentPlayable);
                for (ActivatedAbility ability : currentPlayable) {
                    activatedUnique.put(ability.toString(), ability);
                    activatedAll.add(ability);
                }
            }
        }
        // activated abilities from objects in the command zone (emblems or commanders)
        if (fromAll || fromZone == Zone.COMMAND) {
            for (CommandObject commandObject : game.getState().getCommand()) {
                List<ActivatedAbility> currentPlayable = new ArrayList<>();
                getPlayableFromObjectAll(game, Zone.COMMAND, commandObject, availableMana, currentPlayable);
                for (ActivatedAbility ability : currentPlayable) {
                    activatedUnique.put(ability.toString(), ability);
                    activatedAll.add(ability);
                }
            }
        }
        if (hideDuplicatedAbilities) {
            playable.addAll(activatedUnique.values());
        } else {
            playable.addAll(activatedAll);
        }
    } finally {
        game.setCheckPlayableState(previousState);
    }
    return playable;
}
Also used : AlternateManaPaymentAbility(mage.abilities.costs.mana.AlternateManaPaymentAbility) StackAbility(mage.game.stack.StackAbility) WhileSearchingPlayFromLibraryAbility(mage.abilities.common.WhileSearchingPlayFromLibraryAbility) AtTheEndOfTurnStepPostDelayedTriggeredAbility(mage.abilities.common.delayed.AtTheEndOfTurnStepPostDelayedTriggeredAbility) PassAbility(mage.abilities.common.PassAbility) PlayLandAsCommanderAbility(mage.abilities.common.PlayLandAsCommanderAbility) ManaOptions(mage.abilities.mana.ManaOptions) MatchPlayer(mage.game.match.MatchPlayer) Permanent(mage.game.permanent.Permanent) FilterPermanent(mage.filter.FilterPermanent) FilterControlledPermanent(mage.filter.common.FilterControlledPermanent) TargetPermanent(mage.target.TargetPermanent) StackObject(mage.game.stack.StackObject) FilterCard(mage.filter.FilterCard) TargetCard(mage.target.TargetCard) PermanentCard(mage.game.permanent.PermanentCard) CommandObject(mage.game.command.CommandObject)

Example 77 with StackObject

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

the class EmissaryOfGrudgesEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player controller = game.getPlayer(source.getControllerId());
    StackObject stackObject = game.getStack().getStackObject(source.getFirstTarget());
    if (controller == null || stackObject == null || !stackObject.isControlledBy(ChooseSecretOpponentEffect.getChosenPlayer(source, game))) {
        return false;
    }
    // find if it targets you or a permanent you control
    boolean targetsYouOrAPermanentYouControl = false;
    for (UUID modeId : stackObject.getStackAbility().getModes().getSelectedModes()) {
        Mode mode = stackObject.getStackAbility().getModes().get(modeId);
        for (Target target : mode.getTargets()) {
            for (UUID targetId : target.getTargets()) {
                if (source.isControlledBy(targetId)) {
                    targetsYouOrAPermanentYouControl = true;
                }
                Permanent permanent = game.getPermanent(targetId);
                if (permanent != null && source.isControlledBy(permanent.getControllerId())) {
                    targetsYouOrAPermanentYouControl = true;
                }
            }
        }
    }
    if (targetsYouOrAPermanentYouControl) {
        return stackObject.chooseNewTargets(game, source.getControllerId(), false, false, null);
    }
    return false;
}
Also used : Player(mage.players.Player) Target(mage.target.Target) Permanent(mage.game.permanent.Permanent) Mode(mage.abilities.Mode) TargetStackObject(mage.target.TargetStackObject) StackObject(mage.game.stack.StackObject) UUID(java.util.UUID)

Example 78 with StackObject

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

the class EnchantmentAlterationEffect method apply.

@Override
public boolean apply(ObjectSourcePlayer<MageItem> input, Game game) {
    StackObject source = game.getStack().getStackObject(input.getSourceId());
    Permanent auraIsAttachedToThisPermanent = null;
    Permanent newPermanentToAttachAuraTo;
    if (source != null) {
        if (source.getStackAbility().getTargets().isEmpty() || source.getStackAbility().getTargets().get(0).getTargets().isEmpty()) {
            return true;
        }
        Permanent auraPermanent = game.getPermanent(// targeted aura enchanting land or creature
        source.getStackAbility().getTargets().get(0).getTargets().get(0));
        if (auraPermanent != null) {
            auraIsAttachedToThisPermanent = game.getPermanent(auraPermanent.getAttachedTo());
        }
        if (auraIsAttachedToThisPermanent == null) {
            // the original permanent the aura is attached to
            return false;
        }
        // the new target creature or land to enchant
        newPermanentToAttachAuraTo = game.getPermanent(input.getObject().getId());
        if (newPermanentToAttachAuraTo == auraIsAttachedToThisPermanent) {
            // must be another permanent
            return false;
        }
        if (auraIsAttachedToThisPermanent.isCreature(game) && newPermanentToAttachAuraTo.isCreature(game)) {
            return true;
        }
        if (auraIsAttachedToThisPermanent.isLand(game) && newPermanentToAttachAuraTo.isLand(game)) {
            return true;
        }
        return false;
    }
    return true;
}
Also used : FilterPermanent(mage.filter.FilterPermanent) Permanent(mage.game.permanent.Permanent) TargetPermanent(mage.target.TargetPermanent) StackObject(mage.game.stack.StackObject)

Example 79 with StackObject

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

the class GuardianBeastConditionalEffect method applies.

@Override
public boolean applies(GameEvent event, Ability source, Game game) {
    Permanent permanent = source.getSourcePermanentIfItStillExists(game);
    Permanent targetPermanent = game.getPermanent(event.getTargetId());
    if (permanent == null || permanent.isTapped() || targetPermanent == null) {
        return false;
    }
    if (!Objects.equals(targetPermanent.getControllerId(), permanent.getControllerId())) {
        return false;
    }
    StackObject spell = game.getStack().getStackObject(event.getSourceId());
    if (event.getType() == GameEvent.EventType.GAIN_CONTROL || ((event.getType() == GameEvent.EventType.ATTACH || event.getType() == GameEvent.EventType.TARGET) && spell != null && spell.isEnchantment(game) && spell.hasSubtype(SubType.AURA, game))) {
        for (Permanent perm : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_ARTIFACTS_NON_CREATURE, source.getControllerId(), game)) {
            if (perm != null && Objects.equals(perm.getId(), targetPermanent.getId()) && !perm.isCreature(game)) {
                return true;
            }
        }
    }
    return false;
}
Also used : FilterControlledArtifactPermanent(mage.filter.common.FilterControlledArtifactPermanent) Permanent(mage.game.permanent.Permanent) StackObject(mage.game.stack.StackObject) FilterStackObject(mage.filter.FilterStackObject)

Example 80 with StackObject

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

the class InvasiveSurgeryEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player controller = game.getPlayer(source.getControllerId());
    if (controller == null) {
        return false;
    }
    String cardName = "";
    UUID spellController = null;
    if (source.getTargets().get(0) instanceof TargetSpell) {
        UUID objectId = source.getFirstTarget();
        StackObject stackObject = game.getStack().getStackObject(objectId);
        if (stackObject != null) {
            MageObject targetObject = game.getObject(stackObject.getSourceId());
            if (targetObject instanceof Card) {
                cardName = targetObject.getName();
            }
            spellController = stackObject.getControllerId();
            game.getStack().counter(objectId, source, game);
        }
    }
    // Check the Delirium condition
    if (!DeliriumCondition.instance.apply(game, source)) {
        return true;
    }
    return this.applySearchAndExile(game, source, cardName, spellController);
}
Also used : Player(mage.players.Player) StackObject(mage.game.stack.StackObject) MageObject(mage.MageObject) TargetSpell(mage.target.TargetSpell) UUID(java.util.UUID) Card(mage.cards.Card)

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