Search in sources :

Example 11 with Outcome

use of mage.constants.Outcome 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 12 with Outcome

use of mage.constants.Outcome in project mage by magefree.

the class GlobalRuinDestroyLandEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Set<UUID> lands = new HashSet<>();
    for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
        Player player = game.getPlayer(playerId);
        if (player != null) {
            for (SubType landName : Arrays.stream(SubType.values()).filter(p -> p.getSubTypeSet() == SubTypeSet.BasicLandType).collect(Collectors.toSet())) {
                FilterControlledLandPermanent filter = new FilterControlledLandPermanent(landName + " you control");
                filter.add(landName.getPredicate());
                Target target = new TargetControlledPermanent(1, 1, filter, true);
                if (target.canChoose(source.getSourceId(), player.getId(), game)) {
                    player.chooseTarget(outcome, target, source, game);
                    lands.add(target.getFirstTarget());
                }
            }
        }
    }
    for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_LAND, game)) {
        if (!lands.contains(permanent.getId())) {
            permanent.sacrifice(source, game);
        }
    }
    return true;
}
Also used : Target(mage.target.Target) Arrays(java.util.Arrays) StaticFilters(mage.filter.StaticFilters) SubTypeSet(mage.constants.SubTypeSet) Set(java.util.Set) Outcome(mage.constants.Outcome) OneShotEffect(mage.abilities.effects.OneShotEffect) UUID(java.util.UUID) SubType(mage.constants.SubType) Collectors(java.util.stream.Collectors) Player(mage.players.Player) HashSet(java.util.HashSet) CardSetInfo(mage.cards.CardSetInfo) Game(mage.game.Game) CardImpl(mage.cards.CardImpl) Permanent(mage.game.permanent.Permanent) CardType(mage.constants.CardType) TargetControlledPermanent(mage.target.common.TargetControlledPermanent) FilterControlledLandPermanent(mage.filter.common.FilterControlledLandPermanent) Ability(mage.abilities.Ability) TargetControlledPermanent(mage.target.common.TargetControlledPermanent) Player(mage.players.Player) Target(mage.target.Target) SubType(mage.constants.SubType) Permanent(mage.game.permanent.Permanent) TargetControlledPermanent(mage.target.common.TargetControlledPermanent) FilterControlledLandPermanent(mage.filter.common.FilterControlledLandPermanent) UUID(java.util.UUID) FilterControlledLandPermanent(mage.filter.common.FilterControlledLandPermanent) HashSet(java.util.HashSet)

Example 13 with Outcome

use of mage.constants.Outcome in project mage by magefree.

the class HydradoodleEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Permanent permanent = game.getPermanentEntering(source.getSourceId());
    Player controller = game.getPlayer(source.getControllerId());
    if (permanent != null && controller != null) {
        SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY);
        if (spellAbility != null && spellAbility.getSourceId().equals(source.getSourceId()) && permanent.getZoneChangeCounter(game) == spellAbility.getSourceObjectZoneChangeCounter()) {
            int amount = spellAbility.getManaCostsToPay().getX();
            if (amount > 0) {
                int total = controller.rollDice(outcome, source, game, 6, amount, 0).stream().mapToInt(x -> x).sum();
                permanent.addCounters(CounterType.P1P1.createInstance(total), source.getControllerId(), source, game);
            }
        }
        return true;
    }
    return false;
}
Also used : EntersBattlefieldEffect(mage.abilities.effects.EntersBattlefieldEffect) CounterAnyPredicate(mage.filter.predicate.permanent.CounterAnyPredicate) Outcome(mage.constants.Outcome) OneShotEffect(mage.abilities.effects.OneShotEffect) UUID(java.util.UUID) MageInt(mage.MageInt) ReachAbility(mage.abilities.keyword.ReachAbility) SubType(mage.constants.SubType) EntersBattlefieldAbility(mage.abilities.common.EntersBattlefieldAbility) FilterPermanent(mage.filter.FilterPermanent) Player(mage.players.Player) CardSetInfo(mage.cards.CardSetInfo) SpellAbility(mage.abilities.SpellAbility) Game(mage.game.Game) CardImpl(mage.cards.CardImpl) Permanent(mage.game.permanent.Permanent) CardType(mage.constants.CardType) TrampleAbility(mage.abilities.keyword.TrampleAbility) CounterType(mage.counters.CounterType) Ability(mage.abilities.Ability) Player(mage.players.Player) FilterPermanent(mage.filter.FilterPermanent) Permanent(mage.game.permanent.Permanent) SpellAbility(mage.abilities.SpellAbility)

