Search in sources :

Example 1 with CommandObject

use of mage.game.command.CommandObject in project mage by magefree.

the class CardTestPlayerAPIImpl method assertEmblemCount.

/**
 * Assert emblem count under player's control
 *
 * @param player
 * @param count
 * @throws AssertionError
 */
@Override
public void assertEmblemCount(Player player, int count) throws AssertionError {
    int actualCount = 0;
    for (CommandObject commandObject : currentGame.getState().getCommand()) {
        if (commandObject.getControllerId().equals(player.getId())) {
            actualCount++;
        }
    }
    Assert.assertEquals("Emblem counts are not equal", count, actualCount);
}
Also used : CommandObject(mage.game.command.CommandObject)

Example 2 with CommandObject

use of mage.game.command.CommandObject in project mage by magefree.

the class ArcaneAdaptationEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player controller = game.getPlayer(source.getControllerId());
    SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(source.getSourceId(), game);
    if (controller == null || subType == null) {
        return false;
    }
    // in graveyard
    for (UUID cardId : controller.getGraveyard()) {
        Card card = game.getCard(cardId);
        if (card != null && card.isCreature(game) && !card.hasSubtype(subType, game)) {
            game.getState().getCreateMageObjectAttribute(card, game).getSubtype().add(subType);
        }
    }
    // on Hand
    for (UUID cardId : controller.getHand()) {
        Card card = game.getCard(cardId);
        if (card != null && card.isCreature(game) && !card.hasSubtype(subType, game)) {
            game.getState().getCreateMageObjectAttribute(card, game).getSubtype().add(subType);
        }
    }
    // in Exile
    for (Card card : game.getState().getExile().getAllCards(game)) {
        if (card.isCreature(game) && !card.hasSubtype(subType, game)) {
            game.getState().getCreateMageObjectAttribute(card, game).getSubtype().add(subType);
        }
    }
    // in Library (e.g. for Mystical Teachings)
    for (Card card : controller.getLibrary().getCards(game)) {
        if (card.isOwnedBy(controller.getId()) && card.isCreature(game) && !card.hasSubtype(subType, game)) {
            game.getState().getCreateMageObjectAttribute(card, game).getSubtype().add(subType);
        }
    }
    // commander in command zone
    for (CommandObject commandObject : game.getState().getCommand()) {
        if (commandObject instanceof Commander) {
            Card card = game.getCard(((Commander) commandObject).getId());
            if (card != null && card.isOwnedBy(controller.getId()) && card.isCreature(game) && !card.hasSubtype(subType, game)) {
                game.getState().getCreateMageObjectAttribute(card, game).getSubtype().add(subType);
            }
        }
    }
    // creature spells you control
    for (Iterator<StackObject> iterator = game.getStack().iterator(); iterator.hasNext(); ) {
        StackObject stackObject = iterator.next();
        if (stackObject instanceof Spell && stackObject.isControlledBy(source.getControllerId()) && stackObject.isCreature(game) && !stackObject.hasSubtype(subType, game)) {
            Card card = ((Spell) stackObject).getCard();
            game.getState().getCreateMageObjectAttribute(card, game).getSubtype().add(subType);
        }
    }
    // creatures you control
    List<Permanent> creatures = game.getBattlefield().getAllActivePermanents(new FilterControlledCreaturePermanent(), source.getControllerId(), game);
    for (Permanent creature : creatures) {
        if (creature != null) {
            creature.addSubType(game, subType);
        }
    }
    return true;
}
Also used : CommandObject(mage.game.command.CommandObject) Player(mage.players.Player) Permanent(mage.game.permanent.Permanent) FilterControlledCreaturePermanent(mage.filter.common.FilterControlledCreaturePermanent) Commander(mage.game.command.Commander) StackObject(mage.game.stack.StackObject) FilterControlledCreaturePermanent(mage.filter.common.FilterControlledCreaturePermanent) UUID(java.util.UUID) Spell(mage.game.stack.Spell) Card(mage.cards.Card)

Example 3 with CommandObject

use of mage.game.command.CommandObject in project mage by magefree.

the class CardImpl method removeFromZone.

