Search in sources :

Example 11 with RestrictionEffect

use of mage.abilities.effects.RestrictionEffect 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 12 with RestrictionEffect

use of mage.abilities.effects.RestrictionEffect in project mage by magefree.

the class UntapSourceDuringEachOtherPlayersUntapStepEffect method apply.

@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
    boolean applied = Boolean.TRUE.equals(game.getState().getValue(source.getSourceId() + "applied"));
    if (!applied && layer == Layer.RulesEffects) {
        if (!source.isControlledBy(game.getActivePlayerId()) && game.getStep() != null && game.getStep().getType() == PhaseStep.UNTAP) {
            game.getState().setValue(source.getSourceId() + "applied", true);
            Permanent permanent = game.getPermanent(source.getSourceId());
            if (permanent != null) {
                boolean untap = true;
                for (RestrictionEffect effect : game.getContinuousEffects().getApplicableRestrictionEffects(permanent, game).keySet()) {
                    untap &= effect.canBeUntapped(permanent, source, game, true);
                }
                if (untap) {
                    permanent.untap(game);
                }
            }
        }
    } else if (applied && layer == Layer.RulesEffects) {
        if (game.getStep() != null && game.getStep().getType() == PhaseStep.END_TURN) {
            game.getState().setValue(source.getSourceId() + "applied", false);
        }
    }
    return true;
}
Also used : Permanent(mage.game.permanent.Permanent) RestrictionEffect(mage.abilities.effects.RestrictionEffect)

Example 13 with RestrictionEffect

use of mage.abilities.effects.RestrictionEffect in project mage by magefree.

the class PermanentImpl method getRules.

/**
 * @param game can be null, e.g. for cards viewer
 * @return
 */
@Override
public List<String> getRules(Game game) {
    try {
        List<String> rules = getRules();
        // info
        if (info != null) {
            for (String data : info.values()) {
                rules.add(data);
            }
        }
        // ability hints
        List<String> abilityHints = new ArrayList<>();
        if (HintUtils.ABILITY_HINTS_ENABLE) {
            for (Ability ability : getAbilities(game)) {
                for (Hint hint : ability.getHints()) {
                    String s = hint.getText(game, ability);
                    if (s != null && !s.isEmpty()) {
                        abilityHints.add(s);
                    }
                }
            }
        }
        // restrict hints
        List<String> restrictHints = new ArrayList<>();
        if (game != null && HintUtils.RESTRICT_HINTS_ENABLE) {
            // restrict
            for (Map.Entry<RestrictionEffect, Set<Ability>> entry : game.getContinuousEffects().getApplicableRestrictionEffects(this, game).entrySet()) {
                for (Ability ability : entry.getValue()) {
                    if (!entry.getKey().canAttack(game, false) || !entry.getKey().canAttack(this, null, ability, game, false)) {
                        restrictHints.add(HintUtils.prepareText("Can't attack" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_RESTRICT));
                    }
                    if (!entry.getKey().canBlock(null, this, ability, game, false)) {
                        restrictHints.add(HintUtils.prepareText("Can't block" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_RESTRICT));
                    }
                    if (!entry.getKey().canBeUntapped(this, ability, game, false)) {
                        restrictHints.add(HintUtils.prepareText("Can't untapped" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_RESTRICT));
                    }
                    if (!entry.getKey().canUseActivatedAbilities(this, ability, game, false)) {
                        restrictHints.add(HintUtils.prepareText("Can't use activated abilities" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_RESTRICT));
                    }
                    if (!entry.getKey().canTransform(this, ability, game, false)) {
                        restrictHints.add(HintUtils.prepareText("Can't transform" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_RESTRICT));
                    }
                }
            }
            // requirement
            for (Map.Entry<RequirementEffect, Set<Ability>> entry : game.getContinuousEffects().getApplicableRequirementEffects(this, false, game).entrySet()) {
                for (Ability ability : entry.getValue()) {
                    if (entry.getKey().mustAttack(game)) {
                        restrictHints.add(HintUtils.prepareText("Must attack" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_REQUIRE));
                    }
                    if (entry.getKey().mustBlock(game)) {
                        restrictHints.add(HintUtils.prepareText("Must block" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_REQUIRE));
                    }
                    if (entry.getKey().mustBlockAny(game)) {
                        restrictHints.add(HintUtils.prepareText("Must block any" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_REQUIRE));
                    }
                    if (entry.getKey().mustBlockAllAttackers(game)) {
                        restrictHints.add(HintUtils.prepareText("Must block all attackers" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_REQUIRE));
                    }
                    MageObject object = game.getObject(entry.getKey().mustAttackDefender(ability, game));
                    if (object != null) {
                        restrictHints.add(HintUtils.prepareText("Must attack defender " + object.getLogName() + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_REQUIRE));
                    }
                    object = game.getObject(entry.getKey().mustBlockAttacker(ability, game));
                    if (object != null) {
                        restrictHints.add(HintUtils.prepareText("Must block attacker " + object.getLogName() + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_REQUIRE));
                    }
                    object = game.getObject(entry.getKey().mustBlockAttackerIfElseUnblocked(ability, game));
                    if (object != null) {
                        restrictHints.add(HintUtils.prepareText("Must block attacker if able " + object.getLogName() + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_REQUIRE));
                    }
                }
            }
            restrictHints.sort(String::compareTo);
        }
        // total hints
        if (!abilityHints.isEmpty() || !restrictHints.isEmpty()) {
            rules.add(HintUtils.HINT_START_MARK);
            HintUtils.appendHints(rules, abilityHints);
            HintUtils.appendHints(rules, restrictHints);
        }
        return rules;
    } catch (Exception e) {
        return CardUtil.RULES_ERROR_INFO;
    }
}
Also used : SpellAbility(mage.abilities.SpellAbility) Ability(mage.abilities.Ability) Hint(mage.abilities.hint.Hint) MageObject(mage.MageObject) RequirementEffect(mage.abilities.effects.RequirementEffect) RestrictionEffect(mage.abilities.effects.RestrictionEffect)

