Fixed Alpha Authority and combat to handle a defined maximum of blockers.

This commit is contained in:
LevelX2 2013-05-29 17:41:30 +02:00
parent 9c18425b46
commit 7bb6fabfef
6 changed files with 62 additions and 10 deletions

View file

@ -121,7 +121,7 @@ class CantBeBlockedByMoreThanOneAttachedEffect extends ContinuousEffectImpl<Cant
if (attachment != null && attachment.getAttachedTo() != null) {
Permanent perm = game.getPermanent(attachment.getAttachedTo());
if (perm != null) {
perm.setMaxBlocks(amount);
perm.setMaxBlockedBy(amount);
return true;
}
}

View file

@ -154,8 +154,8 @@ class OdricMasterTacticianEffect extends ReplacementEffectImpl<OdricMasterTactic
if (game.isPaused() || game.isGameOver()) {
return true;
}
game.getCombat().checkBlockRestrictions(game.getPlayer(defenderId), game);
choose = !game.getCombat().checkBlockRequirementsAfter(game.getPlayer(defenderId), player, game);
choose = game.getCombat().checkBlockRestrictions(game.getPlayer(defenderId), game);
choose |= !game.getCombat().checkBlockRequirementsAfter(game.getPlayer(defenderId), player, game);
}
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, defenderId, defenderId));
}

View file

@ -257,8 +257,8 @@ public class Combat implements Serializable, Copyable<Combat> {
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<Combat> {
}
}
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) {

View file

@ -486,15 +486,17 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
}
}
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<UUID> toBeRemoved = new ArrayList<UUID>();
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<CombatGroup> {
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<CombatGroup> {
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

View file

@ -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);

View file

@ -68,8 +68,12 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> 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<UUID> attachments = new ArrayList<UUID>();
@ -124,6 +128,7 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> 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<T extends PermanentImpl<T>> extends CardImpl
}
this.maxBlocks = 1;
this.minBlockedBy = 1;
this.maxBlockedBy = 0;
this.copy = false;
}
@ -434,6 +440,11 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> 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<T extends PermanentImpl<T>> 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);