@Override
public boolean removeFromZone(Game game, Zone fromZone, Ability source) {
    boolean removed = false;
    MageObject lkiObject = null;
    switch(fromZone) {
        case GRAVEYARD:
            removed = game.getPlayer(ownerId).removeFromGraveyard(this, game);
            break;
        case HAND:
            removed = game.getPlayer(ownerId).removeFromHand(this, game);
            break;
        case LIBRARY:
            removed = game.getPlayer(ownerId).removeFromLibrary(this, game);
            break;
        case EXILED:
            if (game.getExile().getCard(getId(), game) != null) {
                removed = game.getExile().removeCard(this, game);
            }
            break;
        case STACK:
            StackObject stackObject;
            if (getSpellAbility() != null) {
                stackObject = game.getStack().getSpell(getSpellAbility().getId(), false);
            } else {
                stackObject = game.getStack().getSpell(this.getId(), false);
            }
            // handle half of Split Cards on stack
            if (stackObject == null && (this instanceof SplitCard)) {
                stackObject = game.getStack().getSpell(((SplitCard) this).getLeftHalfCard().getId(), false);
                if (stackObject == null) {
                    stackObject = game.getStack().getSpell(((SplitCard) this).getRightHalfCard().getId(), false);
                }
            }
            // handle half of Modal Double Faces Cards on stack
            if (stackObject == null && (this instanceof ModalDoubleFacesCard)) {
                stackObject = game.getStack().getSpell(((ModalDoubleFacesCard) this).getLeftHalfCard().getId(), false);
                if (stackObject == null) {
                    stackObject = game.getStack().getSpell(((ModalDoubleFacesCard) this).getRightHalfCard().getId(), false);
                }
            }
            if (stackObject == null && (this instanceof AdventureCard)) {
                stackObject = game.getStack().getSpell(((AdventureCard) this).getSpellCard().getId(), false);
            }
            if (stackObject == null) {
                stackObject = game.getStack().getSpell(getId(), false);
            }
            if (stackObject != null) {
                removed = game.getStack().remove(stackObject, game);
                lkiObject = stackObject;
            }
            break;
        case COMMAND:
            for (CommandObject commandObject : game.getState().getCommand()) {
                if (commandObject.getId().equals(objectId)) {
                    lkiObject = commandObject;
                }
            }
            if (lkiObject != null) {
                removed = game.getState().getCommand().remove(lkiObject);
            }
            break;
        case OUTSIDE:
            if (isCopy()) {
                // copied cards have no need to be removed from a previous zone
                removed = true;
            } else if (game.getPlayer(ownerId).getSideboard().contains(this.getId())) {
                game.getPlayer(ownerId).getSideboard().remove(this.getId());
                removed = true;
            } else if (game.getPhase() == null) {
                // E.g. Commander of commander game
                removed = true;
            } else {
                // Unstable - Summon the Pack
                removed = true;
            }
            break;
        case // for sacrificing permanents or putting to library
        BATTLEFIELD:
            removed = true;
            break;
        default:
            MageObject sourceObject = game.getObject(source.getSourceId());
            logger.fatal("Invalid from zone [" + fromZone + "] for card [" + this.getIdName() + "] source [" + (sourceObject != null ? sourceObject.getName() : "null") + ']');
            break;
    }
    if (removed) {
        if (fromZone != Zone.OUTSIDE) {
            game.rememberLKI(lkiObject != null ? lkiObject.getId() : objectId, fromZone, lkiObject != null ? lkiObject : this);
        }
    } else {
        logger.warn("Couldn't find card in fromZone, card=" + getIdName() + ", fromZone=" + fromZone);
    // possible reason: you to remove card from wrong zone or card already removed,
    // e.g. you added copy card to wrong graveyard (see owner) or removed card from graveyard before moveToZone call
    }
    return removed;
}
Also used : CommandObject(mage.game.command.CommandObject) MageObject(mage.MageObject) StackObject(mage.game.stack.StackObject)

Example 4 with CommandObject

use of mage.game.command.CommandObject in project mage by magefree.

the class RollPlanarDieEffect method apply.

