mirror of
https://github.com/correl/mage.git
synced 2024-11-15 11:09:30 +00:00
Fixed Gorm requiring a blocker from another player (fixes #5025)
This commit is contained in:
parent
cf97a82c33
commit
45243378cf
1 changed files with 42 additions and 35 deletions
|
@ -1,3 +1,4 @@
|
|||
|
||||
package mage.game.combat;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
@ -694,7 +695,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
Set<UUID> opponents = game.getOpponents(attackingPlayerId);
|
||||
//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<UUID, Set<UUID>> mustBeBlockedByAtLeastOne = new HashMap<>();
|
||||
Map<UUID, Set<UUID>> mustBeBlockedByAtLeastX = new HashMap<>();
|
||||
Map<UUID, Integer> minNumberOfBlockersMap = new HashMap<>();
|
||||
|
||||
// check mustBlock requirements of creatures from opponents of attacking player
|
||||
|
@ -707,19 +708,22 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
// get all requirement effects that apply to the creature (e.g. is able to block attacker)
|
||||
for (Map.Entry<RequirementEffect, Set<Ability>> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, false, game).entrySet()) {
|
||||
RequirementEffect effect = entry.getKey();
|
||||
// get possible mustBeBlockedByAtLeastOne blocker
|
||||
// get possible mustBeBlockedByAtLeastX blocker
|
||||
for (Ability ability : entry.getValue()) {
|
||||
UUID toBeBlockedCreature = effect.mustBlockAttackerIfElseUnblocked(ability, game);
|
||||
if (toBeBlockedCreature != null) {
|
||||
minNumberOfBlockersMap.put(toBeBlockedCreature, effect.getMinNumberOfBlockers());
|
||||
Set<UUID> potentialBlockers;
|
||||
if (mustBeBlockedByAtLeastOne.containsKey(toBeBlockedCreature)) {
|
||||
potentialBlockers = mustBeBlockedByAtLeastOne.get(toBeBlockedCreature);
|
||||
} else {
|
||||
potentialBlockers = new HashSet<>();
|
||||
mustBeBlockedByAtLeastOne.put(toBeBlockedCreature, potentialBlockers);
|
||||
CombatGroup toBeBlockedGroup = findGroup(toBeBlockedCreature);
|
||||
if (toBeBlockedGroup != null && toBeBlockedGroup.getDefendingPlayerId().equals(creature.getControllerId())) {
|
||||
minNumberOfBlockersMap.put(toBeBlockedCreature, effect.getMinNumberOfBlockers());
|
||||
Set<UUID> potentialBlockers;
|
||||
if (mustBeBlockedByAtLeastX.containsKey(toBeBlockedCreature)) {
|
||||
potentialBlockers = mustBeBlockedByAtLeastX.get(toBeBlockedCreature);
|
||||
} else {
|
||||
potentialBlockers = new HashSet<>();
|
||||
mustBeBlockedByAtLeastX.put(toBeBlockedCreature, potentialBlockers);
|
||||
}
|
||||
potentialBlockers.add(creature.getId());
|
||||
}
|
||||
potentialBlockers.add(creature.getId());
|
||||
}
|
||||
}
|
||||
// check the mustBlockAllAttackers requirement for creatures already blocking (Blaze of Glory) -------------------------------
|
||||
|
@ -802,19 +806,22 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
// get all requirement effects that apply to the creature
|
||||
for (Map.Entry<RequirementEffect, Set<Ability>> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, false, game).entrySet()) {
|
||||
RequirementEffect effect = entry.getKey();
|
||||
// get possible mustBeBlockedByAtLeastOne blocker
|
||||
// get possible mustBeBlockedByAtLeastX blocker
|
||||
for (Ability ability : entry.getValue()) {
|
||||
UUID toBeBlockedCreature = effect.mustBlockAttackerIfElseUnblocked(ability, game);
|
||||
if (toBeBlockedCreature != null) {
|
||||
minNumberOfBlockersMap.put(toBeBlockedCreature, effect.getMinNumberOfBlockers());
|
||||
Set<UUID> potentialBlockers;
|
||||
if (mustBeBlockedByAtLeastOne.containsKey(toBeBlockedCreature)) {
|
||||
potentialBlockers = mustBeBlockedByAtLeastOne.get(toBeBlockedCreature);
|
||||
} else {
|
||||
potentialBlockers = new HashSet<>();
|
||||
mustBeBlockedByAtLeastOne.put(toBeBlockedCreature, potentialBlockers);
|
||||
CombatGroup toBeBlockedGroup = findGroup(toBeBlockedCreature);
|
||||
if (toBeBlockedGroup != null && toBeBlockedGroup.getDefendingPlayerId().equals(creature.getControllerId())) {
|
||||
minNumberOfBlockersMap.put(toBeBlockedCreature, effect.getMinNumberOfBlockers());
|
||||
Set<UUID> potentialBlockers;
|
||||
if (mustBeBlockedByAtLeastX.containsKey(toBeBlockedCreature)) {
|
||||
potentialBlockers = mustBeBlockedByAtLeastX.get(toBeBlockedCreature);
|
||||
} else {
|
||||
potentialBlockers = new HashSet<>();
|
||||
mustBeBlockedByAtLeastX.put(toBeBlockedCreature, potentialBlockers);
|
||||
}
|
||||
potentialBlockers.add(creature.getId());
|
||||
}
|
||||
potentialBlockers.add(creature.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -889,19 +896,19 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
|
||||
}
|
||||
|
||||
// check if for attacking creatures with mustBeBlockedByAtLeastOne requirements are fulfilled
|
||||
for (UUID toBeBlockedCreatureId : mustBeBlockedByAtLeastOne.keySet()) {
|
||||
// check if for attacking creatures with mustBeBlockedByAtLeastX requirements are fulfilled
|
||||
for (UUID toBeBlockedCreatureId : mustBeBlockedByAtLeastX.keySet()) {
|
||||
for (CombatGroup combatGroup : game.getCombat().getGroups()) {
|
||||
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)) {
|
||||
if (mustBeBlockedByAtLeastX.get(toBeBlockedCreatureId).contains(blockerId)) {
|
||||
requirementFulfilled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
requirementFulfilled &= (combatGroup.getBlockers().size() >= Math.min(minNumberOfBlockersMap.get(toBeBlockedCreatureId), mustBeBlockedByAtLeastOne.get(toBeBlockedCreatureId).size()));
|
||||
requirementFulfilled &= (combatGroup.getBlockers().size() >= Math.min(minNumberOfBlockersMap.get(toBeBlockedCreatureId), mustBeBlockedByAtLeastX.get(toBeBlockedCreatureId).size()));
|
||||
if (!requirementFulfilled) {
|
||||
// creature is not blocked but has possible blockers
|
||||
if (controller.isHuman()) {
|
||||
|
@ -909,12 +916,12 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
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)) {
|
||||
for (UUID possibleBlockerId : mustBeBlockedByAtLeastX.get(toBeBlockedCreatureId)) {
|
||||
if (combatGroup.getBlockers().contains(possibleBlockerId)) {
|
||||
continue;
|
||||
}
|
||||
String blockRequiredMessage = isCreatureDoingARequiredBlock(
|
||||
possibleBlockerId, toBeBlockedCreatureId, mustBeBlockedByAtLeastOne, game);
|
||||
possibleBlockerId, toBeBlockedCreatureId, mustBeBlockedByAtLeastX, 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() + '.');
|
||||
|
@ -925,9 +932,9 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
|
||||
} else {
|
||||
// take the first potential blocker from the set to block for the AI
|
||||
for (UUID possibleBlockerId : mustBeBlockedByAtLeastOne.get(toBeBlockedCreatureId)) {
|
||||
for (UUID possibleBlockerId : mustBeBlockedByAtLeastX.get(toBeBlockedCreatureId)) {
|
||||
String blockRequiredMessage = isCreatureDoingARequiredBlock(
|
||||
possibleBlockerId, toBeBlockedCreatureId, mustBeBlockedByAtLeastOne, game);
|
||||
possibleBlockerId, toBeBlockedCreatureId, mustBeBlockedByAtLeastX, game);
|
||||
if (blockRequiredMessage != null) {
|
||||
// set the block
|
||||
Permanent possibleBlocker = game.getPermanent(possibleBlockerId);
|
||||
|
@ -1008,8 +1015,8 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
} else // check if the blocker blocks a attacker that must be blocked at least by one and is the only blocker, this block is also valid
|
||||
{
|
||||
if (combatGroup.getBlockers().size() == 1) {
|
||||
if (mustBeBlockedByAtLeastOne.containsKey(forcingAttackerId)) {
|
||||
if (mustBeBlockedByAtLeastOne.get(forcingAttackerId).contains(creatureForcedToBlock.getId())) {
|
||||
if (mustBeBlockedByAtLeastX.containsKey(forcingAttackerId)) {
|
||||
if (mustBeBlockedByAtLeastX.get(forcingAttackerId).contains(creatureForcedToBlock.getId())) {
|
||||
blockIsValid = true;
|
||||
break CombatGroups;
|
||||
}
|
||||
|
@ -1042,11 +1049,11 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
*
|
||||
* @param possibleBlockerId
|
||||
* @param toBeBlockedCreatureId
|
||||
* @param mustBeBlockedByAtLeastOne
|
||||
* @param mustBeBlockedByAtLeastX
|
||||
* @param game
|
||||
* @return null block is required otherwise message with reason why not
|
||||
*/
|
||||
protected String isCreatureDoingARequiredBlock(UUID possibleBlockerId, UUID toBeBlockedCreatureId, Map<UUID, Set<UUID>> mustBeBlockedByAtLeastOne, Game game) {
|
||||
protected String isCreatureDoingARequiredBlock(UUID possibleBlockerId, UUID toBeBlockedCreatureId, Map<UUID, Set<UUID>> mustBeBlockedByAtLeastX, Game game) {
|
||||
Permanent possibleBlocker = game.getPermanent(possibleBlockerId);
|
||||
if (possibleBlocker != null) {
|
||||
if (possibleBlocker.getBlocking() == 0) {
|
||||
|
@ -1055,16 +1062,16 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
Set<UUID> forcingAttackers = creatureMustBlockAttackers.get(possibleBlockerId);
|
||||
if (forcingAttackers == null) {
|
||||
// no other creature forces the blocker to block -> it's available
|
||||
// check now, if it already blocks a creature that mustBeBlockedByAtLeastOne
|
||||
// check now, if it already blocks a creature that mustBeBlockedByAtLeastX
|
||||
if (possibleBlocker.getBlocking() > 0) {
|
||||
CombatGroup combatGroupOfPossibleBlocker = findGroupOfBlocker(possibleBlockerId);
|
||||
if (combatGroupOfPossibleBlocker != null) {
|
||||
for (UUID blockedAttackerId : combatGroupOfPossibleBlocker.getAttackers()) {
|
||||
if (mustBeBlockedByAtLeastOne.containsKey(blockedAttackerId)) {
|
||||
if (mustBeBlockedByAtLeastX.containsKey(blockedAttackerId)) {
|
||||
// blocks a creature that has to be blocked by at least one
|
||||
if (combatGroupOfPossibleBlocker.getBlockers().size() == 1) {
|
||||
Set<UUID> blockedSet = mustBeBlockedByAtLeastOne.get(blockedAttackerId);
|
||||
Set<UUID> toBlockSet = mustBeBlockedByAtLeastOne.get(toBeBlockedCreatureId);
|
||||
Set<UUID> blockedSet = mustBeBlockedByAtLeastX.get(blockedAttackerId);
|
||||
Set<UUID> toBlockSet = mustBeBlockedByAtLeastX.get(toBeBlockedCreatureId);
|
||||
if (toBlockSet == null) {
|
||||
// This should never happen.
|
||||
return null;
|
||||
|
|
Loading…
Reference in a new issue