mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Merge branch 'attack' into 'master'
Fix War's Toll + Dueling Grounds See merge request core-developers/forge!6036
This commit is contained in:
@@ -97,6 +97,10 @@ public class AttackConstraints {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<Card, AttackRestriction> getRestrictions() {
|
||||||
|
return restrictions;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a set of legal attackers.
|
* Get a set of legal attackers.
|
||||||
*
|
*
|
||||||
@@ -190,7 +194,6 @@ public class AttackConstraints {
|
|||||||
return new FCollection<>
|
return new FCollection<>
|
||||||
(collectLegalAttackers(Collections.emptyMap(), deepClone(reqs), new CardCollection(), maximum));
|
(collectLegalAttackers(Collections.emptyMap(), deepClone(reqs), new CardCollection(), maximum));
|
||||||
}
|
}
|
||||||
|
|
||||||
private final List<Map<Card, GameEntity>> collectLegalAttackers(final Map<Card, GameEntity> attackers, final List<Attack> reqs, final CardCollection reserved, final int maximum) {
|
private final List<Map<Card, GameEntity>> collectLegalAttackers(final Map<Card, GameEntity> attackers, final List<Attack> reqs, final CardCollection reserved, final int maximum) {
|
||||||
final List<Map<Card, GameEntity>> result = Lists.newLinkedList();
|
final List<Map<Card, GameEntity>> result = Lists.newLinkedList();
|
||||||
|
|
||||||
|
|||||||
@@ -184,10 +184,20 @@ public class AttackRequirement {
|
|||||||
// now, count everything else
|
// now, count everything else
|
||||||
violations += defenderSpecific.countAll() - (isAttacking ? defenderSpecific.count(defender) : 0);
|
violations += defenderSpecific.countAll() - (isAttacking ? defenderSpecific.count(defender) : 0);
|
||||||
if (isAttacking) {
|
if (isAttacking) {
|
||||||
for (final Map.Entry<Card, Integer> mustAttack : causesToAttack.entrySet()) {
|
final Combat combat = defender.getGame().getCombat();
|
||||||
// only count violations if the forced creature can actually attack and has no cost incurred for doing so
|
final Map<Card, AttackRestriction> constraints = combat.getAttackConstraints().getRestrictions();
|
||||||
if (CombatUtil.canAttack(mustAttack.getKey()) && !attackers.containsKey(mustAttack.getKey()) && CombatUtil.getAttackCost(defender.getGame(), mustAttack.getKey(), defender) == null) {
|
|
||||||
violations += mustAttack.getValue().intValue();
|
// 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<Card, Integer> 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,11 +37,11 @@ public class GlobalAttackRestrictions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLegal(final Map<Card, GameEntity> attackers, final CardCollection possibleAttackers) {
|
public boolean isLegal(final Map<Card, GameEntity> attackers, final CardCollection possibleAttackers) {
|
||||||
return !getViolations(attackers, possibleAttackers,true).isViolated();
|
return !getViolations(attackers, possibleAttackers, true).isViolated();
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlobalAttackRestrictionViolations getViolations(final Map<Card, GameEntity> attackers, final CardCollection possibleAttackers) {
|
public GlobalAttackRestrictionViolations getViolations(final Map<Card, GameEntity> attackers, final CardCollection possibleAttackers) {
|
||||||
return getViolations(attackers, possibleAttackers,false);
|
return getViolations(attackers, possibleAttackers, false);
|
||||||
}
|
}
|
||||||
private GlobalAttackRestrictionViolations getViolations(final Map<Card, GameEntity> attackers, final CardCollection possibleAttackers, final boolean returnQuickly) {
|
private GlobalAttackRestrictionViolations getViolations(final Map<Card, GameEntity> attackers, final CardCollection possibleAttackers, final boolean returnQuickly) {
|
||||||
final int nTooMany = max < 0 ? 0 : attackers.size() - max;
|
final int nTooMany = max < 0 ? 0 : attackers.size() - max;
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public class VAssignCombatDamage {
|
|||||||
private final int totalDamageToAssign;
|
private final int totalDamageToAssign;
|
||||||
|
|
||||||
private boolean attackerHasDeathtouch = false;
|
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 attackerHasTrample = false;
|
||||||
private boolean attackerHasInfect = false;
|
private boolean attackerHasInfect = false;
|
||||||
private boolean overrideCombatantOrder = false;
|
private boolean overrideCombatantOrder = false;
|
||||||
@@ -183,7 +183,7 @@ public class VAssignCombatDamage {
|
|||||||
// Defenders area
|
// Defenders area
|
||||||
final JPanel pnlDefenders = new JPanel();
|
final JPanel pnlDefenders = new JPanel();
|
||||||
pnlDefenders.setOpaque(false);
|
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;
|
final String wrap = "wrap " + cols;
|
||||||
pnlDefenders.setLayout(new MigLayout("insets 0, gap 0, ax center, " + wrap));
|
pnlDefenders.setLayout(new MigLayout("insets 0, gap 0, ax center, " + wrap));
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ public class VAssignCombatDamage {
|
|||||||
addPanelForDefender(pnlDefenders, c);
|
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());
|
final DamageTarget dt = new DamageTarget(null, new FLabel.Builder().text("0").fontSize(18).fontAlign(SwingConstants.CENTER).build());
|
||||||
damage.put(null, dt);
|
damage.put(null, dt);
|
||||||
defenders.add(dt);
|
defenders.add(dt);
|
||||||
@@ -288,11 +288,9 @@ public class VAssignCombatDamage {
|
|||||||
|
|
||||||
// If trying to assign to the defender, follow the normal assignment rules
|
// If trying to assign to the defender, follow the normal assignment rules
|
||||||
// No need to check for "active" creature assignee when overriding combatant order
|
// No need to check for "active" creature assignee when overriding combatant order
|
||||||
if (!attackerHasDivideDamage) { // Creatures with this can assign to defender
|
if (!attackerHasDivideDamage && (source == null || source == defender || !overrideCombatantOrder) && isAdding &&
|
||||||
if ((source == null || source == defender || !overrideCombatantOrder) && isAdding &&
|
!VAssignCombatDamage.this.canAssignTo(source)) {
|
||||||
!VAssignCombatDamage.this.canAssignTo(source)) {
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If lethal damage has already been assigned just act like it's 0.
|
// If lethal damage has already been assigned just act like it's 0.
|
||||||
|
|||||||
Reference in New Issue
Block a user