diff --git a/Mage.Sets/src/mage/sets/gatecrash/AlphaAuthority.java b/Mage.Sets/src/mage/sets/gatecrash/AlphaAuthority.java index ca5cb09effd..2aa4cb6bd08 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/AlphaAuthority.java +++ b/Mage.Sets/src/mage/sets/gatecrash/AlphaAuthority.java @@ -121,7 +121,7 @@ class CantBeBlockedByMoreThanOneAttachedEffect extends ContinuousEffectImpl { if (game.isPaused() || game.isGameOver()) { return; } - checkBlockRestrictions(game.getPlayer(defenderId), game); - choose = !checkBlockRequirementsAfter(defender, defender, game); + choose = !checkBlockRestrictions(game.getPlayer(defenderId), game); + choose |= !checkBlockRequirementsAfter(defender, defender, game); } game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, defenderId, defenderId)); } @@ -266,14 +266,16 @@ public class Combat implements Serializable, Copyable { } } - public void checkBlockRestrictions(Player player, Game game) { + public boolean checkBlockRestrictions(Player player, Game game) { int count = 0; + boolean blockWasLegal = true; for (CombatGroup group: groups) { count += group.getBlockers().size(); } for (CombatGroup group : groups) { - group.checkBlockRestrictions(game, count); + blockWasLegal &= group.checkBlockRestrictions(game, count); } + return blockWasLegal; } public void acceptBlockers(Game game) { diff --git a/Mage/src/mage/game/combat/CombatGroup.java b/Mage/src/mage/game/combat/CombatGroup.java index 84e65e004f6..8f7a0e3bf40 100644 --- a/Mage/src/mage/game/combat/CombatGroup.java +++ b/Mage/src/mage/game/combat/CombatGroup.java @@ -486,15 +486,17 @@ public class CombatGroup implements Serializable, Copyable { } } - public void checkBlockRestrictions(Game game, int blockersCount) { + public boolean checkBlockRestrictions(Game game, int blockersCount) { + boolean blockWasLegal = true; if (attackers.isEmpty()) { - return; + return blockWasLegal; } if (blockersCount == 1) { List toBeRemoved = new ArrayList(); for (UUID blockerId: getBlockers()) { Permanent blocker = game.getPermanent(blockerId); if (blocker != null && blocker.getAbilities().containsKey(CantBlockAloneAbility.getInstance().getId())) { + blockWasLegal = false; game.informPlayers(blocker.getName() + " can't block alone. Removing it from combat."); toBeRemoved.add(blockerId); } @@ -507,8 +509,10 @@ public class CombatGroup implements Serializable, Copyable { this.blocked = false; } } + for (UUID uuid : attackers) { Permanent attacker = game.getPermanent(uuid); + // Check if there are enough blockers to have a legal block if (attacker != null && this.blocked && attacker.getMinBlockedBy() > 1 && blockers.size() > 0 && blockers.size() < attacker.getMinBlockedBy()) { for (UUID blockerId : blockers) { Permanent blocker = game.getPermanent(blockerId); @@ -520,9 +524,28 @@ public class CombatGroup implements Serializable, Copyable { blockerOrder.clear(); this.blocked = false; game.informPlayers(attacker.getName() + " can't be blocked except by " + attacker.getMinBlockedBy() + " or more creatures. Blockers discarded."); - return; + blockWasLegal = false; } + // Check if there are to many blockers (maxBlockedBy = 0 means no restrictions) + if (attacker != null && this.blocked && attacker.getMaxBlockedBy() > 0 && attacker.getMaxBlockedBy() < blockers.size()) { + for (UUID blockerId : blockers) { + Permanent blocker = game.getPermanent(blockerId); + if (blocker != null) { + blocker.setBlocking(blocker.getBlocking() - 1); + } + } + blockers.clear(); + blockerOrder.clear(); + this.blocked = false; + game.informPlayers(new StringBuilder(attacker.getName()) + .append(" can't be blocked by more than ").append(attacker.getMaxBlockedBy()) + .append(attacker.getMaxBlockedBy()==1?" creature.":" creatures.") + .append(" Blockers discarded.").toString()); + blockWasLegal = false; + } + } + return blockWasLegal; } @Override diff --git a/Mage/src/mage/game/permanent/Permanent.java b/Mage/src/mage/game/permanent/Permanent.java index 4bb0081ee9d..a7746714b2c 100644 --- a/Mage/src/mage/game/permanent/Permanent.java +++ b/Mage/src/mage/game/permanent/Permanent.java @@ -137,6 +137,16 @@ public interface Permanent extends Card, Controllable { void setMaxBlocks(int maxBlocks); int getMinBlockedBy(); void setMinBlockedBy(int minBlockedBy); + int getMaxBlockedBy(); + + /** + * Sets the maximum number of blockers the creature can be blocked by. + * Default = 0 which means there is no restriction in the number of blockers. + * + * @param maxBlockedBy maximum number of blockers + */ + void setMaxBlockedBy(int maxBlockedBy); + boolean canAttack(Game game); boolean canBlock(UUID attackerId, Game game); boolean canBlockAny(Game game); diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index 1a4dbf5be4a..608b31c9bea 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -68,8 +68,12 @@ public abstract class PermanentImpl> extends CardImpl protected boolean faceUp = true; protected boolean attacking; protected int blocking; + // number of creatures the permanent can block protected int maxBlocks = 1; + // minimal number of creatures the creature can be blocked by protected int minBlockedBy = 1; + // maximal number of creatures the creature can be blocked by 0 = no restriction + protected int maxBlockedBy = 0; protected boolean loyaltyUsed; protected boolean deathtouched; protected List attachments = new ArrayList(); @@ -124,6 +128,7 @@ public abstract class PermanentImpl> extends CardImpl } this.attachedTo = permanent.attachedTo; this.minBlockedBy = permanent.minBlockedBy; + this.maxBlockedBy = permanent.maxBlockedBy; this.transformed = permanent.transformed; this.pairedCard = permanent.pairedCard; this.copy = permanent.copy; @@ -151,6 +156,7 @@ public abstract class PermanentImpl> extends CardImpl } this.maxBlocks = 1; this.minBlockedBy = 1; + this.maxBlockedBy = 0; this.copy = false; } @@ -434,6 +440,11 @@ public abstract class PermanentImpl> extends CardImpl return minBlockedBy; } + @Override + public int getMaxBlockedBy() { + return maxBlockedBy; + } + @Override public UUID getControllerId() { return this.controllerId; @@ -916,6 +927,12 @@ public abstract class PermanentImpl> extends CardImpl this.minBlockedBy = minBlockedBy; } + + @Override + public void setMaxBlockedBy(int maxBlockedBy) { + this.maxBlockedBy = maxBlockedBy; + } + @Override public boolean removeFromCombat(Game game) { game.getCombat().removeFromCombat(objectId, game);