@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) {
        PlanarDieRollResult planarRoll = controller.rollPlanarDie(outcome, source, game);
        if (planarRoll == PlanarDieRollResult.CHAOS_ROLL && chaosEffects != null && chaosTargets != null) {
            for (int i = 0; i < chaosTargets.size(); i++) {
                Target target = chaosTargets.get(i);
                if (target != null) {
                    target.clearChosen();
                }
            }
            for (int i = 0; i < chaosEffects.size(); i++) {
                Effect effect = chaosEffects.get(i);
                Target target = null;
                if (chaosTargets.size() > i) {
                    target = chaosTargets.get(i);
                }
                boolean done = false;
                while (controller.canRespond() && effect != null && !done) {
                    if (target != null && !target.isChosen() && target.canChoose(source.getSourceId(), controller.getId(), game)) {
                        controller.chooseTarget(Outcome.Benefit, target, source, game);
                        source.addTarget(target);
                    }
                    if (target != null) {
                        effect.setTargetPointer(new FixedTarget(target.getFirstTarget()));
                    }
                    try {
                        effect.apply(game, source);
                    } catch (UnsupportedOperationException exception) {
                    }
                    if (effect instanceof ContinuousEffect) {
                        game.addEffect((ContinuousEffect) effect, source);
                    }
                    done = true;
                }
            }
        } else if (planarRoll == PlanarDieRollResult.PLANAR_ROLL) {
            // Steps: 1) Remove the last plane and set its effects to discarded
            for (CommandObject cobject : game.getState().getCommand()) {
                if (cobject instanceof Plane) {
                    if (cobject.getAbilities() != null) {
                        for (Ability ability : cobject.getAbilities()) {
                            for (Effect effect : ability.getEffects()) {
                                if (effect instanceof ContinuousEffect) {
                                    ((ContinuousEffect) effect).discard();
                                }
                            }
                        }
                    }
                    game.getState().removeTriggersOfSourceId(cobject.getId());
                    game.getState().getCommand().remove(cobject);
                    break;
                }
            }
            // 2) Choose a new random plane we haven't been to, or reset if we've been everywhere
            List<String> planesVisited = game.getState().getSeenPlanes();
            if (game.getState().getSeenPlanes() != null) {
                if (planesVisited.size() == Planes.values().length) {
                    game.getState().resetSeenPlanes();
                }
            }
            boolean foundNextPlane = false;
            while (!foundNextPlane) {
                Plane plane = Plane.createRandomPlane();
                try {
                    if (plane != null && !planesVisited.contains(plane.getName())) {
                        foundNextPlane = true;
                        plane.setControllerId(controller.getId());
                        game.addPlane(plane, null, controller.getId());
                    }
                } catch (Exception ex) {
                }
            }
        }
        return true;
    }
    return false;
}
Also used : FixedTarget(mage.target.targetpointer.FixedTarget) Ability(mage.abilities.Ability) Player(mage.players.Player) PlanarDieRollResult(mage.constants.PlanarDieRollResult) Plane(mage.game.command.Plane) MageObject(mage.MageObject) CommandObject(mage.game.command.CommandObject) Target(mage.target.Target) FixedTarget(mage.target.targetpointer.FixedTarget) OneShotEffect(mage.abilities.effects.OneShotEffect) ContinuousEffect(mage.abilities.effects.ContinuousEffect) Effect(mage.abilities.effects.Effect) List(java.util.List) ContinuousEffect(mage.abilities.effects.ContinuousEffect)

Example 5 with CommandObject

use of mage.game.command.CommandObject 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)

Aggregations

CommandObject (mage.game.command.CommandObject)11 StackObject (mage.game.stack.StackObject)6 Spell (mage.game.stack.Spell)5 Player (mage.players.Player)5 MageObject (mage.MageObject)4 Card (mage.cards.Card)4 Permanent (mage.game.permanent.Permanent)4 Ability (mage.abilities.Ability)3 TargetCard (mage.target.TargetCard)3 UUID (java.util.UUID)2 ContinuousEffect (mage.abilities.effects.ContinuousEffect)2 Effect (mage.abilities.effects.Effect)2 FilterCard (mage.filter.FilterCard)2 FilterControlledCreaturePermanent (mage.filter.common.FilterControlledCreaturePermanent)2 Commander (mage.game.command.Commander)2 Plane (mage.game.command.Plane)2 MatchPlayer (mage.game.match.MatchPlayer)2 PermanentCard (mage.game.permanent.PermanentCard)2 SquirrelToken (mage.game.permanent.token.SquirrelToken)2 List (java.util.List)1