mirror of
https://github.com/magefree/mage.git
synced 2025-12-25 04:52:07 -08:00
Fix the combat code to support Slayer's Cleaver
Update the checks for unfulfilled conditions to confirm the blocking creatures actually are fulfilled. Update the check for whether a blocker is already being used correctly to confirm that there isn’t a stricter condition that is unfulfilled. This change also updates the Slayer’s Cleaver test to make it more robust.
This commit is contained in:
parent
6ef1018f6f
commit
87a6d3a1ee
3 changed files with 58 additions and 38 deletions
|
|
@ -749,38 +749,50 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
// check if for attacking creatures with mustBeBlockedByAtLeastOne requirements are fulfilled
|
||||
for (UUID toBeBlockedCreatureId : mustBeBlockedByAtLeastOne.keySet()) {
|
||||
for (CombatGroup combatGroup : game.getCombat().getGroups()) {
|
||||
if (combatGroup.getBlockers().isEmpty() && combatGroup.getAttackers().contains(toBeBlockedCreatureId)) {
|
||||
// creature is not blocked but has possible blockers
|
||||
if (controller.isHuman()) {
|
||||
Permanent toBeBlockedCreature = game.getPermanent(toBeBlockedCreatureId);
|
||||
if (toBeBlockedCreature != null) {
|
||||
// check if all possible blocker block other creatures they are forced to block
|
||||
// read through all possible blockers
|
||||
for (UUID possibleBlockerId : mustBeBlockedByAtLeastOne.get(toBeBlockedCreatureId)) {
|
||||
String blockRequiredMessage = isCreatureDoingARequiredBlock(possibleBlockerId, mustBeBlockedByAtLeastOne, game);
|
||||
if (blockRequiredMessage != null) { // message means not required
|
||||
removeBlocker(possibleBlockerId, game);
|
||||
game.informPlayer(controller, blockRequiredMessage + " Existing block removed. It's a requirement to block " + toBeBlockedCreature.getIdName() + ".");
|
||||
return false;
|
||||
if (combatGroup.getAttackers().contains(toBeBlockedCreatureId)) {
|
||||
boolean requirementFulfilled = false;
|
||||
// Check whether an applicable creature is blocking.
|
||||
for (UUID blockerId : combatGroup.getBlockers()) {
|
||||
if (mustBeBlockedByAtLeastOne.get(toBeBlockedCreatureId).contains(blockerId)) {
|
||||
requirementFulfilled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!requirementFulfilled) {
|
||||
// creature is not blocked but has possible blockers
|
||||
if (controller.isHuman()) {
|
||||
Permanent toBeBlockedCreature = game.getPermanent(toBeBlockedCreatureId);
|
||||
if (toBeBlockedCreature != null) {
|
||||
// check if all possible blocker block other creatures they are forced to block
|
||||
// read through all possible blockers
|
||||
for (UUID possibleBlockerId : mustBeBlockedByAtLeastOne.get(toBeBlockedCreatureId)) {
|
||||
String blockRequiredMessage = isCreatureDoingARequiredBlock(
|
||||
possibleBlockerId, toBeBlockedCreatureId, mustBeBlockedByAtLeastOne, game);
|
||||
if (blockRequiredMessage != null) { // message means not required
|
||||
removeBlocker(possibleBlockerId, game);
|
||||
game.informPlayer(controller, blockRequiredMessage + " Existing block removed. It's a requirement to block " + toBeBlockedCreature.getIdName() + ".");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// take the first potential blocker from the set to block for the AI
|
||||
for (UUID possibleBlockerId : mustBeBlockedByAtLeastOne.get(toBeBlockedCreatureId)) {
|
||||
String blockRequiredMessage = isCreatureDoingARequiredBlock(possibleBlockerId, mustBeBlockedByAtLeastOne, game);
|
||||
if (blockRequiredMessage != null) {
|
||||
// set the block
|
||||
Permanent possibleBlocker = game.getPermanent(possibleBlockerId);
|
||||
Player defender = game.getPlayer(possibleBlocker.getControllerId());
|
||||
if (defender != null) {
|
||||
if (possibleBlocker.getBlocking() > 0) {
|
||||
removeBlocker(possibleBlockerId, game);
|
||||
} else {
|
||||
// take the first potential blocker from the set to block for the AI
|
||||
for (UUID possibleBlockerId : mustBeBlockedByAtLeastOne.get(toBeBlockedCreatureId)) {
|
||||
String blockRequiredMessage = isCreatureDoingARequiredBlock(
|
||||
possibleBlockerId, toBeBlockedCreatureId, mustBeBlockedByAtLeastOne, game);
|
||||
if (blockRequiredMessage != null) {
|
||||
// set the block
|
||||
Permanent possibleBlocker = game.getPermanent(possibleBlockerId);
|
||||
Player defender = game.getPlayer(possibleBlocker.getControllerId());
|
||||
if (defender != null) {
|
||||
if (possibleBlocker.getBlocking() > 0) {
|
||||
removeBlocker(possibleBlockerId, game);
|
||||
}
|
||||
defender.declareBlocker(defender.getId(), possibleBlockerId, toBeBlockedCreatureId, game);
|
||||
}
|
||||
defender.declareBlocker(defender.getId(), possibleBlockerId, toBeBlockedCreatureId, game);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -887,11 +899,12 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
* required block
|
||||
*
|
||||
* @param possibleBlockerId
|
||||
* @param toBeBlockedCreatureId
|
||||
* @param mustBeBlockedByAtLeastOne
|
||||
* @param game
|
||||
* @return null block is required otherwise message with reason why not
|
||||
*/
|
||||
protected String isCreatureDoingARequiredBlock(UUID possibleBlockerId, Map<UUID, Set<UUID>> mustBeBlockedByAtLeastOne, Game game) {
|
||||
protected String isCreatureDoingARequiredBlock(UUID possibleBlockerId, UUID toBeBlockedCreatureId, Map<UUID, Set<UUID>> mustBeBlockedByAtLeastOne, Game game) {
|
||||
Permanent possibleBlocker = game.getPermanent(possibleBlockerId);
|
||||
if (possibleBlocker != null) {
|
||||
if (possibleBlocker.getBlocking() == 0) {
|
||||
|
|
@ -908,9 +921,17 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
if (mustBeBlockedByAtLeastOne.containsKey(blockedAttackerId)) {
|
||||
// blocks a creature that has to be blocked by at least one
|
||||
if (combatGroupOfPossibleBlocker.getBlockers().size() == 1) {
|
||||
// the creature blocks alone already a creature that has to be blocked by at least one,
|
||||
// so this is ok
|
||||
return null;
|
||||
Set <UUID> blockedSet = mustBeBlockedByAtLeastOne.get(blockedAttackerId);
|
||||
Set <UUID> toBlockSet = mustBeBlockedByAtLeastOne.get(toBeBlockedCreatureId);
|
||||
if (toBlockSet == null) {
|
||||
// This should never happen.
|
||||
return null;
|
||||
} else if (toBlockSet.containsAll(blockedSet)) {
|
||||
// the creature already blocks alone a creature that has to be blocked by at least one
|
||||
// and has more possible blockers, so this is ok
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
// TODO: Check if the attacker is already blocked by another creature
|
||||
// and despite there is need that this attacker blocks this attacker also
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue