Search in sources :

Example 6 with Mode

use of mage.abilities.Mode in project mage by magefree.

the class SpellskiteEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    StackObject stackObject = game.getStack().getStackObject(source.getFirstTarget());
    MageObject sourceObject = game.getObject(source.getSourceId());
    if (stackObject != null && sourceObject != null) {
        Targets targets = new Targets();
        Ability sourceAbility;
        String oldTargetName = null;
        if (stackObject instanceof Spell) {
            Spell spell = (Spell) stackObject;
            sourceAbility = spell.getSpellAbility();
        } else if (stackObject instanceof StackAbility) {
            StackAbility stackAbility = (StackAbility) stackObject;
            sourceAbility = stackAbility;
        } else {
            return false;
        }
        for (UUID modeId : sourceAbility.getModes().getSelectedModes()) {
            Mode mode = sourceAbility.getModes().get(modeId);
            targets.addAll(mode.getTargets());
        }
        boolean twoTimesTarget = false;
        if (targets.size() == 1 && targets.get(0).getTargets().size() == 1) {
            Target target = targets.get(0);
            if (target.getFirstTarget().equals(source.getSourceId())) {
                // Target was already the same source, so no change / target event to create
                return true;
            }
            if (target.canTarget(stackObject.getControllerId(), source.getSourceId(), sourceAbility, game)) {
                oldTargetName = getTargetName(targets.getFirstTarget(), game);
                target.clearChosen();
                // The source is still the spell on the stack
                target.addTarget(source.getSourceId(), stackObject.getStackAbility(), game);
            }
        } else {
            // needed for targeted source's with multiple targets
            Player controller = game.getPlayer(source.getControllerId());
            boolean validTargets = false;
            do {
                for (Target target : targets) {
                    if (target.getTargets().contains(source.getSourceId())) {
                        // You can't change a traget to Spellskite, if Spellskite is already targeted by this target
                        continue;
                    }
                    for (UUID targetId : target.getTargets()) {
                        String name = getTargetName(targetId, game);
                        if (target.canTarget(stackObject.getControllerId(), source.getSourceId(), sourceAbility, game)) {
                            validTargets = true;
                            if (name != null && controller.chooseUse(Outcome.Neutral, "Change target from " + name + " to " + sourceObject.getLogName() + '?', source, game)) {
                                oldTargetName = getTargetName(targetId, game);
                                int damageAmount = target.getTargetAmount(targetId);
                                target.remove(targetId);
                                // The source is still the spell on the stack
                                // add the source permanent id and set the damage if any
                                target.addTarget(source.getSourceId(), stackObject.getStackAbility(), game);
                                target.setTargetAmount(source.getSourceId(), damageAmount, game);
                                break;
                            }
                        }
                    }
                    if (oldTargetName != null) {
                        break;
                    }
                }
                if (oldTargetName == null) {
                    game.informPlayer(controller, "You have to select at least one target to change to " + sourceObject.getIdName() + '!');
                }
            } while (validTargets && oldTargetName == null);
        }
        if (oldTargetName != null) {
            game.informPlayers(sourceObject.getLogName() + ": Changed target of " + stackObject.getLogName() + " from " + oldTargetName + " to " + sourceObject.getLogName());
        } else if (twoTimesTarget) {
            game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its not valid to target it twice for " + stackObject.getLogName());
        } else {
            game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its no valid target for " + stackObject.getLogName());
        }
        return true;
    }
    return false;
}
Also used : SimpleActivatedAbility(mage.abilities.common.SimpleActivatedAbility) StackAbility(mage.game.stack.StackAbility) Ability(mage.abilities.Ability) Player(mage.players.Player) Mode(mage.abilities.Mode) TargetStackObject(mage.target.TargetStackObject) StackObject(mage.game.stack.StackObject) MageObject(mage.MageObject) Targets(mage.target.Targets) Spell(mage.game.stack.Spell) StackAbility(mage.game.stack.StackAbility) Target(mage.target.Target) UUID(java.util.UUID)

Example 7 with Mode

use of mage.abilities.Mode in project mage by magefree.

the class DackFaydenEmblemEffect method checkTrigger.

@Override
public boolean checkTrigger(GameEvent event, Game game) {
    boolean returnValue = false;
    List<UUID> targetedPermanentIds = new ArrayList<>(0);
    Player player = game.getPlayer(this.getControllerId());
    if (player != null) {
        if (event.getPlayerId().equals(this.getControllerId())) {
            Spell spell = game.getStack().getSpell(event.getTargetId());
            if (spell != null) {
                SpellAbility spellAbility = spell.getSpellAbility();
                for (Mode mode : spellAbility.getModes().values()) {
                    for (Target target : mode.getTargets()) {
                        if (!target.isNotTarget()) {
                            for (UUID targetId : target.getTargets()) {
                                if (game.getBattlefield().containsPermanent(targetId)) {
                                    returnValue = true;
                                    targetedPermanentIds.add(targetId);
                                }
                            }
                        }
                    }
                }
                for (Effect effect : spellAbility.getEffects()) {
                    for (UUID targetId : effect.getTargetPointer().getTargets(game, spellAbility)) {
                        if (game.getBattlefield().containsPermanent(targetId)) {
                            returnValue = true;
                            targetedPermanentIds.add(targetId);
                        }
                    }
                }
            }
        }
    }
    for (Effect effect : this.getEffects()) {
        if (effect instanceof DackFaydenEmblemEffect) {
            DackFaydenEmblemEffect dackEffect = (DackFaydenEmblemEffect) effect;
            List<Permanent> permanents = new ArrayList<>();
            for (UUID permanentId : targetedPermanentIds) {
                Permanent permanent = game.getPermanent(permanentId);
                if (permanent != null) {
                    permanents.add(permanent);
                }
            }
            dackEffect.setTargets(permanents, game);
        }
    }
    return returnValue;
}
Also used : Player(mage.players.Player) Permanent(mage.game.permanent.Permanent) Mode(mage.abilities.Mode) ArrayList(java.util.ArrayList) SpellAbility(mage.abilities.SpellAbility) Spell(mage.game.stack.Spell) Target(mage.target.Target) Effect(mage.abilities.effects.Effect) UUID(java.util.UUID)

Example 8 with Mode

use of mage.abilities.Mode in project mage by magefree.

the class StackObjectImpl method chooseNewTargets.

/**
 * 114.6. Some effects allow a player to change the target(s) of a spell or
 * ability, and other effects allow a player to choose new targets for a
 * spell or ability.
 * <p>
 * 114.6a If an effect allows a player to "change the target(s)" of a spell
 * or ability, each target can be changed only to another legal target. If a
 * target can't be changed to another legal target, the original target is
 * unchanged, even if the original target is itself illegal by then. If all
 * the targets aren't changed to other legal targets, none of them are
 * changed.
 * <p>
 * 114.6b If an effect allows a player to "change a target" of a spell or
 * ability, the process described in rule 114.6a is followed, except that
 * only one of those targets may be changed (rather than all of them or none
 * of them).
 * <p>
 * 114.6c If an effect allows a player to "change any targets" of a spell or
 * ability, the process described in rule 114.6a is followed, except that
 * any number of those targets may be changed (rather than all of them or
 * none of them).
 * <p>
 * 114.6d If an effect allows a player to "choose new targets" for a spell
 * or ability, the player may leave any number of the targets unchanged,
 * even if those targets would be illegal. If the player chooses to change
 * some or all of the targets, the new targets must be legal and must not
 * cause any unchanged targets to become illegal.
 * <p>
 * 114.6e When changing targets or choosing new targets for a spell or
 * ability, only the final set of targets is evaluated to determine whether
 * the change is legal.
 * <p>
 * Example: Arc Trail is a sorcery that reads "Arc Trail deals 2 damage to
 * any target and 1 damage to another target creature or player." The
 * current targets of Arc Trail are Runeclaw Bear and Llanowar Elves, in
 * that order. You cast Redirect, an instant that reads "You may choose new
 * targets for target spell," targeting Arc Trail. You can change the first
 * target to Llanowar Elves and change the second target to Runeclaw Bear.
 * <p>
 * 114.7. Modal spells and abilities may have different targeting
 * requirements for each mode. An effect that allows a player to change the
 * target(s) of a modal spell or ability, or to choose new targets for a
 * modal spell or ability, doesn't allow that player to change its mode.
 * (See rule 700.2.)
 * <p>
 * 706.10c Some effects copy a spell or ability and state that its
 * controller may choose new targets for the copy. The player may leave any
 * number of the targets unchanged, even if those targets would be illegal.
 * If the player chooses to change some or all of the targets, the new
 * targets must be legal. Once the player has decided what the copy's
 * targets will be, the copy is put onto the stack with those targets.
 *
 * @param game
 * @param targetControllerId       - player that can/has to change the target of
 *                                 the spell
 * @param forceChange              - does only work for targets with maximum of one
 *                                 targetId
 * @param onlyOneTarget            - 114.6b one target must be changed to another
 *                                 target
 * @param newTargetFilterPredicate restriction for the new target (null - can select same targets)
 * @return
 */
@Override
public boolean chooseNewTargets(Game game, UUID targetControllerId, boolean forceChange, boolean onlyOneTarget, Predicate<MageItem> newTargetFilterPredicate) {
    Player targetController = game.getPlayer(targetControllerId);
    if (targetController != null) {
        StringBuilder oldTargetDescription = new StringBuilder();
        StringBuilder newTargetDescription = new StringBuilder();
        // Fused split spells or spells where "Splice on Arcane" was used can have more than one ability
        Abilities<Ability> objectAbilities = new AbilitiesImpl<>();
        if (this instanceof Spell) {
            objectAbilities.addAll(((Spell) this).getSpellAbilities());
        } else {
            objectAbilities.add(getStackAbility());
        }
        for (Ability ability : objectAbilities) {
            // Some spells can have more than one mode
            for (UUID modeId : ability.getModes().getSelectedModes()) {
                Mode mode = ability.getModes().get(modeId);
                ability.getModes().setActiveMode(mode);
                oldTargetDescription.append(ability.getTargetDescription(mode.getTargets(), game));
                for (Target target : mode.getTargets()) {
                    Target newTarget = chooseNewTarget(targetController, ability, mode, target, forceChange, newTargetFilterPredicate, game);
                    // clear the old target and copy all targets from new target
                    target.clearChosen();
                    for (UUID targetId : newTarget.getTargets()) {
                        target.addTarget(targetId, newTarget.getTargetAmount(targetId), ability, game, false);
                    }
                }
                newTargetDescription.append(ability.getTargetDescription(mode.getTargets(), game));
            }
        }
        if (!newTargetDescription.toString().equals(oldTargetDescription.toString()) && !game.isSimulation()) {
            game.informPlayers(this.getLogName() + " is now " + newTargetDescription);
        }
        return true;
    }
    return false;
}
Also used : Ability(mage.abilities.Ability) AbilitiesImpl(mage.abilities.AbilitiesImpl) Player(mage.players.Player) Target(mage.target.Target) Mode(mage.abilities.Mode)

Example 9 with Mode

use of mage.abilities.Mode in project mage by magefree.