Example 14 with Outcome

use of mage.constants.Outcome in project mage by magefree.

the class RagingRiverEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player controller = game.getPlayer(source.getControllerId());
    if (controller != null) {
        List<Permanent> left = new ArrayList<>();
        List<Permanent> right = new ArrayList<>();
        for (UUID defenderId : game.getCombat().getPlayerDefenders(game)) {
            Player defender = game.getPlayer(defenderId);
            if (defender != null) {
                List<Permanent> leftLog = new ArrayList<>();
                List<Permanent> rightLog = new ArrayList<>();
                FilterControlledCreaturePermanent filterBlockers = new FilterControlledCreaturePermanent("creatures without flying you control to assign to the \"left\" pile (creatures not chosen will be assigned to the \"right\" pile)");
                filterBlockers.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
                Target target = new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, filterBlockers, true);
                if (target.canChoose(source.getSourceId(), defenderId, game)) {
                    if (defender.chooseTarget(Outcome.Neutral, target, source, game)) {
                        for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), defenderId, game)) {
                            if (target.getTargets().contains(permanent.getId())) {
                                left.add(permanent);
                                leftLog.add(permanent);
                            } else if (filterBlockers.match(permanent, source.getSourceId(), defenderId, game)) {
                                right.add(permanent);
                                rightLog.add(permanent);
                            }
                        }
                    }
                    // it could be nice to invoke some graphic indicator of which creature is Left or Right in this spot
                    StringBuilder sb = new StringBuilder("Left pile of ").append(defender.getLogName()).append(": ");
                    sb.append(leftLog.stream().map(MageObject::getLogName).collect(Collectors.joining(", ")));
                    game.informPlayers(sb.toString());
                    sb = new StringBuilder("Right pile of ").append(defender.getLogName()).append(": ");
                    sb.append(rightLog.stream().map(MageObject::getLogName).collect(Collectors.joining(", ")));
                    game.informPlayers(sb.toString());
                }
            }
        }
        for (UUID attackers : game.getCombat().getAttackers()) {
            Permanent attacker = game.getPermanent(attackers);
            if (attacker != null && Objects.equals(attacker.getControllerId(), controller.getId())) {
                CombatGroup combatGroup = game.getCombat().findGroup(attacker.getId());
                if (combatGroup != null) {
                    FilterCreaturePermanent filter = new FilterCreaturePermanent();
                    Player defender = game.getPlayer(combatGroup.getDefendingPlayerId());
                    if (defender != null) {
                        if (left.isEmpty() && right.isEmpty()) {
                            // shortcut in case of no labeled blockers available
                            filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
                        } else {
                            List<Permanent> leftLog = left.stream().filter(permanent -> permanent.getControllerId() != null).filter(permanent -> permanent.isControlledBy(defender.getId())).collect(Collectors.toList());
                            List<Permanent> rightLog = right.stream().filter(permanent -> permanent.getControllerId() != null).filter(permanent -> permanent.isControlledBy(defender.getId())).collect(Collectors.toList());
                            if (controller.choosePile(outcome, attacker.getName() + ": attacking " + defender.getName(), leftLog, rightLog, game)) {
                                filter.add(Predicates.not(Predicates.or(new AbilityPredicate(FlyingAbility.class), new PermanentInListPredicate(left))));
                                game.informPlayers(attacker.getLogName() + ": attacks left (" + defender.getLogName() + ")");
                            } else {
                                filter.add(Predicates.not(Predicates.or(new AbilityPredicate(FlyingAbility.class), new PermanentInListPredicate(right))));
                                game.informPlayers(attacker.getLogName() + ": attacks right (" + defender.getLogName() + ")");
                            }
                        }
                        RestrictionEffect effect = new CantBeBlockedByAllTargetEffect(filter, Duration.EndOfCombat);
                        effect.setTargetPointer(new FixedTarget(attacker.getId(), game));
                        game.addEffect(effect, source);
                    }
                }
            }
        }
        return true;
    }
    return false;
}
Also used : Target(mage.target.Target) RestrictionEffect(mage.abilities.effects.RestrictionEffect) CantBeBlockedByAllTargetEffect(mage.abilities.effects.common.combat.CantBeBlockedByAllTargetEffect) Predicates(mage.filter.predicate.Predicates) Player(mage.players.Player) FixedTarget(mage.target.targetpointer.FixedTarget) ArrayList(java.util.ArrayList) AttacksWithCreaturesTriggeredAbility(mage.abilities.common.AttacksWithCreaturesTriggeredAbility) CardType(mage.constants.CardType) FilterControlledCreaturePermanent(mage.filter.common.FilterControlledCreaturePermanent) MageObject(mage.MageObject) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) CombatGroup(mage.game.combat.CombatGroup) FlyingAbility(mage.abilities.keyword.FlyingAbility) PermanentInListPredicate(mage.filter.predicate.permanent.PermanentInListPredicate) Outcome(mage.constants.Outcome) OneShotEffect(mage.abilities.effects.OneShotEffect) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) CardSetInfo(mage.cards.CardSetInfo) Objects(java.util.Objects) Duration(mage.constants.Duration) Game(mage.game.Game) List(java.util.List) CardImpl(mage.cards.CardImpl) Permanent(mage.game.permanent.Permanent) AbilityPredicate(mage.filter.predicate.mageobject.AbilityPredicate) TargetControlledCreaturePermanent(mage.target.common.TargetControlledCreaturePermanent) Ability(mage.abilities.Ability) FixedTarget(mage.target.targetpointer.FixedTarget) Player(mage.players.Player) PermanentInListPredicate(mage.filter.predicate.permanent.PermanentInListPredicate) FilterControlledCreaturePermanent(mage.filter.common.FilterControlledCreaturePermanent) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) Permanent(mage.game.permanent.Permanent) TargetControlledCreaturePermanent(mage.target.common.TargetControlledCreaturePermanent) ArrayList(java.util.ArrayList) FilterControlledCreaturePermanent(mage.filter.common.FilterControlledCreaturePermanent) MageObject(mage.MageObject) TargetControlledCreaturePermanent(mage.target.common.TargetControlledCreaturePermanent) Target(mage.target.Target) FixedTarget(mage.target.targetpointer.FixedTarget) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) FlyingAbility(mage.abilities.keyword.FlyingAbility) UUID(java.util.UUID) RestrictionEffect(mage.abilities.effects.RestrictionEffect) AbilityPredicate(mage.filter.predicate.mageobject.AbilityPredicate) CombatGroup(mage.game.combat.CombatGroup) CantBeBlockedByAllTargetEffect(mage.abilities.effects.common.combat.CantBeBlockedByAllTargetEffect)