Example 14 with RestrictionEffect

use of mage.abilities.effects.RestrictionEffect in project mage by magefree.

the class WordOfCommandTestFlashEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player sourceController = game.getPlayer(source.getControllerId());
    Player targetPlayer = game.getPlayer(source.getFirstTarget());
    MageObject sourceObject = game.getObject(source.getSourceId());
    Card card = null;
    if (sourceController != null && targetPlayer != null && sourceObject != null) {
        Player controller = null;
        Spell wordOfCommand = game.getSpell(source.getSourceId());
        if (wordOfCommand != null) {
            if (wordOfCommand.getCommandedBy() != null) {
                controller = game.getPlayer(wordOfCommand.getCommandedBy());
            } else {
                controller = game.getPlayer(sourceController.getTurnControlledBy());
            }
        }
        if (controller == null) {
            // reset the controller to avoid NPE
            controller = sourceController;
        }
        // Look at target opponent's hand and choose a card from it
        TargetCard targetCard = new TargetCard(Zone.HAND, new FilterCard());
        if (controller.choose(Outcome.Discard, targetPlayer.getHand(), targetCard, game)) {
            card = game.getCard(targetCard.getFirstTarget());
        }
        // You control that player until Word of Command finishes resolving
        CardUtil.takeControlUnderPlayerStart(game, controller, targetPlayer, true);
        // The player plays that card if able
        if (card != null) {
            // While doing so, the player can activate mana abilities only if they're from lands that player controls
            RestrictionEffect effect = new WordOfCommandCantActivateEffect();
            effect.setTargetPointer(new FixedTarget(targetPlayer.getId()));
            game.addEffect(effect, source);
            // and only if mana they produce is spent to activate other mana abilities of lands they control and/or play that card
            ManaPool manaPool = targetPlayer.getManaPool();
            manaPool.setForcedToPay(true);
            manaPool.storeMana();
            int bookmark = game.bookmarkState();
            boolean canPlay = checkPlayability(card, targetPlayer, game, source);
            while (canPlay && targetPlayer.canRespond() && !targetPlayer.playCard(card, game, false, new ApprovingObject(source, game))) {
                SpellAbility spellAbility = card.getSpellAbility();
                if (spellAbility != null) {
                    spellAbility.getManaCostsToPay().clear();
                    spellAbility.getManaCostsToPay().addAll(spellAbility.getManaCosts());
                    // force rollback if card was deemed playable
                    ((ManaCostsImpl) spellAbility.getManaCostsToPay()).forceManaRollback(game, manaPool);
                    canPlay = checkPlayability(card, targetPlayer, game, source);
                } else {
                    break;
                }
            }
            if (!canPlay) {
                game.informPlayers(targetPlayer.getLogName() + " didn't play " + card.getLogName() + " (card can't be played)");
            }
            // duplicate in case of a new mana pool existing - probably not necessary, but just in case
            manaPool.setForcedToPay(false);
            // a rollback creates a new mana pool for the player, so it's necessary to find it again
            manaPool = targetPlayer.getManaPool();
            manaPool.setForcedToPay(false);
            game.removeBookmark(bookmark);
            targetPlayer.resetStoredBookmark(game);
            for (RestrictionEffect eff : game.getContinuousEffects().getRestrictionEffects()) {
                if (eff instanceof WordOfCommandCantActivateEffect) {
                    eff.discard();
                    break;
                }
            }
            game.getContinuousEffects().removeInactiveEffects(game);
            Spell spell = game.getSpell(card.getId());
            if (spell != null) {
                // If the chosen card is cast as a spell, you control the player while that spell is resolving
                spell.setCommandedBy(controller.getId());
            }
        }
        wordOfCommand = game.getSpell(source.getSourceId());
        if (wordOfCommand != null) {
            // You control the player until Word of Command finishes resolving
            wordOfCommand.setCommandedBy(controller.getId());
        } else {
            CardUtil.takeControlUnderPlayerEnd(game, controller, targetPlayer);
        }
        return true;
    }
    return false;
}
Also used : FixedTarget(mage.target.targetpointer.FixedTarget) Player(mage.players.Player) ApprovingObject(mage.ApprovingObject) MageObject(mage.MageObject) TargetCard(mage.target.TargetCard) SpellAbility(mage.abilities.SpellAbility) ManaPool(mage.players.ManaPool) ManaCostsImpl(mage.abilities.costs.mana.ManaCostsImpl) Spell(mage.game.stack.Spell) TargetCard(mage.target.TargetCard) Card(mage.cards.Card) FilterCard(mage.filter.FilterCard) FilterCard(mage.filter.FilterCard) RestrictionEffect(mage.abilities.effects.RestrictionEffect)

