Search in sources :

Example 6 with RequirementEffect

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

the class InciteWarMustAttackEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player player = game.getPlayer(this.getTargetPointer().getFirst(game, source));
    if (player != null) {
        FilterCreaturePermanent filter = new FilterCreaturePermanent();
        filter.add(new ControllerIdPredicate(player.getId()));
        RequirementEffect effect = new AttacksIfAbleAllEffect(filter, Duration.EndOfTurn);
        game.addEffect(effect, source);
        return true;
    }
    return false;
}
Also used : RequirementEffect(mage.abilities.effects.RequirementEffect) TargetPlayer(mage.target.TargetPlayer) Player(mage.players.Player) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) ControllerIdPredicate(mage.filter.predicate.permanent.ControllerIdPredicate) AttacksIfAbleAllEffect(mage.abilities.effects.common.combat.AttacksIfAbleAllEffect)

Example 7 with RequirementEffect

use of mage.abilities.effects.RequirementEffect 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 8 with RequirementEffect

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

the class DomineeringWillEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
    if (targetPlayer != null) {
        ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfTurn, targetPlayer.getId());
        effect.setTargetPointer(new SecondTargetPointer());
        effect.setText("Target player gains control of up to three target nonattacking creatures until end of turn");
        game.addEffect(effect, source);
        Effect effect2 = new UntapTargetEffect();
        effect2.setTargetPointer(new SecondTargetPointer());
        effect2.setText("Untap those creatures");
        effect2.apply(game, source);
        RequirementEffect effect3 = new BlocksIfAbleTargetEffect(Duration.EndOfTurn);
        effect3.setTargetPointer(new SecondTargetPointer());
        effect3.setText("They block this turn if able");
        game.addEffect(effect3, source);
        return true;
    }
    return false;
}
Also used : SecondTargetPointer(mage.target.targetpointer.SecondTargetPointer) RequirementEffect(mage.abilities.effects.RequirementEffect) TargetPlayer(mage.target.TargetPlayer) Player(mage.players.Player) BlocksIfAbleTargetEffect(mage.abilities.effects.common.combat.BlocksIfAbleTargetEffect) GainControlTargetEffect(mage.abilities.effects.common.continuous.GainControlTargetEffect) RequirementEffect(mage.abilities.effects.RequirementEffect) OneShotEffect(mage.abilities.effects.OneShotEffect) ContinuousEffect(mage.abilities.effects.ContinuousEffect) UntapTargetEffect(mage.abilities.effects.common.UntapTargetEffect) Effect(mage.abilities.effects.Effect) BlocksIfAbleTargetEffect(mage.abilities.effects.common.combat.BlocksIfAbleTargetEffect) ContinuousEffect(mage.abilities.effects.ContinuousEffect) UntapTargetEffect(mage.abilities.effects.common.UntapTargetEffect) GainControlTargetEffect(mage.abilities.effects.common.continuous.GainControlTargetEffect)

Example 9 with RequirementEffect

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

the class ImaginaryThreatsEffect method apply.

@Override
public boolean apply(Game game, Ability source) {
    Player player = game.getPlayer(this.getTargetPointer().getFirst(game, source));
    if (player != null) {
        FilterCreaturePermanent filter = new FilterCreaturePermanent();
        filter.add(new ControllerIdPredicate(player.getId()));
        RequirementEffect effect = new AttacksIfAbleAllEffect(filter, Duration.EndOfTurn);
        game.addEffect(effect, source);
        return true;
    }
    return false;
}
Also used : RequirementEffect(mage.abilities.effects.RequirementEffect) Player(mage.players.Player) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) ControllerIdPredicate(mage.filter.predicate.permanent.ControllerIdPredicate) AttacksIfAbleAllEffect(mage.abilities.effects.common.combat.AttacksIfAbleAllEffect)

Example 10 with RequirementEffect

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

the class Combat method checkBlockRequirementsAfter.

/**
 * 509.1c The defending player checks each creature they control to see
 * whether it's affected by any requirements (effects that say a creature
 * must block, or that it must block if some condition is met). If the
 * number of requirements that are being obeyed is fewer than the maximum
 * possible number of requirements that could be obeyed without disobeying
 * any restrictions, the declaration of blockers is illegal. If a creature
 * can't block unless a player pays a cost, that player is not required to
 * pay that cost, even if blocking with that creature would increase the
 * number of requirements being obeyed.
 * <p>
 * <p>
 * Example: A player controls one creature that "blocks if able" and another
 * creature with no abilities. An effect states "Creatures can't be blocked
 * except by two or more creatures." Having only the first creature block
 * violates the restriction. Having neither creature block fulfills the
 * restriction but not the requirement. Having both creatures block the same
 * attacking creature fulfills both the restriction and the requirement, so
 * that's the only option.
 *
 * @param player
 * @param controller
 * @param game
 * @return
 */
