mirror of
https://github.com/correl/mage.git
synced 2024-12-25 03:00:15 +00:00
* Combat blocking - Fixed that blocking of multiple attackers by one creature did not work (e.g. for Guardian of the Gateless).
This commit is contained in:
parent
a079727608
commit
ccd91f0657
4 changed files with 87 additions and 52 deletions
|
@ -70,6 +70,7 @@ import mage.filter.common.FilterCreatureForCombat;
|
||||||
import mage.filter.common.FilterCreatureForCombatBlock;
|
import mage.filter.common.FilterCreatureForCombatBlock;
|
||||||
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
import mage.game.combat.CombatGroup;
|
||||||
import mage.game.draft.Draft;
|
import mage.game.draft.Draft;
|
||||||
import mage.game.match.Match;
|
import mage.game.match.Match;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
@ -99,7 +100,7 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
|
||||||
protected static FilterAttackingCreature filterAttack = new FilterAttackingCreature();
|
protected static FilterAttackingCreature filterAttack = new FilterAttackingCreature();
|
||||||
protected static FilterBlockingCreature filterBlock = new FilterBlockingCreature();
|
protected static FilterBlockingCreature filterBlock = new FilterBlockingCreature();
|
||||||
protected static final Choice replacementEffectChoice = new ChoiceImpl(true);
|
protected static final Choice replacementEffectChoice = new ChoiceImpl(true);
|
||||||
private static final Map<String, Serializable> staticOptions = new HashMap<String, Serializable>();
|
private static final Map<String, Serializable> staticOptions = new HashMap<>();
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(HumanPlayer.class);
|
private static final Logger log = Logger.getLogger(HumanPlayer.class);
|
||||||
|
|
||||||
|
@ -692,10 +693,17 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
|
||||||
} else if (response.getUUID() != null) {
|
} else if (response.getUUID() != null) {
|
||||||
Permanent blocker = game.getPermanent(response.getUUID());
|
Permanent blocker = game.getPermanent(response.getUUID());
|
||||||
if (blocker != null) {
|
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)) {
|
if (filter.match(blocker, null, playerId, game)) {
|
||||||
selectCombatGroup(defendingPlayerId, blocker.getId(), game);
|
selectCombatGroup(defendingPlayerId, blocker.getId(), game);
|
||||||
|
} else {
|
||||||
|
if (filterBlock.match(blocker, null, playerId, game) && game.getStack().isEmpty()) {
|
||||||
|
removeBlocker = true;
|
||||||
}
|
}
|
||||||
else if (filterBlock.match(blocker, null, playerId, game) && game.getStack().isEmpty()) {
|
}
|
||||||
|
|
||||||
|
if (removeBlocker) {
|
||||||
game.getCombat().removeBlocker(blocker.getId(), game);
|
game.getCombat().removeBlocker(blocker.getId(), game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -746,7 +754,15 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
|
||||||
if (response.getBoolean() != null) {
|
if (response.getBoolean() != null) {
|
||||||
// do nothing
|
// do nothing
|
||||||
} else if (response.getUUID() != null) {
|
} else if (response.getUUID() != null) {
|
||||||
|
CombatGroup group = game.getCombat().findGroup(response.getUUID());
|
||||||
|
if (group != null) {
|
||||||
|
// check if already blocked, if not add
|
||||||
|
if (!group.getBlockers().contains(blockerId)) {
|
||||||
declareBlocker(defenderId, blockerId, response.getUUID(), game);
|
declareBlocker(defenderId, blockerId, response.getUUID(), game);
|
||||||
|
} else { // else remove from block
|
||||||
|
game.getCombat().removeBlockerGromGroup(blockerId, group, game);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
package mage.sets.riseoftheeldrazi;
|
package mage.sets.riseoftheeldrazi;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.Rarity;
|
import mage.constants.Rarity;
|
||||||
|
@ -51,9 +52,13 @@ public class VirulentSwipe extends CardImpl<VirulentSwipe> {
|
||||||
this.color.setBlack(true);
|
this.color.setBlack(true);
|
||||||
|
|
||||||
// Target creature gets +2/+0 and gains deathtouch until end of turn.
|
// Target creature gets +2/+0 and gains deathtouch until end of turn.
|
||||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
this.getSpellAbility().addTarget(new TargetCreaturePermanent(true));
|
||||||
this.getSpellAbility().addEffect(new BoostTargetEffect(2, 0, Duration.EndOfTurn));
|
Effect effect = new BoostTargetEffect(2, 0, Duration.EndOfTurn);
|
||||||
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn));
|
effect.setText("Target creature gets +2/+0");
|
||||||
|
this.getSpellAbility().addEffect(effect);
|
||||||
|
effect = new GainAbilityTargetEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn);
|
||||||
|
effect.setText("and gains deathtouch until end of turn");
|
||||||
|
this.getSpellAbility().addEffect(effect);
|
||||||
|
|
||||||
this.addAbility(new ReboundAbility());
|
this.addAbility(new ReboundAbility());
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class CanBlockAdditionalCreatureEffect extends ContinuousEffectImpl<CanBl
|
||||||
/**
|
/**
|
||||||
* Changes the number of creatures source creature can block
|
* Changes the number of creatures source creature can block
|
||||||
*
|
*
|
||||||
* @param amount - 0 = any number, 1-x = n additional blocks
|
* @param amount 0 = any number, 1-x = n additional blocks
|
||||||
*/
|
*/
|
||||||
public CanBlockAdditionalCreatureEffect(int amount) {
|
public CanBlockAdditionalCreatureEffect(int amount) {
|
||||||
this(Duration.WhileOnBattlefield, amount);
|
this(Duration.WhileOnBattlefield, amount);
|
||||||
|
@ -77,17 +77,13 @@ public class CanBlockAdditionalCreatureEffect extends ContinuousEffectImpl<CanBl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
|
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
|
||||||
Permanent perm = game.getPermanent(source.getSourceId());
|
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||||
if (perm != null) {
|
if (permanent != null) {
|
||||||
switch (layer) {
|
|
||||||
case RulesEffects:
|
|
||||||
// maxBlocks = 0 equals to "can block any number of creatures"
|
// maxBlocks = 0 equals to "can block any number of creatures"
|
||||||
if (perm.getMaxBlocks() > 0) {
|
if (amount > 0) {
|
||||||
perm.setMaxBlocks(perm.getMaxBlocks() + amount);
|
permanent.setMaxBlocks(permanent.getMaxBlocks() + amount);
|
||||||
} else {
|
} else {
|
||||||
perm.setMaxBlocks(0);
|
permanent.setMaxBlocks(0);
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -105,11 +101,8 @@ public class CanBlockAdditionalCreatureEffect extends ContinuousEffectImpl<CanBl
|
||||||
case 0:
|
case 0:
|
||||||
sb.append("any number of creatures");
|
sb.append("any number of creatures");
|
||||||
break;
|
break;
|
||||||
case 1:
|
|
||||||
sb.append("an additional creature");
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
sb.append(CardUtil.numberToText(amount)).append(" additional creatures");
|
sb.append(CardUtil.numberToText(amount, "an")).append(" additional creatures");
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,17 +67,17 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
// There are effects that let creatures assigns combat damage equal to its toughness rather than its power
|
// There are effects that let creatures assigns combat damage equal to its toughness rather than its power
|
||||||
private boolean useToughnessForDamage;
|
private boolean useToughnessForDamage;
|
||||||
|
|
||||||
protected List<CombatGroup> groups = new ArrayList<CombatGroup>();
|
protected List<CombatGroup> groups = new ArrayList<>();
|
||||||
protected Map<UUID, CombatGroup> blockingGroups = new HashMap<UUID, CombatGroup>();
|
protected Map<UUID, CombatGroup> blockingGroups = new HashMap<>();
|
||||||
protected Set<UUID> defenders = new HashSet<UUID>();
|
protected Set<UUID> defenders = new HashSet<>();
|
||||||
// how many creatures attack defending player
|
// how many creatures attack defending player
|
||||||
protected Map<UUID, Set<UUID>> numberCreaturesDefenderAttackedBy = new HashMap<UUID, Set<UUID>>();
|
protected Map<UUID, Set<UUID>> numberCreaturesDefenderAttackedBy = new HashMap<>();
|
||||||
protected UUID attackerId; //the player that is attacking
|
protected UUID attackerId; //the player that is attacking
|
||||||
// <creature that can block, <all attackers that force the creature to block it>>
|
// <creature that can block, <all attackers that force the creature to block it>>
|
||||||
protected Map<UUID, Set<UUID>> creatureMustBlockAttackers = new HashMap<UUID, Set<UUID>>();
|
protected Map<UUID, Set<UUID>> creatureMustBlockAttackers = new HashMap<>();
|
||||||
|
|
||||||
// which creature is forced to attack which defender(s). If set is empty, the creature can attack every possible defender
|
// which creature is forced to attack which defender(s). If set is empty, the creature can attack every possible defender
|
||||||
private final Map<UUID, Set<UUID>> creaturesForcedToAttack = new HashMap<UUID, Set<UUID>>();
|
private final Map<UUID, Set<UUID>> creaturesForcedToAttack = new HashMap<>();
|
||||||
private int maxAttackers = Integer.MIN_VALUE;
|
private int maxAttackers = Integer.MIN_VALUE;
|
||||||
|
|
||||||
public Combat() {
|
public Combat() {
|
||||||
|
@ -109,7 +109,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<UUID> getAttackers() {
|
public List<UUID> getAttackers() {
|
||||||
List<UUID> attackers = new ArrayList<UUID>();
|
List<UUID> attackers = new ArrayList<>();
|
||||||
for (CombatGroup group : groups) {
|
for (CombatGroup group : groups) {
|
||||||
attackers.addAll(group.attackers);
|
attackers.addAll(group.attackers);
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<UUID> getBlockers() {
|
public List<UUID> getBlockers() {
|
||||||
List<UUID> blockers = new ArrayList<UUID>();
|
List<UUID> blockers = new ArrayList<>();
|
||||||
for (CombatGroup group : groups) {
|
for (CombatGroup group : groups) {
|
||||||
blockers.addAll(group.blockers);
|
blockers.addAll(group.blockers);
|
||||||
}
|
}
|
||||||
|
@ -214,12 +214,12 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
//20101001 - 508.1d
|
//20101001 - 508.1d
|
||||||
for (Permanent creature : player.getAvailableAttackers(game)) {
|
for (Permanent creature : player.getAvailableAttackers(game)) {
|
||||||
boolean mustAttack = false;
|
boolean mustAttack = false;
|
||||||
Set<UUID> defendersForcedToAttack = new HashSet<UUID>();
|
Set<UUID> defendersForcedToAttack = new HashSet<>();
|
||||||
for (Map.Entry entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, game).entrySet()) {
|
for (Map.Entry<RequirementEffect, HashSet<Ability>> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, game).entrySet()) {
|
||||||
RequirementEffect effect = (RequirementEffect) entry.getKey();
|
RequirementEffect effect = entry.getKey();
|
||||||
if (effect.mustAttack(game)) {
|
if (effect.mustAttack(game)) {
|
||||||
mustAttack = true;
|
mustAttack = true;
|
||||||
for (Ability ability : (HashSet<Ability>) entry.getValue()) {
|
for (Ability ability : entry.getValue()) {
|
||||||
UUID defenderId = effect.mustAttackDefender(ability, game);
|
UUID defenderId = effect.mustAttackDefender(ability, game);
|
||||||
if (defenderId != null) {
|
if (defenderId != null) {
|
||||||
defendersForcedToAttack.add(defenderId);
|
defendersForcedToAttack.add(defenderId);
|
||||||
|
@ -255,7 +255,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
List<UUID> tobeRemoved = new ArrayList<UUID>();
|
List<UUID> tobeRemoved = new ArrayList<>();
|
||||||
for (CombatGroup group : groups) {
|
for (CombatGroup group : groups) {
|
||||||
for (UUID attackingCreatureId : group.getAttackers()) {
|
for (UUID attackingCreatureId : group.getAttackers()) {
|
||||||
Permanent attacker = game.getPermanent(attackingCreatureId);
|
Permanent attacker = game.getPermanent(attackingCreatureId);
|
||||||
|
@ -272,7 +272,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count == 1) {
|
if (count == 1) {
|
||||||
List<UUID> tobeRemoved = new ArrayList<UUID>();
|
List<UUID> tobeRemoved = new ArrayList<>();
|
||||||
for (CombatGroup group : groups) {
|
for (CombatGroup group : groups) {
|
||||||
for (UUID attackingCreatureId : group.getAttackers()) {
|
for (UUID attackingCreatureId : group.getAttackers()) {
|
||||||
Permanent attacker = game.getPermanent(attackingCreatureId);
|
Permanent attacker = game.getPermanent(attackingCreatureId);
|
||||||
|
@ -436,7 +436,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
if (creatureMustBlockAttackers.containsKey(possibleBlocker.getId())) {
|
if (creatureMustBlockAttackers.containsKey(possibleBlocker.getId())) {
|
||||||
creatureMustBlockAttackers.get(possibleBlocker.getId()).add(attackingCreatureId);
|
creatureMustBlockAttackers.get(possibleBlocker.getId()).add(attackingCreatureId);
|
||||||
} else {
|
} else {
|
||||||
Set<UUID> forcingAttackers = new HashSet<UUID>();
|
Set<UUID> forcingAttackers = new HashSet<>();
|
||||||
forcingAttackers.add(attackingCreatureId);
|
forcingAttackers.add(attackingCreatureId);
|
||||||
creatureMustBlockAttackers.put(possibleBlocker.getId(), forcingAttackers);
|
creatureMustBlockAttackers.put(possibleBlocker.getId(), forcingAttackers);
|
||||||
// assign block to the first forcing attacker automatically
|
// assign block to the first forcing attacker automatically
|
||||||
|
@ -479,7 +479,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
Set<UUID> opponents = game.getOpponents(attackerId);
|
Set<UUID> opponents = game.getOpponents(attackerId);
|
||||||
//20101001 - 509.1c
|
//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 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>> mustBeBlockedByAtLeastOne = new HashMap<UUID, Set<UUID>>();
|
Map<UUID, Set<UUID>> mustBeBlockedByAtLeastOne = new HashMap<>();
|
||||||
|
|
||||||
// check mustBlock requirements of creatures from opponents of attacking player
|
// check mustBlock requirements of creatures from opponents of attacking player
|
||||||
for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), player.getId(), game)) {
|
for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), player.getId(), game)) {
|
||||||
|
@ -489,17 +489,17 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
// Creature is already blocking but not forced to do so
|
// Creature is already blocking but not forced to do so
|
||||||
if (creature.getBlocking() > 0) {
|
if (creature.getBlocking() > 0) {
|
||||||
// get all requirement effects that apply to the creature (e.g. is able to block attacker)
|
// get all requirement effects that apply to the creature (e.g. is able to block attacker)
|
||||||
for (Map.Entry entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, game).entrySet()) {
|
for (Map.Entry<RequirementEffect, HashSet<Ability>> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, game).entrySet()) {
|
||||||
RequirementEffect effect = (RequirementEffect) entry.getKey();
|
RequirementEffect effect = entry.getKey();
|
||||||
// get possible mustBeBlockedByAtLeastOne blocker
|
// get possible mustBeBlockedByAtLeastOne blocker
|
||||||
for (Ability ability : (HashSet<Ability>) entry.getValue()) {
|
for (Ability ability : entry.getValue()) {
|
||||||
UUID toBeBlockedCreature = effect.mustBlockAttackerIfElseUnblocked(ability, game);
|
UUID toBeBlockedCreature = effect.mustBlockAttackerIfElseUnblocked(ability, game);
|
||||||
if (toBeBlockedCreature != null) {
|
if (toBeBlockedCreature != null) {
|
||||||
Set<UUID> potentialBlockers;
|
Set<UUID> potentialBlockers;
|
||||||
if (mustBeBlockedByAtLeastOne.containsKey(toBeBlockedCreature)) {
|
if (mustBeBlockedByAtLeastOne.containsKey(toBeBlockedCreature)) {
|
||||||
potentialBlockers = mustBeBlockedByAtLeastOne.get(toBeBlockedCreature);
|
potentialBlockers = mustBeBlockedByAtLeastOne.get(toBeBlockedCreature);
|
||||||
} else {
|
} else {
|
||||||
potentialBlockers = new HashSet<UUID>();
|
potentialBlockers = new HashSet<>();
|
||||||
mustBeBlockedByAtLeastOne.put(toBeBlockedCreature, potentialBlockers);
|
mustBeBlockedByAtLeastOne.put(toBeBlockedCreature, potentialBlockers);
|
||||||
}
|
}
|
||||||
potentialBlockers.add(creature.getId());
|
potentialBlockers.add(creature.getId());
|
||||||
|
@ -511,17 +511,17 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
// Creature is not blocking yet
|
// Creature is not blocking yet
|
||||||
if (creature.getBlocking() == 0) {
|
if (creature.getBlocking() == 0) {
|
||||||
// get all requirement effects that apply to the creature
|
// get all requirement effects that apply to the creature
|
||||||
for (Map.Entry entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, game).entrySet()) {
|
for (Map.Entry<RequirementEffect, HashSet<Ability>> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, game).entrySet()) {
|
||||||
RequirementEffect effect = (RequirementEffect) entry.getKey();
|
RequirementEffect effect = entry.getKey();
|
||||||
// get possible mustBeBlockedByAtLeastOne blocker
|
// get possible mustBeBlockedByAtLeastOne blocker
|
||||||
for (Ability ability : (HashSet<Ability>) entry.getValue()) {
|
for (Ability ability : entry.getValue()) {
|
||||||
UUID toBeBlockedCreature = effect.mustBlockAttackerIfElseUnblocked(ability, game);
|
UUID toBeBlockedCreature = effect.mustBlockAttackerIfElseUnblocked(ability, game);
|
||||||
if (toBeBlockedCreature != null) {
|
if (toBeBlockedCreature != null) {
|
||||||
Set<UUID> potentialBlockers;
|
Set<UUID> potentialBlockers;
|
||||||
if (mustBeBlockedByAtLeastOne.containsKey(toBeBlockedCreature)) {
|
if (mustBeBlockedByAtLeastOne.containsKey(toBeBlockedCreature)) {
|
||||||
potentialBlockers = mustBeBlockedByAtLeastOne.get(toBeBlockedCreature);
|
potentialBlockers = mustBeBlockedByAtLeastOne.get(toBeBlockedCreature);
|
||||||
} else {
|
} else {
|
||||||
potentialBlockers = new HashSet<UUID>();
|
potentialBlockers = new HashSet<>();
|
||||||
mustBeBlockedByAtLeastOne.put(toBeBlockedCreature, potentialBlockers);
|
mustBeBlockedByAtLeastOne.put(toBeBlockedCreature, potentialBlockers);
|
||||||
}
|
}
|
||||||
potentialBlockers.add(creature.getId());
|
potentialBlockers.add(creature.getId());
|
||||||
|
@ -701,9 +701,9 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
for (UUID attackingCreatureId : this.getAttackers()) {
|
for (UUID attackingCreatureId : this.getAttackers()) {
|
||||||
Permanent attackingCreature = game.getPermanent(attackingCreatureId);
|
Permanent attackingCreature = game.getPermanent(attackingCreatureId);
|
||||||
if (attackingCreature != null) {
|
if (attackingCreature != null) {
|
||||||
for (Map.Entry entry : game.getContinuousEffects().getApplicableRestrictionEffects(attackingCreature, game).entrySet()) {
|
for (Map.Entry<RestrictionEffect, HashSet<Ability>> entry : game.getContinuousEffects().getApplicableRestrictionEffects(attackingCreature, game).entrySet()) {
|
||||||
RestrictionEffect effect = (RestrictionEffect) entry.getKey();
|
RestrictionEffect effect = entry.getKey();
|
||||||
for (Ability ability : (HashSet<Ability>) entry.getValue()) {
|
for (Ability ability : entry.getValue()) {
|
||||||
if (!effect.canBeBlockedCheckAfter(attackingCreature, ability, game)) {
|
if (!effect.canBeBlockedCheckAfter(attackingCreature, ability, game)) {
|
||||||
if (controller.isHuman()) {
|
if (controller.isHuman()) {
|
||||||
game.informPlayer(controller, new StringBuilder(attackingCreature.getName()).append(" can't be blocked this way.").toString());
|
game.informPlayer(controller, new StringBuilder(attackingCreature.getName()).append(" can't be blocked this way.").toString());
|
||||||
|
@ -818,7 +818,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
if (numberCreaturesDefenderAttackedBy.containsKey(defendingPlayer.getId())) {
|
if (numberCreaturesDefenderAttackedBy.containsKey(defendingPlayer.getId())) {
|
||||||
defenderAttackedBy = numberCreaturesDefenderAttackedBy.get(defendingPlayer.getId());
|
defenderAttackedBy = numberCreaturesDefenderAttackedBy.get(defendingPlayer.getId());
|
||||||
} else {
|
} else {
|
||||||
defenderAttackedBy = new HashSet<UUID>();
|
defenderAttackedBy = new HashSet<>();
|
||||||
numberCreaturesDefenderAttackedBy.put(defendingPlayer.getId(), defenderAttackedBy);
|
numberCreaturesDefenderAttackedBy.put(defendingPlayer.getId(), defenderAttackedBy);
|
||||||
}
|
}
|
||||||
if (defenderAttackedBy.size() >= defendingPlayer.getMaxAttackedBy()) {
|
if (defenderAttackedBy.size() >= defendingPlayer.getMaxAttackedBy()) {
|
||||||
|
@ -980,7 +980,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<UUID> getPlayerDefenders(Game game) {
|
public Set<UUID> getPlayerDefenders(Game game) {
|
||||||
Set<UUID> playerDefenders = new HashSet<UUID>();
|
Set<UUID> playerDefenders = new HashSet<>();
|
||||||
for (CombatGroup group : groups) {
|
for (CombatGroup group : groups) {
|
||||||
if (group.defenderIsPlaneswalker) {
|
if (group.defenderIsPlaneswalker) {
|
||||||
Permanent permanent = game.getPermanent(group.getDefenderId());
|
Permanent permanent = game.getPermanent(group.getDefenderId());
|
||||||
|
@ -1027,6 +1027,27 @@ public class Combat implements Serializable, Copyable<Combat> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void removeBlockerGromGroup(UUID blockerId, CombatGroup groupToUnblock, Game game) {
|
||||||
|
Permanent creature = game.getPermanent(blockerId);
|
||||||
|
if (creature != null) {
|
||||||
|
for (CombatGroup group : groups) {
|
||||||
|
if (group.equals(groupToUnblock) && group.blockers.contains(blockerId)) {
|
||||||
|
group.blockers.remove(blockerId);
|
||||||
|
group.blockerOrder.remove(blockerId);
|
||||||
|
if (group.blockers.isEmpty()) {
|
||||||
|
group.blocked = false;
|
||||||
|
}
|
||||||
|
if (creature.getBlocking() > 0) {
|
||||||
|
creature.setBlocking(creature.getBlocking() - 1);
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException("Tryinging creature to unblock, but blocking number value of creature < 1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void removeBlocker(UUID blockerId, Game game) {
|
public void removeBlocker(UUID blockerId, Game game) {
|
||||||
for (CombatGroup group : groups) {
|
for (CombatGroup group : groups) {
|
||||||
if (group.blockers.contains(blockerId)) {
|
if (group.blockers.contains(blockerId)) {
|
||||||
|
|
Loading…
Reference in a new issue