Example 15 with RestrictionEffect

use of mage.abilities.effects.RestrictionEffect in project mage by magefree.

the class TraceUtil method traceForPermanent.

private static void traceForPermanent(Game game, Permanent permanent, String uuid, ContinuousEffectsList<RestrictionEffect> restrictionEffects) {
    for (RestrictionEffect effect : restrictionEffects) {
        log.error(uuid + "     effect=" + effect.toString() + " id=" + effect.getId());
        for (Ability ability : restrictionEffects.getAbility(effect.getId())) {
            if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, permanent, null)) {
                log.error(uuid + "        ability=" + ability + ", applies_to_attacker=" + effect.applies(permanent, ability, game));
            } else {
                boolean usable = ability.isInUseableZone(game, permanent, null);
                log.error(uuid + "        instanceof StaticAbility: " + (ability instanceof StaticAbility) + ", ability=" + ability);
                log.error(uuid + "        usable zone: " + usable + ", ability=" + ability);
                if (!usable) {
                    Zone zone = ability.getZone();
                    log.error(uuid + "        zone: " + zone);
                    MageObject object = game.getObject(ability.getSourceId());
                    log.error(uuid + "        object: " + object);
                    if (object != null) {
                        log.error(uuid + "        contains ability: " + object.getAbilities().contains(ability));
                    }
                    Zone test = game.getState().getZone(ability.getSourceId());
                    log.error(uuid + "        test_zone: " + test);
                }
            }
        }
    }
}
Also used : CantBeBlockedSourceAbility(mage.abilities.keyword.CantBeBlockedSourceAbility) StaticAbility(mage.abilities.StaticAbility) ReachAbility(mage.abilities.keyword.ReachAbility) TriggeredAbility(mage.abilities.TriggeredAbility) FlyingAbility(mage.abilities.keyword.FlyingAbility) Ability(mage.abilities.Ability) IntimidateAbility(mage.abilities.keyword.IntimidateAbility) StaticAbility(mage.abilities.StaticAbility) Zone(mage.constants.Zone) MageObject(mage.MageObject) RestrictionEffect(mage.abilities.effects.RestrictionEffect)

Aggregations

RestrictionEffect (mage.abilities.effects.RestrictionEffect)16 Permanent (mage.game.permanent.Permanent)11 FilterCreaturePermanent (mage.filter.common.FilterCreaturePermanent)8 Ability (mage.abilities.Ability)7 Player (mage.players.Player)7 MageObject (mage.MageObject)5 FixedTarget (mage.target.targetpointer.FixedTarget)5 FilterControlledCreaturePermanent (mage.filter.common.FilterControlledCreaturePermanent)4 ArrayList (java.util.ArrayList)3 UUID (java.util.UUID)3 RequirementEffect (mage.abilities.effects.RequirementEffect)3 BandingAbility (mage.abilities.keyword.BandingAbility)3 BandsWithOtherAbility (mage.abilities.keyword.BandsWithOtherAbility)3 FlyingAbility (mage.abilities.keyword.FlyingAbility)3 VigilanceAbility (mage.abilities.keyword.VigilanceAbility)3 JohanVigilanceAbility (mage.abilities.keyword.special.JohanVigilanceAbility)3 TargetControlledPermanent (mage.target.common.TargetControlledPermanent)3 SpellAbility (mage.abilities.SpellAbility)2 StaticAbility (mage.abilities.StaticAbility)2 TriggeredAbility (mage.abilities.TriggeredAbility)2