public boolean checkBlockRequirementsAfter(Player player, Player controller, Game game) {
    // Get once a list of all opponents in range
    Set<UUID> opponents = game.getOpponents(attackingPlayerId);
    // 20101001 - 509.1c
    // map with attackers (UUID) that must be blocked by at least one blocker and a set of all creatures that can block it and don't block yet
    Map<UUID, Set<UUID>> mustBeBlockedByAtLeastX = new HashMap<>();
    Map<UUID, Integer> minNumberOfBlockersMap = new HashMap<>();
    // check mustBlock requirements of creatures from opponents of attacking player
    for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURES_CONTROLLED, player.getId(), game)) {
        // creature is controlled by an opponent of the attacker
        if (opponents.contains(creature.getControllerId())) {
            // Creature is already blocking but not forced to do so
            if (creature.getBlocking() > 0) {
                // get all requirement effects that apply to the creature (e.g. is able to block attacker)
                for (Map.Entry<RequirementEffect, Set<Ability>> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, false, game).entrySet()) {
                    RequirementEffect effect = entry.getKey();
                    // get possible mustBeBlockedByAtLeastX blocker
                    for (Ability ability : entry.getValue()) {
                        UUID toBeBlockedCreature = effect.mustBlockAttackerIfElseUnblocked(ability, game);
                        if (toBeBlockedCreature != null) {
                            CombatGroup toBeBlockedGroup = findGroup(toBeBlockedCreature);
                            if (toBeBlockedGroup != null && toBeBlockedGroup.getDefendingPlayerId().equals(creature.getControllerId())) {
                                minNumberOfBlockersMap.put(toBeBlockedCreature, effect.getMinNumberOfBlockers());
                                Set<UUID> potentialBlockers;
                                if (mustBeBlockedByAtLeastX.containsKey(toBeBlockedCreature)) {
                                    potentialBlockers = mustBeBlockedByAtLeastX.get(toBeBlockedCreature);
                                } else {
                                    potentialBlockers = new HashSet<>();
                                    mustBeBlockedByAtLeastX.put(toBeBlockedCreature, potentialBlockers);
                                }
                                potentialBlockers.add(creature.getId());
                            }
                        }
                    }
                    // check the mustBlockAllAttackers requirement for creatures already blocking (Blaze of Glory) -------------------------------
                    if (effect.mustBlockAllAttackers(game)) {
                        // find all the attackers that the creature can block (and no restictions prevent this)
                        Set<UUID> attackersToBlock = new HashSet<>();
                        boolean mayBlock = false;
                        for (UUID attackingCreatureId : getAttackers()) {
                            if (creature.canBlock(attackingCreatureId, game)) {
                                Permanent attackingCreature = game.getPermanent(attackingCreatureId);
                                if (attackingCreature != null) {
                                    // check if the attacker is already blocked by a max of blockers, so blocker can't block it also
                                    if (attackingCreature.getMaxBlockedBy() != 0) {
                                        // 0 = no restriction about the number of possible blockers
                                        int alreadyBlockingCreatures = 0;
                                        for (CombatGroup group : getGroups()) {
                                            if (group.getAttackers().contains(attackingCreatureId)) {
                                                alreadyBlockingCreatures = group.getBlockers().size();
                                                break;
                                            }
                                        }
                                        if (attackingCreature.getMaxBlockedBy() <= alreadyBlockingCreatures) {
                                            // Attacker can't be blocked by more blockers so check next attacker
                                            continue;
                                        }
                                    }
                                    // check if enough possible blockers are available, if true, mayBlock can be set to true
                                    if (attackingCreature.getMinBlockedBy() > 1) {
                                        int alreadyBlockingCreatures = 0;
                                        for (CombatGroup group : getGroups()) {
                                            if (group.getAttackers().contains(attackingCreatureId)) {
                                                alreadyBlockingCreatures = group.getBlockers().size();
                                                break;
                                            }
                                        }
                                        if (attackingCreature.getMinBlockedBy() >= alreadyBlockingCreatures) {
                                            // Attacker can't be blocked by the current blocker amount so check next attacker
                                            continue;
                                        }
                                    } else {
                                        attackersToBlock.add(attackingCreatureId);
                                    }
                                }
                            }
                        }
                        if (!attackersToBlock.isEmpty()) {
                            for (UUID attackerId : attackersToBlock) {
                                if (!findGroup(attackerId).getBlockers().contains(creature.getId())) {
                                    mayBlock = true;
                                    break;
                                }
                            }
                        }
                        // if creature can block more attackers, inform human player or set blocks for AI player
                        if (mayBlock) {
                            if (controller.isHuman()) {
                                controller.resetPlayerPassedActions();
                                game.informPlayer(controller, "Creature should block all attackers it's able to this turn: " + creature.getIdName());
                            } else {
                                Player defender = game.getPlayer(creature.getControllerId());
                                if (defender != null) {
                                    for (UUID attackingCreatureId : getAttackers()) {
                                        if (creature.canBlock(attackingCreatureId, game) && !findGroup(attackingCreatureId).getBlockers().contains(creature.getId()) && attackersToBlock.contains(attackingCreatureId)) {
                                            // TODO: might need to revisit this (calls some pickBlockerOrder instances even for a single blocker - damage distribution appears to be working correctly however)
                                            defender.declareBlocker(defender.getId(), creature.getId(), attackingCreatureId, game);
                                        }
                                    }
                                }
                            }
                            return false;
                        }
                    }
                }
            }
            // Creature is not blocking yet
            if (creature.getBlocking() == 0) {
                // get all requirement effects that apply to the creature
                for (Map.Entry<RequirementEffect, Set<Ability>> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, false, game).entrySet()) {
                    RequirementEffect effect = entry.getKey();
                    // get possible mustBeBlockedByAtLeastX blocker
                    for (Ability ability : entry.getValue()) {
                        UUID toBeBlockedCreature = effect.mustBlockAttackerIfElseUnblocked(ability, game);
                        if (toBeBlockedCreature != null) {
                            CombatGroup toBeBlockedGroup = findGroup(toBeBlockedCreature);
                            if (toBeBlockedGroup != null && toBeBlockedGroup.getDefendingPlayerId().equals(creature.getControllerId())) {
                                minNumberOfBlockersMap.put(toBeBlockedCreature, effect.getMinNumberOfBlockers());
                                Set<UUID> potentialBlockers;
                                if (mustBeBlockedByAtLeastX.containsKey(toBeBlockedCreature)) {
                                    potentialBlockers = mustBeBlockedByAtLeastX.get(toBeBlockedCreature);
                                } else {
                                    potentialBlockers = new HashSet<>();
                                    mustBeBlockedByAtLeastX.put(toBeBlockedCreature, potentialBlockers);
                                }
                                potentialBlockers.add(creature.getId());
                            }
                        }
                    }
                    // check the mustBlockAny requirement (and mustBlockAllAttackers for not blocking creatures) ----------------------------------------
                    if (effect.mustBlockAny(game) || effect.mustBlockAllAttackers(game)) {
                        // check that it can block at least one of the attackers and no restictions prevent this
                        boolean mayBlock = false;
                        for (UUID attackingCreatureId : getAttackers()) {
                            if (creature.canBlock(attackingCreatureId, game)) {
                                Permanent attackingCreature = game.getPermanent(attackingCreatureId);
                                if (attackingCreature != null) {
                                    // check if the attacker is already blocked by a max of blockers, so blocker can't block it also
                                    if (attackingCreature.getMaxBlockedBy() != 0) {
                                        // 0 = no restriction about the number of possible blockers
                                        int alreadyBlockingCreatures = 0;
                                        for (CombatGroup group : getGroups()) {
                                            if (group.getAttackers().contains(attackingCreatureId)) {
                                                alreadyBlockingCreatures = group.getBlockers().size();
                                                break;
                                            }
                                        }
                                        if (attackingCreature.getMaxBlockedBy() <= alreadyBlockingCreatures) {
                                            // Attacker can't be blocked by more blockers so check next attacker
                                            continue;
                                        }
                                    }
                                    // check if enough possible blockers are available, if true, mayBlock can be set to true
                                    if (attackingCreature.getMinBlockedBy() > 1) {
                                        int alreadyBlockingCreatures = 0;
                                        for (CombatGroup group : getGroups()) {
                                            if (group.getAttackers().contains(attackingCreatureId)) {
                                                alreadyBlockingCreatures = group.getBlockers().size();
                                                break;
                                            }
                                        }
                                        if (attackingCreature.getMinBlockedBy() >= alreadyBlockingCreatures) {
                                            // Attacker can't be blocked by the current blocker amount so check next attacker
                                            continue;
                                        }
                                    } else {
                                        mayBlock = true;
                                        break;
                                    }
                                }
                            }
                        }
                        // if creature can block, inform human player or set block for AI player
                        if (mayBlock) {
                            if (controller.isHuman()) {
                                controller.resetPlayerPassedActions();
                                game.informPlayer(controller, "Creature should block this turn: " + creature.getIdName());
                            } else {
                                Player defender = game.getPlayer(creature.getControllerId());
                                if (defender != null) {
                                    for (UUID attackingCreatureId : getAttackers()) {
                                        if (creature.canBlock(attackingCreatureId, game) && !findGroup(attackingCreatureId).getBlockers().contains(creature.getId())) {
                                            defender.declareBlocker(defender.getId(), creature.getId(), attackingCreatureId, game);
                                            break;
                                        }
                                    }
                                }
                            }
                            return false;
                        }
                    }
                }
            }
        }
    }
    // check if for attacking creatures with mustBeBlockedByAtLeastX requirements are fulfilled
    for (UUID toBeBlockedCreatureId : mustBeBlockedByAtLeastX.keySet()) {
        for (CombatGroup combatGroup : game.getCombat().getGroups()) {
            if (combatGroup.getAttackers().contains(toBeBlockedCreatureId)) {
                boolean requirementFulfilled = false;
                // Check whether an applicable creature is blocking.
                for (UUID blockerId : combatGroup.getBlockers()) {
                    if (mustBeBlockedByAtLeastX.get(toBeBlockedCreatureId).contains(blockerId)) {
                        requirementFulfilled = true;
                        break;
                    }
                }
                requirementFulfilled &= (combatGroup.getBlockers().size() >= Math.min(minNumberOfBlockersMap.get(toBeBlockedCreatureId), mustBeBlockedByAtLeastX.get(toBeBlockedCreatureId).size()));
                if (!requirementFulfilled) {
                    // creature is not blocked but has possible blockers
                    if (controller.isHuman()) {
                        Permanent toBeBlockedCreature = game.getPermanent(toBeBlockedCreatureId);
                        if (toBeBlockedCreature != null) {
                            // read through all possible blockers
                            for (UUID possibleBlockerId : mustBeBlockedByAtLeastX.get(toBeBlockedCreatureId)) {
                                if (combatGroup.getBlockers().contains(possibleBlockerId)) {
                                    continue;
                                }
                                String blockRequiredMessage = isCreatureDoingARequiredBlock(possibleBlockerId, toBeBlockedCreatureId, mustBeBlockedByAtLeastX, game);
                                if (blockRequiredMessage != null) {
                                    // message means not required
                                    removeBlocker(possibleBlockerId, game);
                                    controller.resetPlayerPassedActions();
                                    game.informPlayer(controller, blockRequiredMessage + " Existing block removed. It's a requirement to block " + toBeBlockedCreature.getIdName() + '.');
                                    return false;
                                }
                            }
                        }
                    } else {
                        // take the first potential blocker from the set to block for the AI
                        for (UUID possibleBlockerId : mustBeBlockedByAtLeastX.get(toBeBlockedCreatureId)) {
                            String blockRequiredMessage = isCreatureDoingARequiredBlock(possibleBlockerId, toBeBlockedCreatureId, mustBeBlockedByAtLeastX, game);
                            if (blockRequiredMessage != null) {
                                // set the block
                                Permanent possibleBlocker = game.getPermanent(possibleBlockerId);
                                Player defender = game.getPlayer(possibleBlocker.getControllerId());
                                if (defender != null) {
                                    if (possibleBlocker.getBlocking() > 0) {
                                        removeBlocker(possibleBlockerId, game);
                                    }
                                    defender.declareBlocker(defender.getId(), possibleBlockerId, toBeBlockedCreatureId, game);
                                }
                                if (combatGroup.getBlockers().size() >= minNumberOfBlockersMap.get(toBeBlockedCreatureId)) {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    // check if creatures are forced to block but do not block at all or block creatures they are not forced to block
    StringBuilder sb = new StringBuilder();
    for (Map.Entry<UUID, Set<UUID>> entry : creatureMustBlockAttackers.entrySet()) {
        boolean blockIsValid = true;
        Permanent creatureForcedToBlock = game.getPermanent(entry.getKey());
        if (creatureForcedToBlock == null) {
            break;
        }
        if (!creatureForcedToBlock.isControlledBy(player.getId())) {
            // ignore creatures controlled by other players
            continue;
        }
        // While if assigned all to one the block is possible
        if (creatureForcedToBlock.getBlocking() == 0) {
            blockIsValid = entry.getValue().isEmpty();
            for (UUID possibleAttackerId : entry.getValue()) {
                CombatGroup attackersGroup = game.getCombat().findGroup(possibleAttackerId);
                Permanent attackingCreature = game.getPermanent(possibleAttackerId);
                if (attackersGroup == null || attackingCreature == null) {
                    continue;
                }
                if (attackingCreature.getMinBlockedBy() > 1) {
                    // e.g. Menace
                    if (attackersGroup.getBlockers().size() + 1 < attackingCreature.getMinBlockedBy()) {
                        blockIsValid = true;
                    }
                }
            }
        } else {
            blockIsValid = false;
            // which attacker is the creature blocking
            CombatGroups: for (CombatGroup combatGroup : game.getCombat().getGroups()) {
                if (combatGroup.getBlockers().contains(creatureForcedToBlock.getId())) {
                    for (UUID forcingAttackerId : combatGroup.getAttackers()) {
                        if (entry.getValue().contains(forcingAttackerId)) {
                            // the creature is blocking a forcing attacker, so the block is ok
                            blockIsValid = true;
                            break CombatGroups;
                        } else // check if the blocker blocks a attacker that must be blocked at least by one and is the only blocker, this block is also valid
                        {
                            if (combatGroup.getBlockers().size() == 1) {
                                if (mustBeBlockedByAtLeastX.containsKey(forcingAttackerId)) {
                                    if (mustBeBlockedByAtLeastX.get(forcingAttackerId).contains(creatureForcedToBlock.getId())) {
                                        blockIsValid = true;
                                        break CombatGroups;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        if (!blockIsValid) {
            sb.append(' ').append(creatureForcedToBlock.getIdName());
        }
    }
    if (sb.length() > 0) {
        if (controller.isHuman()) {
            controller.resetPlayerPassedActions();
            sb.insert(0, "Some creatures are forced to block certain attacker(s):\n");
            sb.append("\nPlease block with each of these creatures an appropriate attacker.");
            game.informPlayer(controller, sb.toString());
        }
        return false;
    }
    return true;
}
Also used : JohanVigilanceAbility(mage.abilities.keyword.special.JohanVigilanceAbility) VigilanceAbility(mage.abilities.keyword.VigilanceAbility) BandingAbility(mage.abilities.keyword.BandingAbility) BandsWithOtherAbility(mage.abilities.keyword.BandsWithOtherAbility) Ability(mage.abilities.Ability) Player(mage.players.Player) FilterControlledCreaturePermanent(mage.filter.common.FilterControlledCreaturePermanent) FilterCreaturePermanent(mage.filter.common.FilterCreaturePermanent) Permanent(mage.game.permanent.Permanent) TargetControlledPermanent(mage.target.common.TargetControlledPermanent) RequirementEffect(mage.abilities.effects.RequirementEffect)

Aggregations

RequirementEffect (mage.abilities.effects.RequirementEffect)12 Player (mage.players.Player)10 FilterCreaturePermanent (mage.filter.common.FilterCreaturePermanent)8 Permanent (mage.game.permanent.Permanent)5 Ability (mage.abilities.Ability)4 AttacksIfAbleAllEffect (mage.abilities.effects.common.combat.AttacksIfAbleAllEffect)4 RestrictionEffect (mage.abilities.effects.RestrictionEffect)3 BandingAbility (mage.abilities.keyword.BandingAbility)3 BandsWithOtherAbility (mage.abilities.keyword.BandsWithOtherAbility)3 VigilanceAbility (mage.abilities.keyword.VigilanceAbility)3 JohanVigilanceAbility (mage.abilities.keyword.special.JohanVigilanceAbility)3 FilterControlledCreaturePermanent (mage.filter.common.FilterControlledCreaturePermanent)3 ControllerIdPredicate (mage.filter.predicate.permanent.ControllerIdPredicate)3 TargetPlayer (mage.target.TargetPlayer)3 TargetControlledPermanent (mage.target.common.TargetControlledPermanent)3 MageObject (mage.MageObject)2 Target (mage.target.Target)2 FixedTarget (mage.target.targetpointer.FixedTarget)2 Map (java.util.Map)1 Set (java.util.Set)1