Example 15 with Outcome

use of mage.constants.Outcome in project mage by magefree.

the class SlipperyBogbonderEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player player = game.getPlayer(source.getControllerId());
    Permanent creature = game.getPermanent(source.getFirstTarget());
    FilterPermanent filterPermanent = filter.copy();
    filterPermanent.add(Predicates.not(new PermanentIdPredicate(source.getFirstTarget())));
    if (player == null || creature == null || game.getBattlefield().count(filterPermanent, source.getSourceId(), source.getControllerId(), game) < 1) {
        return false;
    }
    TargetPermanent target = new TargetPermanent(0, Integer.MAX_VALUE, filterPermanent, true);
    player.choose(outcome, target, source.getSourceId(), game);
    List<Permanent> permanents = target.getTargets().stream().filter(uuid -> !creature.getId().equals(uuid)).map(game::getPermanent).filter(Objects::nonNull).collect(Collectors.toList());
    if (permanents.isEmpty()) {
        return false;
    }
    Map<UUID, Map<String, Integer>> counterMap = new HashMap<>();
    for (Permanent permanent : permanents) {
        permanent.getCounters(game).entrySet().stream().forEach(entry -> {
            int num = player.getAmount(0, entry.getValue().getCount(), "Choose how many " + entry.getKey() + " counters to remove from " + permanent.getLogName(), game);
            counterMap.computeIfAbsent(permanent.getId(), x -> new HashMap<>()).put(entry.getKey(), num);
        });
    }
    for (Permanent permanent : permanents) {
        counterMap.get(permanent.getId()).entrySet().stream().filter(entry -> entry.getValue() > 0).map(entry -> CounterType.findByName(entry.getKey()).createInstance(entry.getValue())).filter(counter -> creature.addCounters(counter, source.getControllerId(), source, game)).forEach(counter -> permanent.removeCounters(counter, source, game));
    }
    return true;
}
Also used : PermanentIdPredicate(mage.filter.predicate.permanent.PermanentIdPredicate) PermanentIdPredicate(mage.filter.predicate.permanent.PermanentIdPredicate) java.util(java.util) CounterAnyPredicate(mage.filter.predicate.permanent.CounterAnyPredicate) Predicates(mage.filter.predicate.Predicates) SubType(mage.constants.SubType) FilterPermanent(mage.filter.FilterPermanent) Player(mage.players.Player) CardType(mage.constants.CardType) FilterControlledCreaturePermanent(mage.filter.common.FilterControlledCreaturePermanent) EntersBattlefieldTriggeredAbility(mage.abilities.common.EntersBattlefieldTriggeredAbility) AddCountersTargetEffect(mage.abilities.effects.common.counter.AddCountersTargetEffect) FlashAbility(mage.abilities.keyword.FlashAbility) Outcome(mage.constants.Outcome) OneShotEffect(mage.abilities.effects.OneShotEffect) MageInt(mage.MageInt) Collectors(java.util.stream.Collectors) CardSetInfo(mage.cards.CardSetInfo) Game(mage.game.Game) CardImpl(mage.cards.CardImpl) Permanent(mage.game.permanent.Permanent) TargetCreaturePermanent(mage.target.common.TargetCreaturePermanent) HexproofAbility(mage.abilities.keyword.HexproofAbility) CounterType(mage.counters.CounterType) TargetPermanent(mage.target.TargetPermanent) Ability(mage.abilities.Ability) Player(mage.players.Player) FilterPermanent(mage.filter.FilterPermanent) FilterPermanent(mage.filter.FilterPermanent) FilterControlledCreaturePermanent(mage.filter.common.FilterControlledCreaturePermanent) Permanent(mage.game.permanent.Permanent) TargetCreaturePermanent(mage.target.common.TargetCreaturePermanent) TargetPermanent(mage.target.TargetPermanent) TargetPermanent(mage.target.TargetPermanent)

Aggregations

Outcome (mage.constants.Outcome)20 Player (mage.players.Player)19 Ability (mage.abilities.Ability)16 OneShotEffect (mage.abilities.effects.OneShotEffect)16 CardType (mage.constants.CardType)14 Game (mage.game.Game)14 UUID (java.util.UUID)13 CardImpl (mage.cards.CardImpl)13 CardSetInfo (mage.cards.CardSetInfo)13 Permanent (mage.game.permanent.Permanent)12 FilterPermanent (mage.filter.FilterPermanent)6 Target (mage.target.Target)6 Collectors (java.util.stream.Collectors)5 MageInt (mage.MageInt)5 MageObject (mage.MageObject)5 SubType (mage.constants.SubType)5 SpellAbility (mage.abilities.SpellAbility)4 Zone (mage.constants.Zone)4 CounterType (mage.counters.CounterType)4 TargetPermanent (mage.target.TargetPermanent)4