Search in sources :

Example 1 with FilterCreatureForCombatBlock

use of mage.filter.common.FilterCreatureForCombatBlock in project mage by magefree.

the class HumanPlayer method selectBlockers.

@Override
public void selectBlockers(Ability source, Game game, UUID defendingPlayerId) {
    if (gameInCheckPlayableState(game)) {
        return;
    }
    FilterCreatureForCombatBlock filter = filterCreatureForCombatBlock.copy();
    filter.add(new ControllerIdPredicate(defendingPlayerId));
    // stop skip on any/zero permanents available
    int possibleBlockersCount = game.getBattlefield().count(filter, null, playerId, game);
    boolean canStopOnAny = possibleBlockersCount != 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithAnyPermanents();
    boolean canStopOnZero = possibleBlockersCount == 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithZeroPermanents();
    // skip declare blocker step
    // as opposed to declare attacker - it can be skipped by ANY skip button TODO: make same for declare attackers and rework skip buttons (normal and forced)
    boolean skipButtonActivated = passedAllTurns || passedUntilEndStepBeforeMyTurn || passedTurn || passedUntilEndOfTurn || passedUntilNextMain;
    if (skipButtonActivated && !canStopOnAny && !canStopOnZero) {
        return;
    }
    while (canRespond()) {
        updateGameStatePriority("selectBlockers", game);
        prepareForResponse(game);
        if (!isExecutingMacro()) {
            Map<String, Serializable> options = new HashMap<>();
            java.util.List<UUID> possibleBlockers = game.getBattlefield().getActivePermanents(filter, playerId, game).stream().map(p -> p.getId()).collect(Collectors.toList());
            options.put(Constants.Option.POSSIBLE_BLOCKERS, (Serializable) possibleBlockers);
            game.fireSelectEvent(playerId, "Select blockers", options);
        }
        waitForResponse(game);
        UUID responseId = getFixedResponseUUID(game);
        if (response.getBoolean() != null) {
            return;
        } else if (response.getInteger() != null) {
            return;
        } else if (responseId != null) {
            Permanent blocker = game.getPermanent(responseId);
            if (blocker != null) {
                boolean removeBlocker = false;
                // does not block yet and can block or can block more attackers
                if (filter.match(blocker, null, playerId, game)) {
                    selectCombatGroup(defendingPlayerId, blocker.getId(), game);
                } else if (filterBlock.match(blocker, null, playerId, game) && game.getStack().isEmpty()) {
                    removeBlocker = true;
                }
                if (removeBlocker) {
                    game.getCombat().removeBlocker(blocker.getId(), game);
                }
            }
        }
    }
}
Also used : RequirementEffect(mage.abilities.effects.RequirementEffect) FilterBlockingCreature(mage.filter.common.FilterBlockingCreature) Match(mage.game.match.Match) REQUEST_AUTO_ANSWER_RESET_ALL(mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL) Logger(org.apache.log4j.Logger) TapSourceCost(mage.abilities.costs.common.TapSourceCost) ManaCost(mage.abilities.costs.mana.ManaCost) mage.constants(mage.constants) Draft(mage.game.draft.Draft) mage.abilities(mage.abilities) Choice(mage.choices.Choice) ActivatedManaAbilityImpl(mage.abilities.mana.ActivatedManaAbilityImpl) StaticFilters(mage.filter.StaticFilters) GameLog(mage.util.GameLog) TargetAnyTarget(mage.target.common.TargetAnyTarget) mage.cards(mage.cards) FilterCreatureForCombatBlock(mage.filter.common.FilterCreatureForCombatBlock) CardUtil(mage.util.CardUtil) Collectors(java.util.stream.Collectors) Serializable(java.io.Serializable) FilterCreatureForCombat(mage.filter.common.FilterCreatureForCombat) TargetDefender(mage.target.common.TargetDefender) List(java.util.List) Permanent(mage.game.permanent.Permanent) TargetAmount(mage.target.TargetAmount) Tournament(mage.game.tournament.Tournament) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) Target(mage.target.Target) java.util(java.util) PlayerImpl(mage.players.PlayerImpl) ControllerIdPredicate(mage.filter.predicate.permanent.ControllerIdPredicate) PlayerList(mage.players.PlayerList) DeclareAttackerEvent(mage.game.events.DeclareAttackerEvent) Player(mage.players.Player) ManaUtil(mage.util.ManaUtil) TargetCard(mage.target.TargetCard) FilterAttackingCreature(mage.filter.common.FilterAttackingCreature) MageObject(mage.MageObject) CombatGroup(mage.game.combat.CombatGroup) Spell(mage.game.stack.Spell) SacrificeSourceCost(mage.abilities.costs.common.SacrificeSourceCost) Deck(mage.cards.decks.Deck) TRIGGER_AUTO_ORDER_RESET_ALL(mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL) TargetAttackingCreature(mage.target.common.TargetAttackingCreature) java.awt(java.awt) VariableCost(mage.abilities.costs.VariableCost) ManaCostsImpl(mage.abilities.costs.mana.ManaCostsImpl) Game(mage.game.Game) ManaAbility(mage.abilities.mana.ManaAbility) ChoiceImpl(mage.choices.ChoiceImpl) GameImpl(mage.game.GameImpl) MessageToClient(mage.util.MessageToClient) HintUtils(mage.abilities.hint.HintUtils) TargetPermanent(mage.target.TargetPermanent) Serializable(java.io.Serializable) Permanent(mage.game.permanent.Permanent) TargetPermanent(mage.target.TargetPermanent) FilterCreatureForCombatBlock(mage.filter.common.FilterCreatureForCombatBlock) java.util(java.util) ControllerIdPredicate(mage.filter.predicate.permanent.ControllerIdPredicate)

Example 2 with FilterCreatureForCombatBlock

use of mage.filter.common.FilterCreatureForCombatBlock in project mage by magefree.

the class HumanPlayer method priority.

@Override
public boolean priority(Game game) {
    passed = false;
    // TODO: use controlling player in all choose dialogs (and canRespond too, what's with take control of player AI?!)
    if (canRespond()) {
        HumanPlayer controllingPlayer = this;
        if (isGameUnderControl()) {
            // TODO: must be ! to get real controlling player
            Player player = game.getPlayer(getTurnControlledBy());
            if (player instanceof HumanPlayer) {
                controllingPlayer = (HumanPlayer) player;
            }
        }
        if (getJustActivatedType() != null && !holdingPriority) {
            if (controllingPlayer.getUserData().isPassPriorityCast() && getJustActivatedType() == AbilityType.SPELL) {
                setJustActivatedType(null);
                pass(game);
                return false;
            }
            if (controllingPlayer.getUserData().isPassPriorityActivation() && getJustActivatedType() == AbilityType.ACTIVATED) {
                setJustActivatedType(null);
                pass(game);
                return false;
            }
        }
        // STOP conditions (temporary stop without skip reset)
        boolean quickStop = false;
        if (isGameUnderControl()) {
            // if was attacked - always stop BEFORE blocker step (to cast extra spells)
            if (game.getTurn().getStepType() == PhaseStep.DECLARE_ATTACKERS && game.getCombat().getPlayerDefenders(game).contains(playerId)) {
                FilterCreatureForCombatBlock filter = filterCreatureForCombatBlock.copy();
                filter.add(new ControllerIdPredicate(playerId));
                // stop skip on any/zero permanents available
                int possibleBlockersCount = game.getBattlefield().count(filter, null, playerId, game);
                boolean canStopOnAny = possibleBlockersCount != 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithAnyPermanents();
                boolean canStopOnZero = possibleBlockersCount == 0 && getControllingPlayersUserData(game).getUserSkipPrioritySteps().isStopOnDeclareBlockersWithZeroPermanents();
                quickStop = canStopOnAny || canStopOnZero;
            }
        }
        // SKIP - use the skip actions only if the player itself controls its turn
        if (!quickStop && isGameUnderControl()) {
            if (passedAllTurns || passedTurnSkipStack) {
                if (passWithManaPoolCheck(game)) {
                    return false;
                }
            }
            if (passedUntilEndStepBeforeMyTurn) {
                if (game.getTurn().getStepType() != PhaseStep.END_TURN) {
                    // other step
                    if (passWithManaPoolCheck(game)) {
                        return false;
                    }
                } else {
                    // end step - search yourself
                    PlayerList playerList = game.getState().getPlayerList(playerId);
                    if (!playerList.getPrevious().equals(game.getActivePlayerId())) {
                        if (passWithManaPoolCheck(game)) {
                            return false;
                        }
                    } else {
                        // stop
                        passedUntilEndStepBeforeMyTurn = false;
                    }
                }
            }
            if (game.getStack().isEmpty()) {
                // empty stack
                boolean dontCheckPassStep = false;
                if (passedUntilStackResolved) {
                    // Don't skip to next step with this action. It always only resolves a stack. If stack is empty it does nothing.
                    passedUntilStackResolved = false;
                    dontCheckPassStep = true;
                }
                if (passedTurn || passedTurnSkipStack) {
                    if (passWithManaPoolCheck(game)) {
                        return false;
                    }
                }
                if (passedUntilNextMain) {
                    if (game.getTurn().getStepType() == PhaseStep.POSTCOMBAT_MAIN || game.getTurn().getStepType() == PhaseStep.PRECOMBAT_MAIN) {
                        // it's main step
                        if (!skippedAtLeastOnce || (!playerId.equals(game.getActivePlayerId()) && !controllingPlayer.getUserData().getUserSkipPrioritySteps().isStopOnAllMainPhases())) {
                            skippedAtLeastOnce = true;
                            if (passWithManaPoolCheck(game)) {
                                return false;
                            }
                        } else {
                            dontCheckPassStep = true;
                            // reset skip action
                            passedUntilNextMain = false;
                        }
                    } else {
                        skippedAtLeastOnce = true;
                        if (passWithManaPoolCheck(game)) {
                            return false;
                        }
                    }
                }
                if (passedUntilEndOfTurn) {
                    if (game.getTurn().getStepType() == PhaseStep.END_TURN) {
                        // it's end of turn step
                        if (!skippedAtLeastOnce || (playerId.equals(game.getActivePlayerId()) && !controllingPlayer.getUserData().getUserSkipPrioritySteps().isStopOnAllEndPhases())) {
                            skippedAtLeastOnce = true;
                            if (passWithManaPoolCheck(game)) {
                                return false;
                            }
                        } else {
                            dontCheckPassStep = true;
                            // reset skip action
                            passedUntilEndOfTurn = false;
                        }
                    } else {
                        skippedAtLeastOnce = true;
                        if (passWithManaPoolCheck(game)) {
                            return false;
                        }
                    }
                }
                if (!dontCheckPassStep && checkPassStep(game, controllingPlayer)) {
                    if (passWithManaPoolCheck(game)) {
                        return false;
                    }
                }
            } else {
                // non empty stack
                boolean haveNewObjectsOnStack = !Objects.equals(dateLastAddedToStack, game.getStack().getDateLastAdded());
                dateLastAddedToStack = game.getStack().getDateLastAdded();
                if (passedUntilStackResolved) {
                    if (haveNewObjectsOnStack && (playerId.equals(game.getActivePlayerId()) && controllingPlayer.getUserData().getUserSkipPrioritySteps().isStopOnStackNewObjects())) {
                        // new objects on stack -- disable "pass until stack resolved"
                        passedUntilStackResolved = false;
                    } else {
                    // no new objects on stack -- go to next priority
                    }
                }
                if (passedUntilStackResolved) {
                    if (passWithManaPoolCheck(game)) {
                        return false;
                    }
                }
            }
        }
        while (canRespond()) {
            holdingPriority = false;
            updateGameStatePriority("priority", game);
            prepareForResponse(game);
            if (!isExecutingMacro()) {
                game.firePriorityEvent(playerId);
            }
            waitForResponse(game);
            if (game.executingRollback()) {
                return true;
            }
            if (response.getBoolean() != null || response.getInteger() != null) {
                if (!activatingMacro && passWithManaPoolCheck(game)) {
                    return false;
                } else {
                    if (activatingMacro) {
                        synchronized (actionQueue) {
                            actionQueue.notifyAll();
                        }
                    }
                    continue;
                }
            }
            break;
        }
        UUID responseId = getFixedResponseUUID(game);
        if (response.getString() != null && response.getString().equals("special")) {
            activateSpecialAction(game, null);
        } else if (responseId != null) {
            boolean result = false;
            MageObject object = game.getObject(responseId);
            if (object != null) {
                Zone zone = game.getState().getZone(object.getId());
                if (zone != null) {
                    // look at card or try to cast/activate abilities
                    LinkedHashMap<UUID, ActivatedAbility> useableAbilities = new LinkedHashMap<>();
                    Player actingPlayer = null;
                    if (playerId.equals(game.getPriorityPlayerId())) {
                        actingPlayer = this;
                    } else if (getPlayersUnderYourControl().contains(game.getPriorityPlayerId())) {
                        actingPlayer = game.getPlayer(game.getPriorityPlayerId());
                    }
                    if (actingPlayer != null) {
                        useableAbilities = actingPlayer.getPlayableActivatedAbilities(object, zone, game);
                        // Enable it on massive broken cards/abilities only or for manual tests
                        if (ALLOW_USERS_TO_PUT_NON_PLAYABLE_SPELLS_ON_STACK_WORKAROUND) {
                            if (object instanceof Card) {
                                for (Ability ability : ((Card) object).getAbilities(game)) {
                                    if (ability instanceof SpellAbility && ((SpellAbility) ability).canActivate(actingPlayer.getId(), game).canActivate() || ability instanceof PlayLandAbility) {
                                        useableAbilities.putIfAbsent(ability.getId(), (ActivatedAbility) ability);
                                    }
                                }
                            }
                        }
                    }
                    if (object instanceof Card && ((Card) object).isFaceDown(game) && lookAtFaceDownCard((Card) object, game, useableAbilities.size())) {
                        result = true;
                    } else {
                        if (!useableAbilities.isEmpty()) {
                            activateAbility(useableAbilities, object, game);
                            result = true;
                        }
                    }
                }
            }
            return result;
        } else {
            return response.getManaType() == null;
        }
        return true;
    }
    return false;
}
Also used : ManaAbility(mage.abilities.mana.ManaAbility) Player(mage.players.Player) PlayerList(mage.players.PlayerList) MageObject(mage.MageObject) TargetCard(mage.target.TargetCard) FilterCreatureForCombatBlock(mage.filter.common.FilterCreatureForCombatBlock) ControllerIdPredicate(mage.filter.predicate.permanent.ControllerIdPredicate)

Aggregations

MageObject (mage.MageObject)2 ManaAbility (mage.abilities.mana.ManaAbility)2 FilterCreatureForCombatBlock (mage.filter.common.FilterCreatureForCombatBlock)2 ControllerIdPredicate (mage.filter.predicate.permanent.ControllerIdPredicate)2 Player (mage.players.Player)2 java.awt (java.awt)1 Serializable (java.io.Serializable)1 java.util (java.util)1 List (java.util.List)1 ConcurrentLinkedQueue (java.util.concurrent.ConcurrentLinkedQueue)1 Collectors (java.util.stream.Collectors)1 mage.abilities (mage.abilities)1 VariableCost (mage.abilities.costs.VariableCost)1 SacrificeSourceCost (mage.abilities.costs.common.SacrificeSourceCost)1 TapSourceCost (mage.abilities.costs.common.TapSourceCost)1 ManaCost (mage.abilities.costs.mana.ManaCost)1 ManaCostsImpl (mage.abilities.costs.mana.ManaCostsImpl)1 RequirementEffect (mage.abilities.effects.RequirementEffect)1 HintUtils (mage.abilities.hint.HintUtils)1 ActivatedManaAbilityImpl (mage.abilities.mana.ActivatedManaAbilityImpl)1