the class OrvarTheAllFormEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player player = game.getPlayer(source.getControllerId());
    Spell spell = (Spell) this.getValue("spellCast");
    if (player == null || spell == null) {
        return false;
    }
    List<Predicate<Permanent>> predicates = spell.getSpellAbility().getModes().values().stream().map(Mode::getTargets).flatMap(Collection::stream).map(Target::getTargets).flatMap(Collection::stream).map(game::getPermanent).filter(Objects::nonNull).map(MageItem::getId).map(PermanentIdPredicate::new).collect(Collectors.toList());
    if (predicates.isEmpty()) {
        return false;
    }
    FilterPermanent filter = new FilterControlledPermanent("a permanent you control targeted by that spell");
    filter.add(Predicates.or(predicates));
    filter.add(Predicates.not(new MageObjectReferencePredicate(new MageObjectReference(source))));
    TargetPermanent target = new TargetPermanent(filter);
    target.setNotTarget(true);
    player.choose(outcome, target, source.getSourceId(), game);
    return new CreateTokenCopyTargetEffect().setTargetPointer(new FixedTarget(target.getFirstTarget(), game)).apply(game, source);
}
Also used : FixedTarget(mage.target.targetpointer.FixedTarget) Player(mage.players.Player) FilterPermanent(mage.filter.FilterPermanent) Mode(mage.abilities.Mode) MageItem(mage.MageItem) FilterControlledPermanent(mage.filter.common.FilterControlledPermanent) Spell(mage.game.stack.Spell) PermanentIdPredicate(mage.filter.predicate.permanent.PermanentIdPredicate) Predicate(mage.filter.predicate.Predicate) MageObjectReferencePredicate(mage.filter.predicate.mageobject.MageObjectReferencePredicate) Target(mage.target.Target) FixedTarget(mage.target.targetpointer.FixedTarget) MageObjectReferencePredicate(mage.filter.predicate.mageobject.MageObjectReferencePredicate) TargetPermanent(mage.target.TargetPermanent) CreateTokenCopyTargetEffect(mage.abilities.effects.common.CreateTokenCopyTargetEffect) MageObjectReference(mage.MageObjectReference)

Example 10 with Mode

use of mage.abilities.Mode in project mage by magefree.

the class ChapterTriggeredAbility method addChapterEffect.

public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effects effects, Targets targets, boolean optional, Mode... modes) {
    for (int i = fromChapter.getNumber(); i <= toChapter.getNumber(); i++) {
        ChapterTriggeredAbility ability = new ChapterTriggeredAbility(null, SagaChapter.getChapter(i), toChapter, optional);
        for (Effect effect : effects) {
            if (effect != null) {
                ability.addEffect(effect.copy());
            }
        }
        for (Target target : targets) {
            if (target != null) {
                ability.addTarget(target.copy());
            }
        }
        for (Mode mode : modes) {
            ability.addMode(mode.copy());
        }
        if (i > fromChapter.getNumber()) {
            ability.setRuleVisible(false);
        }
        card.addAbility(ability);
    }
}
Also used : Target(mage.target.Target) Mode(mage.abilities.Mode) AddCountersSourceEffect(mage.abilities.effects.common.counter.AddCountersSourceEffect) Effect(mage.abilities.effects.Effect)

Aggregations

Mode (mage.abilities.Mode)19 Target (mage.target.Target)16 UUID (java.util.UUID)11 Player (mage.players.Player)10 Spell (mage.game.stack.Spell)8 Ability (mage.abilities.Ability)7 StackObject (mage.game.stack.StackObject)7 Permanent (mage.game.permanent.Permanent)6 Effect (mage.abilities.effects.Effect)5 MageObject (mage.MageObject)4 MageObjectReference (mage.MageObjectReference)4 FixedTarget (mage.target.targetpointer.FixedTarget)4 ArrayList (java.util.ArrayList)3 MageInt (mage.MageInt)3 CardImpl (mage.cards.CardImpl)3 CardSetInfo (mage.cards.CardSetInfo)3 CardType (mage.constants.CardType)3 SubType (mage.constants.SubType)3 java.util (java.util)2 AbilityImpl (mage.abilities.AbilityImpl)2