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);
}
}
}
}
}
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;
}
Aggregations