mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
Merge branch 'blockfix' into 'master'
AiBlockController: fix for menace + trample See merge request core-developers/forge!5614
This commit is contained in:
@@ -185,7 +185,7 @@ public class AiBlockController {
|
|||||||
List<Card> currentAttackers = new ArrayList<>(attackersLeft);
|
List<Card> currentAttackers = new ArrayList<>(attackersLeft);
|
||||||
|
|
||||||
for (final Card attacker : attackersLeft) {
|
for (final Card attacker : attackersLeft) {
|
||||||
if (StaticAbilityCantAttackBlock.getMinMaxBlocker(attacker, combat.getDefenderPlayerByAttacker(attacker)).getLeft() > 1) {
|
if (CombatUtil.getMinNumBlockersForAttacker(attacker, combat.getDefenderPlayerByAttacker(attacker)) > 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,7 +296,7 @@ public class AiBlockController {
|
|||||||
|
|
||||||
// 6. Blockers that don't survive until the next turn anyway
|
// 6. Blockers that don't survive until the next turn anyway
|
||||||
for (final Card attacker : attackersLeft) {
|
for (final Card attacker : attackersLeft) {
|
||||||
if (StaticAbilityCantAttackBlock.getMinMaxBlocker(attacker, combat.getDefenderPlayerByAttacker(attacker)).getLeft() > 1) {
|
if (CombatUtil.getMinNumBlockersForAttacker(attacker, combat.getDefenderPlayerByAttacker(attacker)) > 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -537,7 +537,7 @@ public class AiBlockController {
|
|||||||
|
|
||||||
// Try to block a Menace attacker with two blockers, neither of which will die
|
// Try to block a Menace attacker with two blockers, neither of which will die
|
||||||
for (final Card attacker : attackersLeft) {
|
for (final Card attacker : attackersLeft) {
|
||||||
if (StaticAbilityCantAttackBlock.getMinMaxBlocker(attacker, combat.getDefenderPlayerByAttacker(attacker)).getLeft() <= 1) {
|
if (CombatUtil.getMinNumBlockersForAttacker(attacker, combat.getDefenderPlayerByAttacker(attacker)) <= 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -593,7 +593,7 @@ public class AiBlockController {
|
|||||||
List<Card> killingBlockers;
|
List<Card> killingBlockers;
|
||||||
|
|
||||||
for (final Card attacker : attackersLeft) {
|
for (final Card attacker : attackersLeft) {
|
||||||
if (StaticAbilityCantAttackBlock.getMinMaxBlocker(attacker, combat.getDefenderPlayerByAttacker(attacker)).getLeft() > 1) {
|
if (CombatUtil.getMinNumBlockersForAttacker(attacker, combat.getDefenderPlayerByAttacker(attacker)) > 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (ComputerUtilCombat.attackerHasThreateningAfflict(attacker, ai)) {
|
if (ComputerUtilCombat.attackerHasThreateningAfflict(attacker, ai)) {
|
||||||
@@ -642,7 +642,7 @@ public class AiBlockController {
|
|||||||
|
|
||||||
Card attacker = attackers.get(0);
|
Card attacker = attackers.get(0);
|
||||||
|
|
||||||
if (StaticAbilityCantAttackBlock.getMinMaxBlocker(attacker, combat.getDefenderPlayerByAttacker(attacker)).getLeft() > 1
|
if (CombatUtil.getMinNumBlockersForAttacker(attacker, combat.getDefenderPlayerByAttacker(attacker)) > 1
|
||||||
|| attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")
|
|| attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")
|
||||||
|| ComputerUtilCombat.attackerHasThreateningAfflict(attacker, ai)) {
|
|| ComputerUtilCombat.attackerHasThreateningAfflict(attacker, ai)) {
|
||||||
attackers.remove(0);
|
attackers.remove(0);
|
||||||
@@ -691,7 +691,7 @@ public class AiBlockController {
|
|||||||
List<Card> currentAttackers = new ArrayList<>(attackersLeft);
|
List<Card> currentAttackers = new ArrayList<>(attackersLeft);
|
||||||
|
|
||||||
for (final Card attacker : currentAttackers) {
|
for (final Card attacker : currentAttackers) {
|
||||||
if (StaticAbilityCantAttackBlock.getMinMaxBlocker(attacker, combat.getDefenderPlayerByAttacker(attacker)).getLeft() <= 1) {
|
if (CombatUtil.getMinNumBlockersForAttacker(attacker, combat.getDefenderPlayerByAttacker(attacker)) <= 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
List<Card> possibleBlockers = getPossibleBlockers(combat, attacker, blockersLeft, true);
|
List<Card> possibleBlockers = getPossibleBlockers(combat, attacker, blockersLeft, true);
|
||||||
@@ -729,8 +729,7 @@ public class AiBlockController {
|
|||||||
// "Whenever CARDNAME becomes blocked, it gets +1/+1 until end of turn for each creature blocking it."
|
// "Whenever CARDNAME becomes blocked, it gets +1/+1 until end of turn for each creature blocking it."
|
||||||
|
|
||||||
for (final Card attacker : tramplingAttackers) {
|
for (final Card attacker : tramplingAttackers) {
|
||||||
|
if (CombatUtil.getMinNumBlockersForAttacker(attacker, combat.getDefenderPlayerByAttacker(attacker)) > combat.getBlockers(attacker).size()
|
||||||
if (((StaticAbilityCantAttackBlock.getMinMaxBlocker(attacker, combat.getDefenderPlayerByAttacker(attacker)).getLeft() > 1) && !combat.isBlocked(attacker))
|
|
||||||
|| attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")
|
|| attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")
|
||||||
|| attacker.hasKeyword("CARDNAME can't be blocked unless all creatures defending player controls block it.")) {
|
|| attacker.hasKeyword("CARDNAME can't be blocked unless all creatures defending player controls block it.")) {
|
||||||
continue;
|
continue;
|
||||||
@@ -829,7 +828,7 @@ public class AiBlockController {
|
|||||||
|
|
||||||
AiController aic = ((PlayerControllerAi) ai.getController()).getAi();
|
AiController aic = ((PlayerControllerAi) ai.getController()).getAi();
|
||||||
final int evalThresholdToken = aic.getIntProperty(AiProps.THRESHOLD_TOKEN_CHUMP_TO_SAVE_PLANESWALKER);
|
final int evalThresholdToken = aic.getIntProperty(AiProps.THRESHOLD_TOKEN_CHUMP_TO_SAVE_PLANESWALKER);
|
||||||
final int evalThresholdNonToken = aic.getIntProperty(AiProps.THRESHOLD_TOKEN_CHUMP_TO_SAVE_PLANESWALKER);
|
final int evalThresholdNonToken = aic.getIntProperty(AiProps.THRESHOLD_NONTOKEN_CHUMP_TO_SAVE_PLANESWALKER);
|
||||||
final boolean onlyIfLethal = aic.getBooleanProperty(AiProps.CHUMP_TO_SAVE_PLANESWALKER_ONLY_ON_LETHAL);
|
final boolean onlyIfLethal = aic.getBooleanProperty(AiProps.CHUMP_TO_SAVE_PLANESWALKER_ONLY_ON_LETHAL);
|
||||||
|
|
||||||
if (evalThresholdToken > 0 || evalThresholdNonToken > 0) {
|
if (evalThresholdToken > 0 || evalThresholdNonToken > 0) {
|
||||||
|
|||||||
@@ -1776,8 +1776,7 @@ public class ComputerUtilCombat {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attacker may kill the blocker before he can deal normal
|
// Attacker may kill the blocker before he can deal normal (secondary) damage
|
||||||
// (secondary) damage
|
|
||||||
if (dealsFirstStrikeDamage(attacker, withoutAbilities, combat)
|
if (dealsFirstStrikeDamage(attacker, withoutAbilities, combat)
|
||||||
&& !blocker.hasKeyword(Keyword.INDESTRUCTIBLE)) {
|
&& !blocker.hasKeyword(Keyword.INDESTRUCTIBLE)) {
|
||||||
if (attackerDamage >= defenderLife) {
|
if (attackerDamage >= defenderLife) {
|
||||||
@@ -1828,7 +1827,7 @@ public class ComputerUtilCombat {
|
|||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean blockerWouldBeDestroyed(Player ai, final Card blocker, Combat combat) {
|
public static boolean blockerWouldBeDestroyed(Player ai, final Card blocker, Combat combat) {
|
||||||
// TODO THis function only checks if a single attacker at a time would destroy a blocker
|
// TODO This function only checks if a single attacker at a time would destroy a blocker
|
||||||
// This needs to expand to tally up damage
|
// This needs to expand to tally up damage
|
||||||
final List<Card> attackers = combat.getAttackersBlockedBy(blocker);
|
final List<Card> attackers = combat.getAttackersBlockedBy(blocker);
|
||||||
|
|
||||||
@@ -2010,8 +2009,7 @@ public class ComputerUtilCombat {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attacker may kill the blocker before he can deal normal
|
// Attacker may kill the blocker before he can deal normal (secondary) damage
|
||||||
// (secondary) damage
|
|
||||||
if (dealsFirstStrikeDamage(blocker, withoutAbilities, combat)
|
if (dealsFirstStrikeDamage(blocker, withoutAbilities, combat)
|
||||||
&& !attacker.hasKeyword(Keyword.INDESTRUCTIBLE)) {
|
&& !attacker.hasKeyword(Keyword.INDESTRUCTIBLE)) {
|
||||||
if (defenderDamage >= attackerLife) {
|
if (defenderDamage >= attackerLife) {
|
||||||
|
|||||||
@@ -413,7 +413,7 @@ public class SpecialCardAi {
|
|||||||
if (!isBlocking && combat.getDefenderByAttacker(source) instanceof Card) {
|
if (!isBlocking && combat.getDefenderByAttacker(source) instanceof Card) {
|
||||||
int loyalty = combat.getDefenderByAttacker(source).getCounters(CounterEnumType.LOYALTY);
|
int loyalty = combat.getDefenderByAttacker(source).getCounters(CounterEnumType.LOYALTY);
|
||||||
int totalDamageToPW = 0;
|
int totalDamageToPW = 0;
|
||||||
for (Card atk : (combat.getAttackersOf(combat.getDefenderByAttacker(source)))) {
|
for (Card atk :combat.getAttackersOf(combat.getDefenderByAttacker(source))) {
|
||||||
if (combat.isUnblocked(atk)) {
|
if (combat.isUnblocked(atk)) {
|
||||||
totalDamageToPW += atk.getNetCombatDamage();
|
totalDamageToPW += atk.getNetCombatDamage();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class PlayAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean checkApiLogic(final Player ai, final SpellAbility sa) {
|
protected boolean checkApiLogic(final Player ai, final SpellAbility sa) {
|
||||||
final String logic = sa.hasParam("AILogic") ? sa.getParam("AILogic") : "";
|
final String logic = sa.getParamOrDefault("AILogic", "");
|
||||||
|
|
||||||
final Game game = ai.getGame();
|
final Game game = ai.getGame();
|
||||||
final Card source = sa.getHostCard();
|
final Card source = sa.getHostCard();
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ public class SacrificeAi extends SpellAbilityAi {
|
|||||||
// Only cast it if Human has the full amount of valid
|
// Only cast it if Human has the full amount of valid
|
||||||
// Only cast it if AI doesn't have the full amount of Valid
|
// Only cast it if AI doesn't have the full amount of Valid
|
||||||
// TODO: Cast if the type is favorable: my "worst" valid is worse than his "worst" valid
|
// TODO: Cast if the type is favorable: my "worst" valid is worse than his "worst" valid
|
||||||
final String num = sa.hasParam("Amount") ? sa.getParam("Amount") : "1";
|
final String num = sa.getParamOrDefault("Amount", "1");
|
||||||
int amount = AbilityUtils.calculateAmount(source, num, sa);
|
int amount = AbilityUtils.calculateAmount(source, num, sa);
|
||||||
|
|
||||||
if (num.equals("X") && sa.getSVar(num).equals("Count$xPaid")) {
|
if (num.equals("X") && sa.getSVar(num).equals("Count$xPaid")) {
|
||||||
|
|||||||
@@ -1482,7 +1482,7 @@ public class AbilityUtils {
|
|||||||
final Card source = sa.getHostCard();
|
final Card source = sa.getHostCard();
|
||||||
|
|
||||||
// The player who has the chance to cancel the ability
|
// The player who has the chance to cancel the ability
|
||||||
final String pays = sa.hasParam("UnlessPayer") ? sa.getParam("UnlessPayer") : "TargetedController";
|
final String pays = sa.getParamOrDefault("UnlessPayer", "TargetedController");
|
||||||
final FCollectionView<Player> allPayers = getDefinedPlayers(sa.getHostCard(), pays, sa);
|
final FCollectionView<Player> allPayers = getDefinedPlayers(sa.getHostCard(), pays, sa);
|
||||||
final String resolveSubs = sa.getParam("UnlessResolveSubs"); // no value means 'Always'
|
final String resolveSubs = sa.getParam("UnlessResolveSubs"); // no value means 'Always'
|
||||||
final boolean execSubsWhenPaid = "WhenPaid".equals(resolveSubs) || StringUtils.isBlank(resolveSubs);
|
final boolean execSubsWhenPaid = "WhenPaid".equals(resolveSubs) || StringUtils.isBlank(resolveSubs);
|
||||||
@@ -1565,7 +1565,7 @@ public class AbilityUtils {
|
|||||||
" ", ""), sa);
|
" ", ""), sa);
|
||||||
//Check for XColor
|
//Check for XColor
|
||||||
ManaCostBeingPaid toPay = new ManaCostBeingPaid(ManaCost.ZERO);
|
ManaCostBeingPaid toPay = new ManaCostBeingPaid(ManaCost.ZERO);
|
||||||
byte xColor = ManaAtom.fromName(sa.hasParam("UnlessXColor") ? sa.getParam("UnlessXColor") : "1");
|
byte xColor = ManaAtom.fromName(sa.getParamOrDefault("UnlessXColor", "1"));
|
||||||
toPay.increaseShard(ManaCostShard.valueOf(xColor), xCost);
|
toPay.increaseShard(ManaCostShard.valueOf(xColor), xCost);
|
||||||
cost = new Cost(toPay.toManaCost(), true);
|
cost = new Cost(toPay.toManaCost(), true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ public abstract class SpellAbilityEffect {
|
|||||||
boolean your = location.startsWith("Your");
|
boolean your = location.startsWith("Your");
|
||||||
boolean combat = location.endsWith("Combat");
|
boolean combat = location.endsWith("Combat");
|
||||||
|
|
||||||
String desc = sa.hasParam("AtEOTDesc") ? sa.getParam("AtEOTDesc") : "";
|
String desc = sa.getParamOrDefault("AtEOTDesc", "");
|
||||||
|
|
||||||
if (your) {
|
if (your) {
|
||||||
location = location.substring("Your".length());
|
location = location.substring("Your".length());
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class BalanceEffect extends SpellAbilityEffect {
|
|||||||
Player activator = sa.getActivatingPlayer();
|
Player activator = sa.getActivatingPlayer();
|
||||||
Card source = sa.getHostCard();
|
Card source = sa.getHostCard();
|
||||||
Game game = activator.getGame();
|
Game game = activator.getGame();
|
||||||
String valid = sa.hasParam("Valid") ? sa.getParam("Valid") : "Card";
|
String valid = sa.getParamOrDefault("Valid", "Card");
|
||||||
ZoneType zone = sa.hasParam("Zone") ? ZoneType.smartValueOf(sa.getParam("Zone")) : ZoneType.Battlefield;
|
ZoneType zone = sa.hasParam("Zone") ? ZoneType.smartValueOf(sa.getParam("Zone")) : ZoneType.Battlefield;
|
||||||
|
|
||||||
int min = Integer.MAX_VALUE;
|
int min = Integer.MAX_VALUE;
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ public class DiscardEffect extends SpellAbilityEffect {
|
|||||||
boolean runDiscard = !sa.hasParam("Optional") || p.getController().confirmAction(sa, PlayerActionConfirmMode.Random, message);
|
boolean runDiscard = !sa.hasParam("Optional") || p.getController().confirmAction(sa, PlayerActionConfirmMode.Random, message);
|
||||||
|
|
||||||
if (runDiscard) {
|
if (runDiscard) {
|
||||||
final String valid = sa.hasParam("DiscardValid") ? sa.getParam("DiscardValid") : "Card";
|
final String valid = sa.getParamOrDefault("DiscardValid", "Card");
|
||||||
List<Card> list = CardLists.getValidCards(p.getCardsIn(ZoneType.Hand), valid, source.getController(), source, sa);
|
List<Card> list = CardLists.getValidCards(p.getCardsIn(ZoneType.Hand), valid, source.getController(), source, sa);
|
||||||
list = CardLists.filter(list, Presets.NON_TOKEN);
|
list = CardLists.filter(list, Presets.NON_TOKEN);
|
||||||
CardCollection toDiscard = new CardCollection();
|
CardCollection toDiscard = new CardCollection();
|
||||||
@@ -250,7 +250,7 @@ public class DiscardEffect extends SpellAbilityEffect {
|
|||||||
dPHand = p.getController().chooseCardsToRevealFromHand(amount, amount, dPHand);
|
dPHand = p.getController().chooseCardsToRevealFromHand(amount, amount, dPHand);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String valid = sa.hasParam("DiscardValid") ? sa.getParam("DiscardValid") : "Card";
|
final String valid = sa.getParamOrDefault("DiscardValid", "Card");
|
||||||
String[] dValid = valid.split(",");
|
String[] dValid = valid.split(",");
|
||||||
CardCollection validCards = CardLists.getValidCards(dPHand, dValid, source.getController(), source, sa);
|
CardCollection validCards = CardLists.getValidCards(dPHand, dValid, source.getController(), source, sa);
|
||||||
|
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ public class FlipCoinEffect extends SpellAbilityEffect {
|
|||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean flipCoinCall(final Player caller, final SpellAbility sa, final int multiplier) {
|
public static boolean flipCoinCall(final Player caller, final SpellAbility sa, final int multiplier) {
|
||||||
String varName = sa.hasParam("SaveNumFlipsToSVar") ? sa.getParam("SaveNumFlipsToSVar") : "X";
|
String varName = sa.getParamOrDefault("SaveNumFlipsToSVar", "X");
|
||||||
return flipCoinCall(caller, sa, multiplier, varName);
|
return flipCoinCall(caller, sa, multiplier, varName);
|
||||||
}
|
}
|
||||||
public static boolean flipCoinCall(final Player caller, final SpellAbility sa, final int multiplier, final String varName) {
|
public static boolean flipCoinCall(final Player caller, final SpellAbility sa, final int multiplier, final String varName) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class MakeCardEffect extends SpellAbilityEffect {
|
|||||||
final Player player = sa.getActivatingPlayer();
|
final Player player = sa.getActivatingPlayer();
|
||||||
final Game game = player.getGame();
|
final Game game = player.getGame();
|
||||||
|
|
||||||
String name = sa.hasParam("Name") ? sa.getParam("Name") : sa.getHostCard().getName();
|
String name = sa.getParamOrDefault("Name", sa.getHostCard().getName());
|
||||||
if (name.equals("ChosenName")) {
|
if (name.equals("ChosenName")) {
|
||||||
name = sa.getHostCard().getChosenName();
|
name = sa.getHostCard().getChosenName();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ public class PumpEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sa.hasParam("RandomKeyword")) {
|
if (sa.hasParam("RandomKeyword")) {
|
||||||
final String num = sa.hasParam("RandomKWNum") ? sa.getParam("RandomKWNum") : "1";
|
final String num = sa.getParamOrDefault("RandomKWNum", "1");
|
||||||
final int numkw = AbilityUtils.calculateAmount(host, num, sa);
|
final int numkw = AbilityUtils.calculateAmount(host, num, sa);
|
||||||
List<String> choice = Lists.newArrayList();
|
List<String> choice = Lists.newArrayList();
|
||||||
List<String> total = Lists.newArrayList(keywords);
|
List<String> total = Lists.newArrayList(keywords);
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class RestartGameEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
ZoneType leaveZone = ZoneType.smartValueOf(sa.hasParam("RestrictFromZone") ? sa.getParam("RestrictFromZone") : null);
|
ZoneType leaveZone = ZoneType.smartValueOf(sa.hasParam("RestrictFromZone") ? sa.getParam("RestrictFromZone") : null);
|
||||||
restartZones.remove(leaveZone);
|
restartZones.remove(leaveZone);
|
||||||
String leaveRestriction = sa.hasParam("RestrictFromValid") ? sa.getParam("RestrictFromValid") : "Card";
|
String leaveRestriction = sa.getParamOrDefault("RestrictFromValid", "Card");
|
||||||
|
|
||||||
//Card.resetUniqueNumber();
|
//Card.resetUniqueNumber();
|
||||||
// need this code here, otherwise observables fail
|
// need this code here, otherwise observables fail
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ public class AttackingBand {
|
|||||||
public void addAttacker(Card card) { attackers.add(card); }
|
public void addAttacker(Card card) { attackers.add(card); }
|
||||||
public void removeAttacker(Card card) { attackers.remove(card); }
|
public void removeAttacker(Card card) { attackers.remove(card); }
|
||||||
|
|
||||||
|
|
||||||
public static boolean isValidBand(List<Card> band, boolean shareDamage) {
|
public static boolean isValidBand(List<Card> band, boolean shareDamage) {
|
||||||
if (band.isEmpty()) {
|
if (band.isEmpty()) {
|
||||||
// An empty band is not a valid band
|
// An empty band is not a valid band
|
||||||
@@ -73,7 +72,6 @@ public class AttackingBand {
|
|||||||
return isValidBand(newBand, false);
|
return isValidBand(newBand, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean contains(Card c) {
|
public boolean contains(Card c) {
|
||||||
return attackers.contains(c);
|
return attackers.contains(c);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -345,13 +345,6 @@ public class Combat {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final CardCollection getBlockers(final Card card) {
|
|
||||||
// If requesting the ordered blocking list pass true, directly.
|
|
||||||
AttackingBand band = getBandOfAttacker(card);
|
|
||||||
Collection<Card> blockers = blockedBands.get(band);
|
|
||||||
return blockers == null ? new CardCollection() : new CardCollection(blockers);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean isBlocked(final Card attacker) {
|
public final boolean isBlocked(final Card attacker) {
|
||||||
AttackingBand band = getBandOfAttacker(attacker);
|
AttackingBand band = getBandOfAttacker(attacker);
|
||||||
return band != null && Boolean.TRUE.equals(band.isBlocked());
|
return band != null && Boolean.TRUE.equals(band.isBlocked());
|
||||||
@@ -408,6 +401,10 @@ public class Combat {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final CardCollection getBlockers(final Card card) {
|
||||||
|
// If requesting the ordered blocking list pass true, directly.
|
||||||
|
return getBlockers(getBandOfAttacker(card));
|
||||||
|
}
|
||||||
public final CardCollection getBlockers(final AttackingBand band) {
|
public final CardCollection getBlockers(final AttackingBand band) {
|
||||||
Collection<Card> blockers = blockedBands.get(band);
|
Collection<Card> blockers = blockedBands.get(band);
|
||||||
return blockers == null ? new CardCollection() : new CardCollection(blockers);
|
return blockers == null ? new CardCollection() : new CardCollection(blockers);
|
||||||
@@ -512,8 +509,7 @@ public class Combat {
|
|||||||
final CardCollection oldBlockers = blockersOrderedForDamageAssignment.get(attacker);
|
final CardCollection oldBlockers = blockersOrderedForDamageAssignment.get(attacker);
|
||||||
if (oldBlockers == null || oldBlockers.isEmpty()) {
|
if (oldBlockers == null || oldBlockers.isEmpty()) {
|
||||||
blockersOrderedForDamageAssignment.put(attacker, new CardCollection(blocker));
|
blockersOrderedForDamageAssignment.put(attacker, new CardCollection(blocker));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
CardCollection orderedBlockers = playerWhoAttacks.getController().orderBlocker(attacker, blocker, oldBlockers);
|
CardCollection orderedBlockers = playerWhoAttacks.getController().orderBlocker(attacker, blocker, oldBlockers);
|
||||||
blockersOrderedForDamageAssignment.put(attacker, orderedBlockers);
|
blockersOrderedForDamageAssignment.put(attacker, orderedBlockers);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -501,7 +501,7 @@ public class CombatUtil {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( combat != null ) {
|
if (combat != null) {
|
||||||
if (StaticAbilityCantAttackBlock.getMinMaxBlocker(attacker, defendingPlayer).getRight() == combat.getBlockers(attacker).size()) {
|
if (StaticAbilityCantAttackBlock.getMinMaxBlocker(attacker, defendingPlayer).getRight() == combat.getBlockers(attacker).size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -763,7 +763,7 @@ public class CombatUtil {
|
|||||||
for (final Card attacker : attackers) {
|
for (final Card attacker : attackers) {
|
||||||
if (canBlock(attacker, blocker, combat)) {
|
if (canBlock(attacker, blocker, combat)) {
|
||||||
boolean must = true;
|
boolean must = true;
|
||||||
if (StaticAbilityCantAttackBlock.getMinMaxBlocker(attacker, defending).getLeft() > 1) {
|
if (getMinNumBlockersForAttacker(attacker, defending) > 1) {
|
||||||
final List<Card> possibleBlockers = Lists.newArrayList(defendersArmy);
|
final List<Card> possibleBlockers = Lists.newArrayList(defendersArmy);
|
||||||
possibleBlockers.remove(blocker);
|
possibleBlockers.remove(blocker);
|
||||||
if (!canBeBlocked(attacker, possibleBlockers, combat)) {
|
if (!canBeBlocked(attacker, possibleBlockers, combat)) {
|
||||||
@@ -875,7 +875,7 @@ public class CombatUtil {
|
|||||||
|
|
||||||
Player defendingPlayer = combat.getDefenderPlayerByAttacker(attacker);
|
Player defendingPlayer = combat.getDefenderPlayerByAttacker(attacker);
|
||||||
|
|
||||||
if (StaticAbilityCantAttackBlock.getMinMaxBlocker(attacker, defendingPlayer).getLeft() > 1) {
|
if (getMinNumBlockersForAttacker(attacker, defendingPlayer) > 1) {
|
||||||
final List<Card> blockers = defendingPlayer.getCreaturesInPlay();
|
final List<Card> blockers = defendingPlayer.getCreaturesInPlay();
|
||||||
blockers.remove(blocker);
|
blockers.remove(blocker);
|
||||||
if (!canBeBlocked(attacker, blockers, combat)) {
|
if (!canBeBlocked(attacker, blockers, combat)) {
|
||||||
@@ -894,7 +894,7 @@ public class CombatUtil {
|
|||||||
&& combat.isAttacking(attacker)) {
|
&& combat.isAttacking(attacker)) {
|
||||||
boolean canBe = true;
|
boolean canBe = true;
|
||||||
Player defendingPlayer = combat.getDefenderPlayerByAttacker(attacker);
|
Player defendingPlayer = combat.getDefenderPlayerByAttacker(attacker);
|
||||||
if (StaticAbilityCantAttackBlock.getMinMaxBlocker(attacker, defendingPlayer).getLeft() > 1) {
|
if (getMinNumBlockersForAttacker(attacker, defendingPlayer) > 1) {
|
||||||
final List<Card> blockers = freeBlockers != null ? new CardCollection(freeBlockers) : defendingPlayer.getCreaturesInPlay();
|
final List<Card> blockers = freeBlockers != null ? new CardCollection(freeBlockers) : defendingPlayer.getCreaturesInPlay();
|
||||||
blockers.remove(blocker);
|
blockers.remove(blocker);
|
||||||
if (!canBeBlocked(attacker, blockers, combat)) {
|
if (!canBeBlocked(attacker, blockers, combat)) {
|
||||||
@@ -1099,4 +1099,4 @@ public class CombatUtil {
|
|||||||
public static int getMinNumBlockersForAttacker(Card attacker, Player defender) {
|
public static int getMinNumBlockersForAttacker(Card attacker, Player defender) {
|
||||||
return StaticAbilityCantAttackBlock.getMinMaxBlocker(attacker, defender).getLeft();
|
return StaticAbilityCantAttackBlock.getMinMaxBlocker(attacker, defender).getLeft();
|
||||||
}
|
}
|
||||||
} // end class CombatUtil
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user