- Fix Crawlspace in multiplayer

- Move a method using getOpponent() to AI (only place it's used, to group the methods using this deprecated function in the AI code)
This commit is contained in:
elcnesh
2014-07-29 22:22:14 +00:00
parent ed496dbc10
commit ecc4620dda
7 changed files with 54 additions and 41 deletions

View File

@@ -394,7 +394,7 @@ public class AiAttackController {
}
for (Card attacker : oppList) {
if (!CombatUtil.canAttackNextTurn(attacker)) {
if (!ComputerUtil.canAttackNextTurn(attacker)) {
continue;
}
if (blockersLeft > 0 && CombatUtil.canBeBlocked(attacker, ai)) {
@@ -657,7 +657,7 @@ public class AiAttackController {
for (final Card pCard : this.oppList) {
// if the creature can attack next turn add it to counter attackers
// list
if (CombatUtil.canAttackNextTurn(pCard)) {
if (ComputerUtil.canAttackNextTurn(pCard)) {
nextTurnAttackers.add(pCard);
if (pCard.getNetCombatDamage() > 0) {
candidateCounterAttackDamage += pCard.getNetCombatDamage();
@@ -684,7 +684,7 @@ public class AiAttackController {
for (final Card pCard : this.myList) {
// if the creature can attack then it's a potential attacker this
// turn, assume summoning sickness creatures will be able to
if (CombatUtil.canAttackNextTurn(pCard)) {
if (ComputerUtil.canAttackNextTurn(pCard)) {
candidateAttackers.add(pCard);
if (pCard.getNetCombatDamage() > 0) {
candidateUnblockedDamage += ComputerUtilCombat.damageIfUnblocked(pCard, opp, null);

View File

@@ -879,7 +879,7 @@ public class ComputerUtil {
playNow = false;
break;
}
if (!playNow && c.isCreature() && CombatUtil.canAttackNextTurn(c) && c.canBeEquippedBy(card)) {
if (!playNow && c.isCreature() && ComputerUtil.canAttackNextTurn(c) && c.canBeEquippedBy(card)) {
playNow = true;
}
}
@@ -1981,4 +1981,17 @@ public class ComputerUtil {
return bestBoardPosition;
}
/**
* <p>
* canAttackNextTurn.
* </p>
*
* @param c
* a {@link forge.game.card.Card} object.
* @return a boolean.
*/
public static boolean canAttackNextTurn(final Card c) {
return CombatUtil.canAttackNextTurn(c, c.getController().getOpponent());
}
}

View File

@@ -616,7 +616,7 @@ public class AttachAi extends SpellAbilityAi {
prefList = CardLists.filter(prefList, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return CombatUtil.canAttackNextTurn(c) && c.getNetAttack() > 0;
return ComputerUtil.canAttackNextTurn(c) && c.getNetAttack() > 0;
}
});
}
@@ -945,7 +945,7 @@ public class AttachAi extends SpellAbilityAi {
if (!c.isCreature()) {
return true;
}
return CombatUtil.canAttackNextTurn(c) && powerBonus + c.getNetAttack() > 0;
return ComputerUtil.canAttackNextTurn(c) && powerBonus + c.getNetAttack() > 0;
}
});
}
@@ -1133,7 +1133,7 @@ public class AttachAi extends SpellAbilityAi {
// give evasive keywords to creatures that can attack and deal damage
if (evasive) {
if (card.getNetCombatDamage() + powerBonus <= 0
|| !CombatUtil.canAttackNextTurn(card)
|| !ComputerUtil.canAttackNextTurn(card)
|| !CombatUtil.canBeBlocked(card, opponent)) {
return false;
}
@@ -1142,20 +1142,20 @@ public class AttachAi extends SpellAbilityAi {
|| card.getNetCombatDamage() + powerBonus <= 0
|| card.hasKeyword("CARDNAME can attack as though it had haste.")
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| !CombatUtil.canAttackNextTurn(card)) {
|| !ComputerUtil.canAttackNextTurn(card)) {
return false;
}
} else if (keyword.endsWith("Indestructible")) {
return true;
} else if (keyword.endsWith("Deathtouch") || keyword.endsWith("Wither")) {
if (card.getNetCombatDamage() + powerBonus <= 0
|| ((!CombatUtil.canBeBlocked(card, opponent) || !CombatUtil.canAttackNextTurn(card))
|| ((!CombatUtil.canBeBlocked(card, opponent) || !ComputerUtil.canAttackNextTurn(card))
&& !CombatUtil.canBlock(card, true))) {
return false;
}
} else if (keyword.equals("Double Strike") || keyword.equals("Lifelink")) {
if (card.getNetCombatDamage() + powerBonus <= 0
|| (!CombatUtil.canAttackNextTurn(card) && !CombatUtil.canBlock(card, true))) {
|| (!ComputerUtil.canAttackNextTurn(card) && !CombatUtil.canBlock(card, true))) {
return false;
}
} else if (keyword.equals("First Strike")) {
@@ -1164,29 +1164,29 @@ public class AttachAi extends SpellAbilityAi {
}
} else if (keyword.startsWith("Flanking")) {
if (card.getNetCombatDamage() + powerBonus <= 0
|| !CombatUtil.canAttackNextTurn(card)
|| !ComputerUtil.canAttackNextTurn(card)
|| !CombatUtil.canBeBlocked(card, opponent)) {
return false;
}
} else if (keyword.startsWith("Bushido")) {
if ((!CombatUtil.canBeBlocked(card, opponent) || !CombatUtil.canAttackNextTurn(card))
if ((!CombatUtil.canBeBlocked(card, opponent) || !ComputerUtil.canAttackNextTurn(card))
&& !CombatUtil.canBlock(card, true)) {
return false;
}
} else if (keyword.equals("Trample")) {
if (card.getNetCombatDamage() + powerBonus <= 1
|| !CombatUtil.canBeBlocked(card, opponent)
|| !CombatUtil.canAttackNextTurn(card)) {
|| !ComputerUtil.canAttackNextTurn(card)) {
return false;
}
} else if (keyword.equals("Infect")) {
if (card.getNetCombatDamage() + powerBonus <= 0
|| !CombatUtil.canAttackNextTurn(card)) {
|| !ComputerUtil.canAttackNextTurn(card)) {
return false;
}
} else if (keyword.equals("Vigilance")) {
if (card.getNetCombatDamage() + powerBonus <= 0
|| !CombatUtil.canAttackNextTurn(card)
|| !ComputerUtil.canAttackNextTurn(card)
|| !CombatUtil.canBlock(card, true)) {
return false;
}
@@ -1231,11 +1231,11 @@ public class AttachAi extends SpellAbilityAi {
if (keyword.endsWith("CARDNAME can't attack.") || keyword.equals("Defender")
|| keyword.endsWith("CARDNAME can't attack or block.")) {
if (!CombatUtil.canAttackNextTurn(card) || card.getNetCombatDamage() < 1) {
if (!ComputerUtil.canAttackNextTurn(card) || card.getNetCombatDamage() < 1) {
return false;
}
} else if (keyword.endsWith("CARDNAME attacks each turn if able.") || keyword.endsWith("CARDNAME attacks each combat if able.")) {
if (!CombatUtil.canAttackNextTurn(card) || !CombatUtil.canBlock(card, true) || ai.getCreaturesInPlay().isEmpty()) {
if (!ComputerUtil.canAttackNextTurn(card) || !CombatUtil.canBlock(card, true) || ai.getCreaturesInPlay().isEmpty()) {
return false;
}
} else if (keyword.endsWith("CARDNAME can't block.") || keyword.contains("CantBlock")) {
@@ -1250,12 +1250,12 @@ public class AttachAi extends SpellAbilityAi {
}
return false;
} else if (keyword.endsWith("Prevent all combat damage that would be dealt by CARDNAME.")) {
if (!CombatUtil.canAttackNextTurn(card) || card.getNetCombatDamage() < 1) {
if (!ComputerUtil.canAttackNextTurn(card) || card.getNetCombatDamage() < 1) {
return false;
}
} else if (keyword.endsWith("Prevent all combat damage that would be dealt to and dealt by CARDNAME.")
|| keyword.endsWith("Prevent all damage that would be dealt to and dealt by CARDNAME.")) {
if (!CombatUtil.canAttackNextTurn(card) || card.getNetCombatDamage() < 2) {
if (!ComputerUtil.canAttackNextTurn(card) || card.getNetCombatDamage() < 2) {
return false;
}
} else if (keyword.endsWith("CARDNAME doesn't untap during your untap step.")) {

View File

@@ -18,6 +18,8 @@
package forge.ai.ability;
import com.google.common.base.Predicate;
import forge.ai.ComputerUtil;
import forge.ai.ComputerUtilCard;
import forge.ai.SpellAbilityAi;
import forge.game.card.Card;
@@ -78,7 +80,7 @@ public final class EncodeAi extends SpellAbilityAi {
final List<Card> attackers = CardLists.filter(options, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return CombatUtil.canAttackNextTurn(c);
return ComputerUtil.canAttackNextTurn(c);
}
});
final List<Card> unblockables = CardLists.filter(attackers, new Predicate<Card>() {

View File

@@ -235,7 +235,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|| newPower <= 0
|| card.hasKeyword("CARDNAME can attack as though it had haste.")
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| !CombatUtil.canAttackNextTurn(card)) {
|| !ComputerUtil.canAttackNextTurn(card)) {
return false;
}
} else if (keyword.endsWith("Indestructible")) {

View File

@@ -2,6 +2,8 @@ package forge.ai.ability;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import forge.ai.ComputerUtil;
import forge.ai.SpellAbilityAi;
import forge.game.Game;
import forge.game.card.Card;
@@ -83,7 +85,7 @@ public class TapAllAi extends SpellAbilityAi {
final boolean any = Iterables.any(validTappables, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return CombatUtil.canAttack(c) && CombatUtil.canAttackNextTurn(c);
return CombatUtil.canAttack(c) && ComputerUtil.canAttackNextTurn(c);
}
});
if(!any) {

View File

@@ -731,7 +731,7 @@ public class CombatUtil {
* @return a boolean.
*/
public static boolean canAttack(final Card c, final GameEntity def, final Combat combat) {
int cntAttackers = combat.getAttackers().size();
final int cntAttackers = combat.getAttackers().size();
final Game game = c.getGame();
if (cntAttackers > 0) {
@@ -741,10 +741,6 @@ public class CombatUtil {
if (keyword.equals("No more than two creatures can attack each combat.")) {
return false;
}
if (keyword.equals("No more than two creatures can attack you each combat.") &&
card.getController().getOpponent().equals(c.getController())) {
return false;
}
}
if (keyword.equals("CARDNAME can only attack alone.") && combat.isAttacking(card)) {
return false;
@@ -761,6 +757,18 @@ public class CombatUtil {
}
}
final int cntAttackersToDef = combat.getAttackersOf(def).size();
if (cntAttackersToDef > 1) {
for (final Card card : game.getCardsIn(ZoneType.Battlefield)) {
for (final String keyword : card.getKeyword()) {
if (keyword.equals("No more than two creatures can attack you each combat.") &&
card.getController().equals(def)) {
return false;
}
}
}
}
if ((c.hasKeyword("CARDNAME can't attack or block alone.") || c.hasKeyword("CARDNAME can't attack alone."))
&& c.getController().getCreaturesInPlay().size() < 2) {
return false;
@@ -832,20 +840,8 @@ public class CombatUtil {
*
* @param c
* a {@link forge.game.card.Card} object.
* @return a boolean.
*/
public static boolean canAttackNextTurn(final Card c) {
return canAttackNextTurn(c, c.getController().getOpponent());
}
// can a creature attack if untapped and without summoning sickness?
/**
* <p>
* canAttackNextTurn.
* </p>
*
* @param c
* a {@link forge.game.card.Card} object.
* @param def
* the defending {@link GameEntity}.
* @return a boolean.
*/
public static boolean canAttackNextTurn(final Card c, final GameEntity defender) {