mirror of
https://github.com/correl/mage.git
synced 2024-12-26 03:00:11 +00:00
Fixed undoing individual blocker declarations for multi-blockers
One more #4172 fix
This commit is contained in:
parent
56c615a66f
commit
8f9356533d
1 changed files with 193 additions and 6 deletions
|
@ -678,6 +678,82 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
potentialBlockers.add(creature.getId());
|
||||
}
|
||||
}
|
||||
// check the mustBlockAllAttackers requirement (Blaze of Glory) -------------------------------
|
||||
if (effect.mustBlockAllAttackers(game)) {
|
||||
Set<UUID> attackersToBlock = new HashSet<>();
|
||||
// check that it can block at least one of the attackers
|
||||
// and no restictions prevent this
|
||||
boolean mayBlock = false;
|
||||
for (UUID attackingCreatureId : getAttackers()) {
|
||||
if (creature.canBlock(attackingCreatureId, game)) {
|
||||
Permanent attackingCreature = game.getPermanent(attackingCreatureId);
|
||||
if (attackingCreature != null) {
|
||||
// check if the attacker is already blocked by a max of blockers, so blocker can't block it also
|
||||
if (attackingCreature.getMaxBlockedBy() != 0) { // 0 = no restriction about the number of possible blockers
|
||||
int alreadyBlockingCreatures = 0;
|
||||
for (CombatGroup group : getGroups()) {
|
||||
if (group.getAttackers().contains(attackingCreatureId)) {
|
||||
alreadyBlockingCreatures = group.getBlockers().size();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (attackingCreature.getMaxBlockedBy() <= alreadyBlockingCreatures) {
|
||||
// Attacker can't be blocked by more blockers so check next attacker
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// check restrictions of the creature to block that prevent it can be blocked
|
||||
|
||||
if (attackingCreature.getMinBlockedBy() > 1) {
|
||||
// TODO: check if enough possible blockers are available, if true, mayBlock can be set to true
|
||||
|
||||
} else {
|
||||
attackersToBlock.add(attackingCreatureId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//~ // remove creatures already blocked by affected creature
|
||||
//~ for (CombatGroup group : getBlockingGroups()) {
|
||||
//~ if (group.getAttackers().contains(attackingCreatureId)) {
|
||||
//~ for (UUID attackingCreatureId : group.getAttackers()) {
|
||||
//~ CombatGroup attackersGroup = findGroup(attackingCreatureId);
|
||||
//~ if (attackersGroup != null) {
|
||||
//~ if (attackersGroup.getBlockers().contains(creature.getId())) {
|
||||
//~ attackersToBlock.remove(attackingCreatureId);
|
||||
//~ }
|
||||
//~ }
|
||||
//~ }
|
||||
//~ }
|
||||
//~ }
|
||||
if (!attackersToBlock.isEmpty()) {
|
||||
if (attackersToBlock.size() > creature.getBlocking()) {
|
||||
mayBlock = true;
|
||||
}
|
||||
}
|
||||
// if so inform human player or set block for AI player
|
||||
if (mayBlock) {
|
||||
if (controller.isHuman()) {
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayer(controller, "Creature should block all attackers it's able to this turn: " + creature.getIdName());
|
||||
}
|
||||
} else {
|
||||
Player defender = game.getPlayer(creature.getControllerId());
|
||||
if (defender != null) {
|
||||
for (UUID attackingCreatureId : getAttackers()) {
|
||||
if (creature.canBlock(attackingCreatureId, game)) {
|
||||
// ???
|
||||
if (attackersToBlock.contains(attackingCreatureId)) {
|
||||
//~ defender.declareBlocker(defender.getId(), creature.getId(), attackingCreatureId, game);
|
||||
addBlockingGroup(creature.getId(), creature.getId(), defender.getId(), game);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -701,8 +777,8 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
}
|
||||
}
|
||||
|
||||
// check the mustBlockAny requirement ----------------------------------------
|
||||
if (effect.mustBlockAny(game)) {
|
||||
// check the mustBlockAny requirement ---------------------------------------- (and mustBlockAllAttackers for AI)
|
||||
if (effect.mustBlockAny(game) || effect.mustBlockAllAttackers(game)) {
|
||||
// check that it can block at least one of the attackers
|
||||
// and no restictions prevent this
|
||||
boolean mayBlock = false;
|
||||
|
@ -740,15 +816,28 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
if (mayBlock) {
|
||||
if (controller.isHuman()) {
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayer(controller, "Creature should block this turn: " + creature.getIdName());
|
||||
if (!effect.mustBlockAllAttackers(game)) {
|
||||
game.informPlayer(controller, "Creature should block this turn: " + creature.getIdName());
|
||||
} else {
|
||||
game.informPlayer(controller, "Creature should block all attackers it's able to this turn: " + creature.getIdName());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Player defender = game.getPlayer(creature.getControllerId());
|
||||
if (defender != null) {
|
||||
for (UUID attackingCreatureId : getAttackers()) {
|
||||
if (creature.canBlock(attackingCreatureId, game)) {
|
||||
defender.declareBlocker(defender.getId(), creature.getId(), attackingCreatureId, game);
|
||||
break;
|
||||
if (!effect.mustBlockAllAttackers(game)) {
|
||||
defender.declareBlocker(defender.getId(), creature.getId(), attackingCreatureId, game);
|
||||
break;
|
||||
} else {
|
||||
// this might be buggy with additional restriction effects
|
||||
if (creature.getBlocking() == 0) {
|
||||
defender.declareBlocker(defender.getId(), creature.getId(), attackingCreatureId, game);
|
||||
} else {
|
||||
addBlockingGroup(creature.getId(), creature.getId(), defender.getId(), game);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -756,6 +845,82 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
// check the mustBlockAllAttackers requirement -------------------------------
|
||||
if (effect.mustBlockAllAttackers(game)) {
|
||||
Set<UUID> attackersToBlock = new HashSet<>();
|
||||
// check that it can block at least one of the attackers
|
||||
// and no restictions prevent this
|
||||
boolean mayBlock = false;
|
||||
for (UUID attackingCreatureId : getAttackers()) {
|
||||
if (creature.canBlock(attackingCreatureId, game)) {
|
||||
Permanent attackingCreature = game.getPermanent(attackingCreatureId);
|
||||
if (attackingCreature != null) {
|
||||
// check if the attacker is already blocked by a max of blockers, so blocker can't block it also
|
||||
if (attackingCreature.getMaxBlockedBy() != 0) { // 0 = no restriction about the number of possible blockers
|
||||
int alreadyBlockingCreatures = 0;
|
||||
for (CombatGroup group : getGroups()) {
|
||||
if (group.getAttackers().contains(attackingCreatureId)) {
|
||||
alreadyBlockingCreatures = group.getBlockers().size();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (attackingCreature.getMaxBlockedBy() <= alreadyBlockingCreatures) {
|
||||
// Attacker can't be blocked by more blockers so check next attacker
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// check restrictions of the creature to block that prevent it can be blocked
|
||||
|
||||
if (attackingCreature.getMinBlockedBy() > 1) {
|
||||
// TODO: check if enough possible blockers are available, if true, mayBlock can be set to true
|
||||
|
||||
} else {
|
||||
attackersToBlock.add(attackingCreatureId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!attackersToBlock.isEmpty()) {
|
||||
//~ CombatGroup group = findGroupOfBlocker(creature.getId());
|
||||
//~ if (group == null) {
|
||||
//~ mayBlock = true;
|
||||
//~ } else {
|
||||
//~ for (UUID attackingCreatureId : attackersToBlock) {
|
||||
//~ if (!group.getAttackers().contains(attackingCreatureId)) {
|
||||
//~ mayBlock = true;
|
||||
//~ break;
|
||||
//~ }
|
||||
//~ }
|
||||
game.informPlayers(attackersToBlock.size() + " and " + creature.getBlocking());
|
||||
if (attackersToBlock.size() > creature.getBlocking()) {
|
||||
mayBlock = true;
|
||||
}
|
||||
//~ }
|
||||
}
|
||||
// if so inform human player or set block for AI player
|
||||
if (mayBlock) {
|
||||
if (controller.isHuman()) {
|
||||
if (!game.isSimulation()) {
|
||||
game.informPlayer(controller, "Creature should block all attackers if able this turn: " + creature.getIdName());
|
||||
}
|
||||
} else {
|
||||
Player defender = game.getPlayer(creature.getControllerId());
|
||||
if (defender != null) {
|
||||
for (UUID attackingCreatureId : getAttackers()) {
|
||||
if (creature.canBlock(attackingCreatureId, game)) {
|
||||
// ???
|
||||
if (attackersToBlock.contains(attackingCreatureId)) {
|
||||
defender.declareBlocker(defender.getId(), creature.getId(), attackingCreatureId, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1180,6 +1345,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
//TODO: handle banding
|
||||
blockingGroups.get(blockerId).attackers.add(attackerId);
|
||||
}
|
||||
// "blocker.setBlocking(blocker.getBlocking() + 1)" is handled by the attacking combat group
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1392,6 +1558,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
}
|
||||
|
||||
public void removeBlockerGromGroup(UUID blockerId, CombatGroup groupToUnblock, Game game) {
|
||||
// Manual player action for undoing one declared blocker (used for multi-blocker creatures)
|
||||
Permanent creature = game.getPermanent(blockerId);
|
||||
if (creature != null) {
|
||||
for (CombatGroup group : groups) {
|
||||
|
@ -1404,7 +1571,26 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
if (creature.getBlocking() > 0) {
|
||||
creature.setBlocking(creature.getBlocking() - 1);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Tryinging creature to unblock, but blocking number value of creature < 1");
|
||||
throw new UnsupportedOperationException("Trying to unblock creature, but blocking number value of creature < 1");
|
||||
}
|
||||
boolean canRemove = false;
|
||||
for (CombatGroup blockGroup : getBlockingGroups()) {
|
||||
if (blockGroup.blockers.contains(blockerId)) {
|
||||
for (UUID attackerId : group.getAttackers()) {
|
||||
blockGroup.attackers.remove(attackerId);
|
||||
blockGroup.attackerOrder.remove(attackerId);
|
||||
}
|
||||
if (creature.getBlocking() == 0) {
|
||||
blockGroup.blockers.remove(blockerId);
|
||||
blockGroup.attackerOrder.clear();
|
||||
}
|
||||
}
|
||||
if (blockGroup.blockers.isEmpty()) {
|
||||
canRemove = true;
|
||||
}
|
||||
}
|
||||
if (canRemove) {
|
||||
blockingGroups.remove(blockerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1412,6 +1598,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
}
|
||||
|
||||
public void removeBlocker(UUID blockerId, Game game) {
|
||||
// Manual player action for undoing all declared blockers (used for single-blocker creatures and multi-blockers exceeding blocking limit)
|
||||
for (CombatGroup group : groups) {
|
||||
if (group.blockers.contains(blockerId)) {
|
||||
group.blockers.remove(blockerId);
|
||||
|
|
Loading…
Reference in a new issue