From 151742f4fd2535ef937409386ab35ade2caeed8a Mon Sep 17 00:00:00 2001 From: Bug Hunter Date: Wed, 12 Jan 2022 05:05:24 +0000 Subject: [PATCH] Fix War's Toll + Dueling Grounds --- .../forge/game/combat/AttackConstraints.java | 5 ++++- .../forge/game/combat/AttackRequirement.java | 18 ++++++++++++++---- .../game/combat/GlobalAttackRestrictions.java | 4 ++-- .../screens/match/VAssignCombatDamage.java | 14 ++++++-------- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/forge-game/src/main/java/forge/game/combat/AttackConstraints.java b/forge-game/src/main/java/forge/game/combat/AttackConstraints.java index 2c1d89da64e..56433fbf4d0 100644 --- a/forge-game/src/main/java/forge/game/combat/AttackConstraints.java +++ b/forge-game/src/main/java/forge/game/combat/AttackConstraints.java @@ -97,6 +97,10 @@ public class AttackConstraints { } } + public Map getRestrictions() { + return restrictions; + } + /** * Get a set of legal attackers. * @@ -190,7 +194,6 @@ public class AttackConstraints { return new FCollection<> (collectLegalAttackers(Collections.emptyMap(), deepClone(reqs), new CardCollection(), maximum)); } - private final List> collectLegalAttackers(final Map attackers, final List reqs, final CardCollection reserved, final int maximum) { final List> result = Lists.newLinkedList(); diff --git a/forge-game/src/main/java/forge/game/combat/AttackRequirement.java b/forge-game/src/main/java/forge/game/combat/AttackRequirement.java index d0f176a4a3e..6da720bdc43 100644 --- a/forge-game/src/main/java/forge/game/combat/AttackRequirement.java +++ b/forge-game/src/main/java/forge/game/combat/AttackRequirement.java @@ -184,10 +184,20 @@ public class AttackRequirement { // now, count everything else violations += defenderSpecific.countAll() - (isAttacking ? defenderSpecific.count(defender) : 0); if (isAttacking) { - for (final Map.Entry mustAttack : causesToAttack.entrySet()) { - // only count violations if the forced creature can actually attack and has no cost incurred for doing so - if (CombatUtil.canAttack(mustAttack.getKey()) && !attackers.containsKey(mustAttack.getKey()) && CombatUtil.getAttackCost(defender.getGame(), mustAttack.getKey(), defender) == null) { - violations += mustAttack.getValue().intValue(); + final Combat combat = defender.getGame().getCombat(); + final Map constraints = combat.getAttackConstraints().getRestrictions(); + + // check if a restriction will apply such that the requirement is no longer relevant + if (attackers.size() != 1 || !constraints.get(attackers.entrySet().iterator().next().getKey()).getTypes().contains(AttackRestrictionType.ONLY_ALONE)) { + for (final Map.Entry mustAttack : causesToAttack.entrySet()) { + if (constraints.get(mustAttack.getKey()).getTypes().contains(AttackRestrictionType.ONLY_ALONE)) continue; + int max = GlobalAttackRestrictions.getGlobalRestrictions(mustAttack.getKey().getController(), combat.getDefenders()).getMax(); + if (max == -1) max = Integer.MAX_VALUE; + + // only count violations if the forced creature can actually attack and has no cost incurred for doing so + if (attackers.size() < max && !attackers.containsKey(mustAttack.getKey()) && CombatUtil.canAttack(mustAttack.getKey()) && CombatUtil.getAttackCost(defender.getGame(), mustAttack.getKey(), defender) == null) { + violations += mustAttack.getValue().intValue(); + } } } } diff --git a/forge-game/src/main/java/forge/game/combat/GlobalAttackRestrictions.java b/forge-game/src/main/java/forge/game/combat/GlobalAttackRestrictions.java index 20d06279ce1..46e24fbfe70 100644 --- a/forge-game/src/main/java/forge/game/combat/GlobalAttackRestrictions.java +++ b/forge-game/src/main/java/forge/game/combat/GlobalAttackRestrictions.java @@ -37,11 +37,11 @@ public class GlobalAttackRestrictions { } public boolean isLegal(final Map attackers, final CardCollection possibleAttackers) { - return !getViolations(attackers, possibleAttackers,true).isViolated(); + return !getViolations(attackers, possibleAttackers, true).isViolated(); } public GlobalAttackRestrictionViolations getViolations(final Map attackers, final CardCollection possibleAttackers) { - return getViolations(attackers, possibleAttackers,false); + return getViolations(attackers, possibleAttackers, false); } private GlobalAttackRestrictionViolations getViolations(final Map attackers, final CardCollection possibleAttackers, final boolean returnQuickly) { final int nTooMany = max < 0 ? 0 : attackers.size() - max; diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/VAssignCombatDamage.java b/forge-gui-desktop/src/main/java/forge/screens/match/VAssignCombatDamage.java index 9fe31a827fa..3aa57942e4f 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/VAssignCombatDamage.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/VAssignCombatDamage.java @@ -75,7 +75,7 @@ public class VAssignCombatDamage { private final int totalDamageToAssign; private boolean attackerHasDeathtouch = false; - private boolean attackerHasDivideDamage = false; + private boolean attackerHasDivideDamage = false; // Creatures with this can assign to defender private boolean attackerHasTrample = false; private boolean attackerHasInfect = false; private boolean overrideCombatantOrder = false; @@ -183,7 +183,7 @@ public class VAssignCombatDamage { // Defenders area final JPanel pnlDefenders = new JPanel(); pnlDefenders.setOpaque(false); - int cols = ((attackerHasTrample) || (attackerHasDivideDamage && overrideCombatantOrder)) ? blockers.size() + 1 : blockers.size(); + int cols = attackerHasTrample || (attackerHasDivideDamage && overrideCombatantOrder) ? blockers.size() + 1 : blockers.size(); final String wrap = "wrap " + cols; pnlDefenders.setLayout(new MigLayout("insets 0, gap 0, ax center, " + wrap)); @@ -197,7 +197,7 @@ public class VAssignCombatDamage { addPanelForDefender(pnlDefenders, c); } - if ((attackerHasTrample) || (attackerHasDivideDamage && overrideCombatantOrder)) { + if (attackerHasTrample || (attackerHasDivideDamage && overrideCombatantOrder)) { final DamageTarget dt = new DamageTarget(null, new FLabel.Builder().text("0").fontSize(18).fontAlign(SwingConstants.CENTER).build()); damage.put(null, dt); defenders.add(dt); @@ -288,11 +288,9 @@ public class VAssignCombatDamage { // If trying to assign to the defender, follow the normal assignment rules // No need to check for "active" creature assignee when overriding combatant order - if (!attackerHasDivideDamage) { // Creatures with this can assign to defender - if ((source == null || source == defender || !overrideCombatantOrder) && isAdding && - !VAssignCombatDamage.this.canAssignTo(source)) { - return; - } + if (!attackerHasDivideDamage && (source == null || source == defender || !overrideCombatantOrder) && isAdding && + !VAssignCombatDamage.this.canAssignTo(source)) { + return; } // If lethal damage has already been assigned just act like it's 0.