use of mage.target.common.TargetDefender in project mage by magefree.
the class HumanPlayer method selectDefender.
/**
* Selects a defender for an attacker and adds the attacker to combat
*
* @param defenders - list of possible defender
* @param attackerId - UUID of attacker
* @param game
* @return
*/
protected boolean selectDefender(Set<UUID> defenders, UUID attackerId, Game game) {
boolean forcedToAttack = false;
Set<UUID> possibleDefender = game.getCombat().getCreaturesForcedToAttack().get(attackerId);
if (possibleDefender != null) {
forcedToAttack = true;
}
if (possibleDefender == null || possibleDefender.isEmpty()) {
possibleDefender = defenders;
}
if (possibleDefender.size() == 1) {
declareAttacker(attackerId, possibleDefender.iterator().next(), game, true);
return true;
} else {
TargetDefender target = new TargetDefender(possibleDefender, attackerId);
if (forcedToAttack) {
StringBuilder sb = new StringBuilder(target.getTargetName());
Permanent attacker = game.getPermanent(attackerId);
if (attacker != null) {
sb.append(" (").append(attacker.getName()).append(')');
target.setTargetName(sb.toString());
}
}
if (chooseTarget(Outcome.Damage, target, null, game)) {
UUID defenderId = getFixedResponseUUID(game);
declareAttacker(attackerId, defenderId, game, true);
return true;
}
}
return false;
}
use of mage.target.common.TargetDefender in project mage by magefree.
the class PortalMageEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Permanent attackingCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
if (attackingCreature != null) {
CombatGroup combatGroupTarget = null;
for (CombatGroup combatGroup : game.getCombat().getGroups()) {
if (combatGroup.getAttackers().contains(attackingCreature.getId())) {
combatGroupTarget = combatGroup;
break;
}
}
if (combatGroupTarget == null) {
return false;
}
// Reselecting which player or planeswalker a creature is attacking ignores all requirements,
// restrictions, and costs associated with attacking.
// Update possible defender
Set<UUID> defenders = new LinkedHashSet<>();
for (UUID playerId : game.getCombat().getAttackablePlayers(game)) {
defenders.add(playerId);
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_PLANESWALKER, playerId, game)) {
defenders.add(permanent.getId());
}
}
// Select the new defender
TargetDefender target = new TargetDefender(defenders, null);
if (controller.chooseTarget(Outcome.Damage, target, source, game)) {
if (!combatGroupTarget.getDefenderId().equals(target.getFirstTarget())) {
if (combatGroupTarget.changeDefenderPostDeclaration(target.getFirstTarget(), game)) {
String attacked = "";
Player player = game.getPlayer(target.getFirstTarget());
if (player != null) {
attacked = player.getLogName();
} else {
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
attacked = permanent.getLogName();
}
}
game.informPlayers(attackingCreature.getLogName() + " now attacks " + attacked);
return true;
}
}
}
}
return true;
}
return false;
}
use of mage.target.common.TargetDefender in project mage by magefree.
the class Combat method checkAttackRequirements.
protected void checkAttackRequirements(Player player, Game game) {
// 20101001 - 508.1d
for (Permanent creature : player.getAvailableAttackers(game)) {
boolean mustAttack = false;
Set<UUID> defendersForcedToAttack = new HashSet<>();
if (creature.getGoadingPlayers().isEmpty()) {
// check if a creature has to attack
for (Map.Entry<RequirementEffect, Set<Ability>> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, false, game).entrySet()) {
RequirementEffect effect = entry.getKey();
if (!effect.mustAttack(game)) {
continue;
}
mustAttack = true;
for (Ability ability : entry.getValue()) {
UUID defenderId = effect.mustAttackDefender(ability, game);
if (defenderId != null && defenders.contains(defenderId)) {
defendersForcedToAttack.add(defenderId);
}
break;
}
}
} else {
// if creature is goaded then we start with assumption that it needs to attack any player
mustAttack = true;
defendersForcedToAttack.addAll(defenders);
}
if (!mustAttack) {
continue;
}
// check which defenders the forced to attack creature can attack without paying a cost
Set<UUID> defendersCostlessAttackable = new HashSet<>(defenders);
for (UUID defenderId : defenders) {
if (game.getContinuousEffects().checkIfThereArePayCostToAttackBlockEffects(new DeclareAttackerEvent(defenderId, creature.getId(), creature.getControllerId()), game)) {
defendersCostlessAttackable.remove(defenderId);
defendersForcedToAttack.remove(defenderId);
continue;
}
for (Map.Entry<RestrictionEffect, Set<Ability>> entry : game.getContinuousEffects().getApplicableRestrictionEffects(creature, game).entrySet()) {
if (entry.getValue().stream().anyMatch(ability -> entry.getKey().canAttack(creature, defenderId, ability, game, false))) {
continue;
}
defendersCostlessAttackable.remove(defenderId);
defendersForcedToAttack.remove(defenderId);
break;
}
}
// then they attack one of those players, otherwise they attack any player
if (!defendersForcedToAttack.stream().allMatch(creature.getGoadingPlayers()::contains)) {
defendersForcedToAttack.removeAll(creature.getGoadingPlayers());
}
// force attack only if a defender can be attacked without paying a cost
if (defendersCostlessAttackable.isEmpty()) {
continue;
}
creaturesForcedToAttack.put(creature.getId(), defendersForcedToAttack);
// No need to attack a special defender
Set<UUID> defendersToChooseFrom = defendersForcedToAttack.isEmpty() ? defendersCostlessAttackable : defendersForcedToAttack;
if (defendersToChooseFrom.size() == 1) {
player.declareAttacker(creature.getId(), defendersToChooseFrom.iterator().next(), game, false);
continue;
}
TargetDefender target = new TargetDefender(defendersToChooseFrom, creature.getId());
target.setRequired(true);
target.setTargetName("planeswalker or player for " + creature.getLogName() + " to attack (must attack effect)");
if (player.chooseTarget(Outcome.Damage, target, null, game)) {
player.declareAttacker(creature.getId(), target.getFirstTarget(), game, false);
}
}
}
use of mage.target.common.TargetDefender in project mage by magefree.
the class Combat method addAttackingCreature.
public boolean addAttackingCreature(UUID creatureId, Game game, UUID playerToAttack) {
Set<UUID> possibleDefenders;
if (playerToAttack != null) {
possibleDefenders = new HashSet<>();
for (UUID objectId : defenders) {
Permanent planeswalker = game.getPermanent(objectId);
if (planeswalker != null && planeswalker.isControlledBy(playerToAttack)) {
possibleDefenders.add(objectId);
} else if (playerToAttack.equals(objectId)) {
possibleDefenders.add(objectId);
}
}
} else {
possibleDefenders = new HashSet<>(defenders);
}
Player player = game.getPlayer(attackingPlayerId);
if (player == null) {
return false;
}
if (possibleDefenders.size() == 1) {
addAttackerToCombat(creatureId, possibleDefenders.iterator().next(), game);
return true;
} else {
TargetDefender target = new TargetDefender(possibleDefenders, creatureId);
target.setNotTarget(true);
target.setRequired(true);
player.chooseTarget(Outcome.Damage, target, null, game);
if (target.getFirstTarget() != null) {
addAttackerToCombat(creatureId, target.getFirstTarget(), game);
return true;
}
}
return false;
}
Aggregations