mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
removed some calls to IsComputer in favour of comparision with player passed as parameter
checkConditions inlined ComputerUtilCombat recieve ai player as parameter
This commit is contained in:
@@ -345,19 +345,6 @@ public class AbilityFactory {
|
|||||||
condition.setConditions(mapParams);
|
condition.setConditions(mapParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* checkConditional.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param sa
|
|
||||||
* a {@link forge.card.spellability.SpellAbility} object.
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public static boolean checkConditional(final SpellAbility sa) {
|
|
||||||
return sa.getConditions().checkConditions(sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Easy creation of SubAbilities
|
// Easy creation of SubAbilities
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -1579,13 +1566,7 @@ public class AbilityFactory {
|
|||||||
public static void passUnlessCost(final SpellAbility sa, final boolean usedStack, final GameState game) {
|
public static void passUnlessCost(final SpellAbility sa, final boolean usedStack, final GameState game) {
|
||||||
final Card source = sa.getSourceCard();
|
final Card source = sa.getSourceCard();
|
||||||
final ApiType api = sa.getApi();
|
final ApiType api = sa.getApi();
|
||||||
if (api == null) {
|
if (api == null || sa.getParam("UnlessCost") == null) {
|
||||||
sa.resolve();
|
|
||||||
AbilityFactory.resolveSubAbilities(sa, usedStack, game);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Nothing to do
|
|
||||||
if (sa.getParam("UnlessCost") == null) {
|
|
||||||
sa.resolve();
|
sa.resolve();
|
||||||
AbilityFactory.resolveSubAbilities(sa, usedStack, game);
|
AbilityFactory.resolveSubAbilities(sa, usedStack, game);
|
||||||
return;
|
return;
|
||||||
@@ -1730,7 +1711,7 @@ public class AbilityFactory {
|
|||||||
|
|
||||||
final GameState game = Singletons.getModel().getGame();
|
final GameState game = Singletons.getModel().getGame();
|
||||||
// check conditions
|
// check conditions
|
||||||
if (AbilityFactory.checkConditional(sa)) {
|
if (sa.getConditions().areMet(sa)) {
|
||||||
if (sa.isWrapper()) {
|
if (sa.isWrapper()) {
|
||||||
sa.resolve();
|
sa.resolve();
|
||||||
AbilityFactory.resolveSubAbilities(sa, usedStack, game);
|
AbilityFactory.resolveSubAbilities(sa, usedStack, game);
|
||||||
@@ -1757,12 +1738,12 @@ public class AbilityFactory {
|
|||||||
// every resolving spellAbility will end here
|
// every resolving spellAbility will end here
|
||||||
if (usedStack) {
|
if (usedStack) {
|
||||||
SpellAbility root = sa.getRootAbility();
|
SpellAbility root = sa.getRootAbility();
|
||||||
Singletons.getModel().getGame().getStack().finishResolving(root, false);
|
game.getStack().finishResolving(root, false);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// check conditions
|
// check conditions
|
||||||
if (AbilityFactory.checkConditional(abSub)) {
|
if (abSub.getConditions().areMet(abSub)) {
|
||||||
AbilityFactory.passUnlessCost(abSub, usedStack, game);
|
AbilityFactory.passUnlessCost(abSub, usedStack, game);
|
||||||
} else {
|
} else {
|
||||||
AbilityFactory.resolveSubAbilities(abSub, usedStack, game);
|
AbilityFactory.resolveSubAbilities(abSub, usedStack, game);
|
||||||
|
|||||||
@@ -816,7 +816,7 @@ public class AttachAi extends SpellAiLogic {
|
|||||||
// at some point can support attaching a different card
|
// at some point can support attaching a different card
|
||||||
|
|
||||||
// Don't equip if already equipping
|
// Don't equip if already equipping
|
||||||
if (attachSource.getEquippingCard() != null && attachSource.getEquippingCard().getController().isComputer()) {
|
if (attachSource.getEquippingCard() != null && attachSource.getEquippingCard().getController() == aiPlayer) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -222,10 +222,10 @@ public class ChangeZoneAi extends SpellAiLogic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// don't play if the conditions aren't met, unless it would trigger a beneficial sub-condition
|
// don't play if the conditions aren't met, unless it would trigger a beneficial sub-condition
|
||||||
if (!AbilityFactory.checkConditional(sa)) {
|
if (!sa.getConditions().areMet(sa)) {
|
||||||
final AbilitySub abSub = sa.getSubAbility();
|
final AbilitySub abSub = sa.getSubAbility();
|
||||||
if (abSub != null && !sa.isWrapper() && "True".equals(source.getSVar("AIPlayForSub"))) {
|
if (abSub != null && !sa.isWrapper() && "True".equals(source.getSVar("AIPlayForSub"))) {
|
||||||
if (!AbilityFactory.checkConditional(abSub)) {
|
if (!abSub.getConditions().areMet(abSub)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -269,7 +269,7 @@ public class ChangeZoneAi extends SpellAiLogic {
|
|||||||
for (final Player p : pDefined) {
|
for (final Player p : pDefined) {
|
||||||
List<Card> list = p.getCardsIn(origin);
|
List<Card> list = p.getCardsIn(origin);
|
||||||
|
|
||||||
if ((type != null) && p.isComputer()) {
|
if ((type != null) && p == ai) {
|
||||||
// AI only "knows" about his information
|
// AI only "knows" about his information
|
||||||
list = CardLists.getValidCards(list, type, source.getController(), source);
|
list = CardLists.getValidCards(list, type, source.getController(), source);
|
||||||
}
|
}
|
||||||
@@ -402,7 +402,7 @@ public class ChangeZoneAi extends SpellAiLogic {
|
|||||||
List<Card> list = p.getCardsIn(origin);
|
List<Card> list = p.getCardsIn(origin);
|
||||||
|
|
||||||
// Computer should "know" his deck
|
// Computer should "know" his deck
|
||||||
if (p.isComputer()) {
|
if (p == ai) {
|
||||||
list = AbilityFactory.filterListByType(list, sa.getParam("ChangeType"), sa);
|
list = AbilityFactory.filterListByType(list, sa.getParam("ChangeType"), sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -741,7 +741,7 @@ public class ChangeZoneAi extends SpellAiLogic {
|
|||||||
CardLists.sortByEvaluateCreature(combatants);
|
CardLists.sortByEvaluateCreature(combatants);
|
||||||
|
|
||||||
for (final Card c : combatants) {
|
for (final Card c : combatants) {
|
||||||
if (c.getShield() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(c) && !c.getOwner().isHuman() && !c.isToken()) {
|
if (c.getShield() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c) && c.getOwner() == ai && !c.isToken()) {
|
||||||
tgt.addTarget(c);
|
tgt.addTarget(c);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -812,7 +812,7 @@ public class ChangeZoneAi extends SpellAiLogic {
|
|||||||
@Override
|
@Override
|
||||||
public boolean apply(final Card c) {
|
public boolean apply(final Card c) {
|
||||||
for (Card aura : c.getEnchantedBy()) {
|
for (Card aura : c.getEnchantedBy()) {
|
||||||
if (c.getOwner().isHuman() && aura.getController().equals(ai)) {
|
if (c.getOwner().isHostileTo(ai) && aura.getController().equals(ai)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1036,7 +1036,7 @@ public class ChangeZoneAi extends SpellAiLogic {
|
|||||||
if (!list.isEmpty()) {
|
if (!list.isEmpty()) {
|
||||||
final Card attachedTo = list.get(0);
|
final Card attachedTo = list.get(0);
|
||||||
// This code is for the Dragon auras
|
// This code is for the Dragon auras
|
||||||
if (attachedTo.getController().isHuman()) {
|
if (attachedTo.getController().isHostileTo(ai)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1147,7 +1147,7 @@ public class ChangeZoneAi extends SpellAiLogic {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (player.isHuman() && sa.hasParam("GainControl") && activator.equals(ai)) {
|
if (player.isHostileTo(ai) && sa.hasParam("GainControl") && activator.equals(ai)) {
|
||||||
fetchList = CardLists.filter(fetchList, new Predicate<Card>() {
|
fetchList = CardLists.filter(fetchList, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(final Card c) {
|
public boolean apply(final Card c) {
|
||||||
@@ -1161,7 +1161,7 @@ public class ChangeZoneAi extends SpellAiLogic {
|
|||||||
}
|
}
|
||||||
if (ZoneType.Exile.equals(destination) || origin.contains(ZoneType.Battlefield)) {
|
if (ZoneType.Exile.equals(destination) || origin.contains(ZoneType.Battlefield)) {
|
||||||
// Exiling or bouncing stuff
|
// Exiling or bouncing stuff
|
||||||
if (player.isHuman()) {
|
if (player.isHostileTo(ai)) {
|
||||||
c = CardFactoryUtil.getBestAI(fetchList);
|
c = CardFactoryUtil.getBestAI(fetchList);
|
||||||
} else {
|
} else {
|
||||||
c = CardFactoryUtil.getWorstAI(fetchList);
|
c = CardFactoryUtil.getWorstAI(fetchList);
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ public class DamageDealAi extends DamageAiBase {
|
|||||||
final List<Card> killables = CardLists.filter(hPlay, new Predicate<Card>() {
|
final List<Card> killables = CardLists.filter(hPlay, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(final Card c) {
|
public boolean apply(final Card c) {
|
||||||
return (c.getEnoughDamageToKill(d, source, false, noPrevention) <= d) && !ComputerUtil.canRegenerate(c)
|
return (c.getEnoughDamageToKill(d, source, false, noPrevention) <= d) && !ComputerUtil.canRegenerate(ai, c)
|
||||||
&& !(c.getSVar("SacMe").length() > 0);
|
&& !(c.getSVar("SacMe").length() > 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class DamagePreventAi extends SpellAiLogic {
|
|||||||
for (final Object o : objects) {
|
for (final Object o : objects) {
|
||||||
if (o instanceof Card) {
|
if (o instanceof Card) {
|
||||||
final Card c = (Card) o;
|
final Card c = (Card) o;
|
||||||
flag |= ComputerUtilCombat.combatantWouldBeDestroyed(c);
|
flag |= ComputerUtilCombat.combatantWouldBeDestroyed(ai, c);
|
||||||
} else if (o instanceof Player) {
|
} else if (o instanceof Player) {
|
||||||
// Don't need to worry about Combat Damage during AI's turn
|
// Don't need to worry about Combat Damage during AI's turn
|
||||||
final Player p = (Player) o;
|
final Player p = (Player) o;
|
||||||
@@ -134,7 +134,7 @@ public class DamagePreventAi extends SpellAiLogic {
|
|||||||
CardLists.sortByEvaluateCreature(combatants);
|
CardLists.sortByEvaluateCreature(combatants);
|
||||||
|
|
||||||
for (final Card c : combatants) {
|
for (final Card c : combatants) {
|
||||||
if (ComputerUtilCombat.combatantWouldBeDestroyed(c)) {
|
if (ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) {
|
||||||
tgt.addTarget(c);
|
tgt.addTarget(c);
|
||||||
chance = true;
|
chance = true;
|
||||||
break;
|
break;
|
||||||
@@ -195,7 +195,7 @@ public class DamagePreventAi extends SpellAiLogic {
|
|||||||
CardLists.sortByEvaluateCreature(combatants);
|
CardLists.sortByEvaluateCreature(combatants);
|
||||||
if (Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
|
if (Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
|
||||||
for (final Card c : combatants) {
|
for (final Card c : combatants) {
|
||||||
if (ComputerUtilCombat.combatantWouldBeDestroyed(c)) {
|
if (ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) {
|
||||||
tgt.addTarget(c);
|
tgt.addTarget(c);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class DestroyAi extends SpellAiLogic {
|
|||||||
* @see forge.card.abilityfactory.SpellAiLogic#canPlayAI(forge.game.player.Player, java.util.Map, forge.card.spellability.SpellAbility)
|
* @see forge.card.abilityfactory.SpellAiLogic#canPlayAI(forge.game.player.Player, java.util.Map, forge.card.spellability.SpellAbility)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected boolean canPlayAI(Player ai, SpellAbility sa) {
|
protected boolean canPlayAI(final Player ai, SpellAbility sa) {
|
||||||
// AI needs to be expanded, since this function can be pretty complex
|
// AI needs to be expanded, since this function can be pretty complex
|
||||||
// based on what the expected targets could be
|
// based on what the expected targets could be
|
||||||
final Random r = MyRandom.getRandom();
|
final Random r = MyRandom.getRandom();
|
||||||
@@ -105,7 +105,7 @@ public class DestroyAi extends SpellAiLogic {
|
|||||||
list = CardLists.filter(list, new Predicate<Card>() {
|
list = CardLists.filter(list, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(final Card c) {
|
public boolean apply(final Card c) {
|
||||||
return ((c.getShield() == 0) && !ComputerUtil.canRegenerate(c));
|
return ((c.getShield() == 0) && !ComputerUtil.canRegenerate(ai, c));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,10 +52,10 @@ public class LifeGainAi extends SpellAiLogic {
|
|||||||
}
|
}
|
||||||
// don't play if the conditions aren't met, unless it would trigger a
|
// don't play if the conditions aren't met, unless it would trigger a
|
||||||
// beneficial sub-condition
|
// beneficial sub-condition
|
||||||
if (!AbilityFactory.checkConditional(sa)) {
|
if (!sa.getConditions().areMet(sa)) {
|
||||||
final AbilitySub abSub = sa.getSubAbility();
|
final AbilitySub abSub = sa.getSubAbility();
|
||||||
if (abSub != null && !sa.isWrapper() && "True".equals(source.getSVar("AIPlayForSub"))) {
|
if (abSub != null && !sa.isWrapper() && "True".equals(source.getSVar("AIPlayForSub"))) {
|
||||||
if (!AbilityFactory.checkConditional(abSub)) {
|
if (!abSub.getConditions().areMet(abSub)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class MustBlockAi extends SpellAiLogic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
protected boolean doTriggerAINoCost(final Player ai, SpellAbility sa, boolean mandatory) {
|
||||||
final Card source = sa.getSourceCard();
|
final Card source = sa.getSourceCard();
|
||||||
final Target abTgt = sa.getTarget();
|
final Target abTgt = sa.getTarget();
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ public class MustBlockAi extends SpellAiLogic {
|
|||||||
if (!CombatUtil.canBlock(definedAttacker, c)) {
|
if (!CombatUtil.canBlock(definedAttacker, c)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ComputerUtilCombat.canDestroyAttacker(definedAttacker, c, null, false)) {
|
if (ComputerUtilCombat.canDestroyAttacker(ai, definedAttacker, c, null, false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!ComputerUtilCombat.canDestroyBlocker(c, definedAttacker, null, false)) {
|
if (!ComputerUtilCombat.canDestroyBlocker(ai, c, definedAttacker, null, false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
c.setTapped(tapped);
|
c.setTapped(tapped);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import forge.card.cardfactory.CardFactoryUtil;
|
|||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
|
import forge.game.GameState;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.game.ai.ComputerUtilCost;
|
import forge.game.ai.ComputerUtilCost;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
@@ -66,6 +67,7 @@ public class ProtectAi extends SpellAiLogic {
|
|||||||
*/
|
*/
|
||||||
private static List<Card> getProtectCreatures(final Player ai, final SpellAbility sa) {
|
private static List<Card> getProtectCreatures(final Player ai, final SpellAbility sa) {
|
||||||
final ArrayList<String> gains = AbilityFactory.getProtectionList(sa);
|
final ArrayList<String> gains = AbilityFactory.getProtectionList(sa);
|
||||||
|
final GameState game = Singletons.getModel().getGame();
|
||||||
|
|
||||||
List<Card> list = ai.getCreaturesInPlay();
|
List<Card> list = ai.getCreaturesInPlay();
|
||||||
list = CardLists.filter(list, new Predicate<Card>() {
|
list = CardLists.filter(list, new Predicate<Card>() {
|
||||||
@@ -81,8 +83,8 @@ public class ProtectAi extends SpellAiLogic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// will the creature attack (only relevant for sorcery speed)?
|
// will the creature attack (only relevant for sorcery speed)?
|
||||||
if (Singletons.getModel().getGame().getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
if (game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
||||||
&& Singletons.getModel().getGame().getPhaseHandler().isPlayerTurn(ai)
|
&& game.getPhaseHandler().isPlayerTurn(ai)
|
||||||
&& CardFactoryUtil.doesCreatureAttackAI(ai, c)) {
|
&& CardFactoryUtil.doesCreatureAttackAI(ai, c)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -90,14 +92,14 @@ public class ProtectAi extends SpellAiLogic {
|
|||||||
// is the creature blocking and unable to destroy the attacker
|
// is the creature blocking and unable to destroy the attacker
|
||||||
// or would be destroyed itself?
|
// or would be destroyed itself?
|
||||||
if (c.isBlocking()
|
if (c.isBlocking()
|
||||||
&& (ComputerUtilCombat.blockerWouldBeDestroyed(c))) {
|
&& (ComputerUtilCombat.blockerWouldBeDestroyed(ai, c))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// is the creature in blocked and the blocker would survive
|
// is the creature in blocked and the blocker would survive
|
||||||
if (Singletons.getModel().getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)
|
if (game.getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)
|
||||||
&& Singletons.getModel().getGame().getCombat().isAttacking(c) && Singletons.getModel().getGame().getCombat().isBlocked(c)
|
&& game.getCombat().isAttacking(c) && game.getCombat().isBlocked(c)
|
||||||
&& ComputerUtilCombat.blockerWouldBeDestroyed(Singletons.getModel().getGame().getCombat().getBlockers(c).get(0))) {
|
&& ComputerUtilCombat.blockerWouldBeDestroyed(ai, game.getCombat().getBlockers(c).get(0))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import forge.card.abilityfactory.AbilityFactory;
|
|||||||
import forge.card.abilityfactory.SpellAiLogic;
|
import forge.card.abilityfactory.SpellAiLogic;
|
||||||
import forge.card.cardfactory.CardFactoryUtil;
|
import forge.card.cardfactory.CardFactoryUtil;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
|
import forge.game.GameState;
|
||||||
import forge.game.ai.ComputerUtilCombat;
|
import forge.game.ai.ComputerUtilCombat;
|
||||||
import forge.game.phase.Combat;
|
import forge.game.phase.Combat;
|
||||||
import forge.game.phase.CombatUtil;
|
import forge.game.phase.CombatUtil;
|
||||||
@@ -223,7 +224,7 @@ public abstract class PumpAiBase extends SpellAiLogic {
|
|||||||
List<Card> attackers = combat.getAttackers();
|
List<Card> attackers = combat.getAttackers();
|
||||||
for (Card attacker : attackers) {
|
for (Card attacker : attackers) {
|
||||||
if (CombatUtil.canBlock(attacker, card, combat)
|
if (CombatUtil.canBlock(attacker, card, combat)
|
||||||
&& !ComputerUtilCombat.canDestroyAttacker(attacker, card, combat, false)) {
|
&& !ComputerUtilCombat.canDestroyAttacker(ai, attacker, card, combat, false)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,7 +233,7 @@ public abstract class PumpAiBase extends SpellAiLogic {
|
|||||||
List<Card> blockers = opp.getCreaturesInPlay();
|
List<Card> blockers = opp.getCreaturesInPlay();
|
||||||
for (Card blocker : blockers) {
|
for (Card blocker : blockers) {
|
||||||
if (CombatUtil.canBlock(card, blocker, combat)
|
if (CombatUtil.canBlock(card, blocker, combat)
|
||||||
&& !ComputerUtilCombat.canDestroyBlocker(blocker, card, combat, false)) {
|
&& !ComputerUtilCombat.canDestroyBlocker(ai, blocker, card, combat, false)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -382,7 +383,8 @@ public abstract class PumpAiBase extends SpellAiLogic {
|
|||||||
|
|
||||||
protected boolean shouldPumpCard(final Player ai, final SpellAbility sa, final Card c, final int defense, final int attack,
|
protected boolean shouldPumpCard(final Player ai, final SpellAbility sa, final Card c, final int defense, final int attack,
|
||||||
final List<String> keywords) {
|
final List<String> keywords) {
|
||||||
PhaseHandler phase = Singletons.getModel().getGame().getPhaseHandler();
|
final GameState game = Singletons.getModel().getGame();
|
||||||
|
PhaseHandler phase = game.getPhaseHandler();
|
||||||
|
|
||||||
if (!c.canBeTargetedBy(sa)) {
|
if (!c.canBeTargetedBy(sa)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -408,36 +410,35 @@ public abstract class PumpAiBase extends SpellAiLogic {
|
|||||||
// is the creature blocking and unable to destroy the attacker
|
// is the creature blocking and unable to destroy the attacker
|
||||||
// or would be destroyed itself?
|
// or would be destroyed itself?
|
||||||
if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) && c.isBlocking()) {
|
if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) && c.isBlocking()) {
|
||||||
if (defense > 0 && ComputerUtilCombat.blockerWouldBeDestroyed(c)) {
|
if (defense > 0 && ComputerUtilCombat.blockerWouldBeDestroyed(ai, c)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
List<Card> blockedBy = Singletons.getModel().getGame().getCombat().getAttackersBlockedBy(c);
|
List<Card> blockedBy = Singletons.getModel().getGame().getCombat().getAttackersBlockedBy(c);
|
||||||
// For now, Only care the first creature blocked by a card.
|
// For now, Only care the first creature blocked by a card.
|
||||||
// TODO Add in better BlockAdditional support
|
// TODO Add in better BlockAdditional support
|
||||||
if (!blockedBy.isEmpty() && attack > 0 && !ComputerUtilCombat.attackerWouldBeDestroyed(blockedBy.get(0))) {
|
if (!blockedBy.isEmpty() && attack > 0 && !ComputerUtilCombat.attackerWouldBeDestroyed(ai, blockedBy.get(0))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// is the creature unblocked and the spell will pump its power?
|
// is the creature unblocked and the spell will pump its power?
|
||||||
if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)
|
if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)
|
||||||
&& Singletons.getModel().getGame().getCombat().isAttacking(c)
|
&& game.getCombat().isAttacking(c) && game.getCombat().isUnblocked(c) && attack > 0) {
|
||||||
&& Singletons.getModel().getGame().getCombat().isUnblocked(c) && attack > 0) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// is the creature blocked and the blocker would survive
|
// is the creature blocked and the blocker would survive
|
||||||
if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) && attack > 0
|
if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) && attack > 0
|
||||||
&& Singletons.getModel().getGame().getCombat().isAttacking(c)
|
&& game.getCombat().isAttacking(c)
|
||||||
&& Singletons.getModel().getGame().getCombat().isBlocked(c)
|
&& game.getCombat().isBlocked(c)
|
||||||
&& Singletons.getModel().getGame().getCombat().getBlockers(c) != null
|
&& game.getCombat().getBlockers(c) != null
|
||||||
&& !Singletons.getModel().getGame().getCombat().getBlockers(c).isEmpty()
|
&& !game.getCombat().getBlockers(c).isEmpty()
|
||||||
&& !ComputerUtilCombat.blockerWouldBeDestroyed(Singletons.getModel().getGame().getCombat().getBlockers(c).get(0))) {
|
&& !ComputerUtilCombat.blockerWouldBeDestroyed(ai, game.getCombat().getBlockers(c).get(0))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the life of the computer is in danger, try to pump blockers blocking Tramplers
|
// if the life of the computer is in danger, try to pump blockers blocking Tramplers
|
||||||
List<Card> blockedBy = Singletons.getModel().getGame().getCombat().getAttackersBlockedBy(c);
|
List<Card> blockedBy = game.getCombat().getAttackersBlockedBy(c);
|
||||||
boolean attackerHasTrample = false;
|
boolean attackerHasTrample = false;
|
||||||
for (Card b : blockedBy) {
|
for (Card b : blockedBy) {
|
||||||
attackerHasTrample |= b.hasKeyword("Trample");
|
attackerHasTrample |= b.hasKeyword("Trample");
|
||||||
@@ -448,7 +449,7 @@ public abstract class PumpAiBase extends SpellAiLogic {
|
|||||||
&& c.isBlocking()
|
&& c.isBlocking()
|
||||||
&& defense > 0
|
&& defense > 0
|
||||||
&& attackerHasTrample
|
&& attackerHasTrample
|
||||||
&& (sa.isAbility() || ComputerUtilCombat.lifeInDanger(ai, Singletons.getModel().getGame().getCombat()))) {
|
&& (sa.isAbility() || ComputerUtilCombat.lifeInDanger(ai, game.getCombat()))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ public class RegenerateAi extends SpellAiLogic {
|
|||||||
|
|
||||||
for (final Card c : list) {
|
for (final Card c : list) {
|
||||||
if (c.getShield() == 0) {
|
if (c.getShield() == 0) {
|
||||||
flag |= ComputerUtilCombat.combatantWouldBeDestroyed(c);
|
flag |= ComputerUtilCombat.combatantWouldBeDestroyed(ai, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ public class RegenerateAi extends SpellAiLogic {
|
|||||||
CardLists.sortByEvaluateCreature(combatants);
|
CardLists.sortByEvaluateCreature(combatants);
|
||||||
|
|
||||||
for (final Card c : combatants) {
|
for (final Card c : combatants) {
|
||||||
if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(c)) {
|
if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) {
|
||||||
tgt.addTarget(c);
|
tgt.addTarget(c);
|
||||||
chance = true;
|
chance = true;
|
||||||
break;
|
break;
|
||||||
@@ -190,7 +190,7 @@ public class RegenerateAi extends SpellAiLogic {
|
|||||||
CardLists.sortByEvaluateCreature(combatants);
|
CardLists.sortByEvaluateCreature(combatants);
|
||||||
if (Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
|
if (Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
|
||||||
for (final Card c : combatants) {
|
for (final Card c : combatants) {
|
||||||
if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(c)) {
|
if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) {
|
||||||
tgt.addTarget(c);
|
tgt.addTarget(c);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class RegenerateAllAi extends SpellAiLogic {
|
|||||||
final List<Card> combatants = CardLists.filter(list, CardPredicates.Presets.CREATURES);
|
final List<Card> combatants = CardLists.filter(list, CardPredicates.Presets.CREATURES);
|
||||||
|
|
||||||
for (final Card c : combatants) {
|
for (final Card c : combatants) {
|
||||||
if (c.getShield() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(c)) {
|
if (c.getShield() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) {
|
||||||
numSaved++;
|
numSaved++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ public class ChooseTypeEffect extends SpellEffect {
|
|||||||
GuiChoose.one("Computer picked: ", new String[]{chosen});
|
GuiChoose.one("Computer picked: ", new String[]{chosen});
|
||||||
chosenType = chosen;
|
chosenType = chosen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CardUtil.isACreatureType(chosenType) && !invalidTypes.contains(chosenType)) {
|
if (CardUtil.isACreatureType(chosenType) && !invalidTypes.contains(chosenType)) {
|
||||||
valid = true;
|
valid = true;
|
||||||
card.setChosenType(chosenType);
|
card.setChosenType(chosenType);
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ public class SpellAbilityCondition extends SpellAbilityVariables {
|
|||||||
* a {@link forge.card.spellability.SpellAbility} object.
|
* a {@link forge.card.spellability.SpellAbility} object.
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public final boolean checkConditions(final SpellAbility sa) {
|
public final boolean areMet(final SpellAbility sa) {
|
||||||
|
|
||||||
Player activator = sa.getActivatingPlayer();
|
Player activator = sa.getActivatingPlayer();
|
||||||
if (activator == null) {
|
if (activator == null) {
|
||||||
|
|||||||
@@ -901,7 +901,7 @@ public class AiAttackController {
|
|||||||
if ((isWorthLessThanAllKillers || canKillAllDangerous || numberOfPossibleBlockers < 2)
|
if ((isWorthLessThanAllKillers || canKillAllDangerous || numberOfPossibleBlockers < 2)
|
||||||
&& CombatUtil.canBlock(attacker, defender)) {
|
&& CombatUtil.canBlock(attacker, defender)) {
|
||||||
numberOfPossibleBlockers += 1;
|
numberOfPossibleBlockers += 1;
|
||||||
if (isWorthLessThanAllKillers && ComputerUtilCombat.canDestroyAttacker(attacker, defender, combat, false)
|
if (isWorthLessThanAllKillers && ComputerUtilCombat.canDestroyAttacker(ai, attacker, defender, combat, false)
|
||||||
&& !(attacker.hasKeyword("Undying") && attacker.getCounters(CounterType.P1P1) == 0)) {
|
&& !(attacker.hasKeyword("Undying") && attacker.getCounters(CounterType.P1P1) == 0)) {
|
||||||
canBeKilledByOne = true; // there is a single creature on
|
canBeKilledByOne = true; // there is a single creature on
|
||||||
// the battlefield that can kill
|
// the battlefield that can kill
|
||||||
@@ -915,7 +915,7 @@ public class AiAttackController {
|
|||||||
}
|
}
|
||||||
// see if this attacking creature can destroy this defender, if
|
// see if this attacking creature can destroy this defender, if
|
||||||
// not record that it can't kill everything
|
// not record that it can't kill everything
|
||||||
if (canKillAllDangerous && !ComputerUtilCombat.canDestroyBlocker(defender, attacker, combat, false)) {
|
if (canKillAllDangerous && !ComputerUtilCombat.canDestroyBlocker(ai, defender, attacker, combat, false)) {
|
||||||
canKillAll = false;
|
canKillAll = false;
|
||||||
if (!canKillAllDangerous) {
|
if (!canKillAllDangerous) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -415,7 +415,7 @@ public class ComputerUtil {
|
|||||||
typeList = CardLists.getNotType(typeList, "Creature");
|
typeList = CardLists.getNotType(typeList, "Creature");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((target != null) && target.getController().isComputer() && typeList.contains(target)) {
|
if ((target != null) && target.getController() == ai && typeList.contains(target)) {
|
||||||
typeList.remove(target); // don't sacrifice the card we're pumping
|
typeList.remove(target); // don't sacrifice the card we're pumping
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,7 +473,7 @@ public class ComputerUtil {
|
|||||||
} else {
|
} else {
|
||||||
typeList = CardLists.getValidCards(ai.getCardsIn(zone), type.split(","), activate.getController(), activate);
|
typeList = CardLists.getValidCards(ai.getCardsIn(zone), type.split(","), activate.getController(), activate);
|
||||||
}
|
}
|
||||||
if ((target != null) && target.getController().isComputer() && typeList.contains(target)) {
|
if ((target != null) && target.getController() == ai && typeList.contains(target)) {
|
||||||
typeList.remove(target); // don't exile the card we're pumping
|
typeList.remove(target); // don't exile the card we're pumping
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,7 +588,7 @@ public class ComputerUtil {
|
|||||||
public static List<Card> chooseReturnType(final Player ai, final String type, final Card activate, final Card target, final int amount) {
|
public static List<Card> chooseReturnType(final Player ai, final String type, final Card activate, final Card target, final int amount) {
|
||||||
final List<Card> typeList =
|
final List<Card> typeList =
|
||||||
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(","), activate.getController(), activate);
|
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(","), activate.getController(), activate);
|
||||||
if ((target != null) && target.getController().isComputer() && typeList.contains(target)) {
|
if ((target != null) && target.getController() == ai && typeList.contains(target)) {
|
||||||
// don't bounce the card we're pumping
|
// don't bounce the card we're pumping
|
||||||
typeList.remove(target);
|
typeList.remove(target);
|
||||||
}
|
}
|
||||||
@@ -709,12 +709,13 @@ public class ComputerUtil {
|
|||||||
* <p>
|
* <p>
|
||||||
* canRegenerate.
|
* canRegenerate.
|
||||||
* </p>
|
* </p>
|
||||||
|
* @param ai
|
||||||
*
|
*
|
||||||
* @param card
|
* @param card
|
||||||
* a {@link forge.Card} object.
|
* a {@link forge.Card} object.
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean canRegenerate(final Card card) {
|
public static boolean canRegenerate(Player ai, final Card card) {
|
||||||
|
|
||||||
if (card.hasKeyword("CARDNAME can't be regenerated.")) {
|
if (card.hasKeyword("CARDNAME can't be regenerated.")) {
|
||||||
return false;
|
return false;
|
||||||
@@ -736,7 +737,7 @@ public class ComputerUtil {
|
|||||||
continue; // Can't play ability
|
continue; // Can't play ability
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controller.isComputer()) {
|
if (controller == ai) {
|
||||||
final Cost abCost = sa.getPayCosts();
|
final Cost abCost = sa.getPayCosts();
|
||||||
if (abCost != null) {
|
if (abCost != null) {
|
||||||
// AI currently disabled for these costs
|
// AI currently disabled for these costs
|
||||||
|
|||||||
@@ -229,11 +229,11 @@ public class ComputerUtilBlock {
|
|||||||
* a {@link forge.game.phase.Combat} object.
|
* a {@link forge.game.phase.Combat} object.
|
||||||
* @return a {@link forge.CardList} object.
|
* @return a {@link forge.CardList} object.
|
||||||
*/
|
*/
|
||||||
private static List<Card> getSafeBlockers(final Card attacker, final List<Card> blockersLeft, final Combat combat) {
|
private static List<Card> getSafeBlockers(final Player ai, final Card attacker, final List<Card> blockersLeft, final Combat combat) {
|
||||||
final List<Card> blockers = new ArrayList<Card>();
|
final List<Card> blockers = new ArrayList<Card>();
|
||||||
|
|
||||||
for (final Card b : blockersLeft) {
|
for (final Card b : blockersLeft) {
|
||||||
if (!ComputerUtilCombat.canDestroyBlocker(b, attacker, combat, false)) {
|
if (!ComputerUtilCombat.canDestroyBlocker(ai, b, attacker, combat, false)) {
|
||||||
blockers.add(b);
|
blockers.add(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -255,11 +255,11 @@ public class ComputerUtilBlock {
|
|||||||
* a {@link forge.game.phase.Combat} object.
|
* a {@link forge.game.phase.Combat} object.
|
||||||
* @return a {@link forge.CardList} object.
|
* @return a {@link forge.CardList} object.
|
||||||
*/
|
*/
|
||||||
private static List<Card> getKillingBlockers(final Card attacker, final List<Card> blockersLeft, final Combat combat) {
|
private static List<Card> getKillingBlockers(final Player ai, final Card attacker, final List<Card> blockersLeft, final Combat combat) {
|
||||||
final List<Card> blockers = new ArrayList<Card>();
|
final List<Card> blockers = new ArrayList<Card>();
|
||||||
|
|
||||||
for (final Card b : blockersLeft) {
|
for (final Card b : blockersLeft) {
|
||||||
if (ComputerUtilCombat.canDestroyAttacker(attacker, b, combat, false)) {
|
if (ComputerUtilCombat.canDestroyAttacker(ai, attacker, b, combat, false)) {
|
||||||
blockers.add(b);
|
blockers.add(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,7 +337,7 @@ public class ComputerUtilBlock {
|
|||||||
* a {@link forge.game.phase.Combat} object.
|
* a {@link forge.game.phase.Combat} object.
|
||||||
* @return a {@link forge.game.phase.Combat} object.
|
* @return a {@link forge.game.phase.Combat} object.
|
||||||
*/
|
*/
|
||||||
private static Combat makeGoodBlocks(final Combat combat) {
|
private static Combat makeGoodBlocks(final Player ai, final Combat combat) {
|
||||||
|
|
||||||
List<Card> currentAttackers = new ArrayList<Card>(ComputerUtilBlock.getAttackersLeft());
|
List<Card> currentAttackers = new ArrayList<Card>(ComputerUtilBlock.getAttackersLeft());
|
||||||
|
|
||||||
@@ -352,13 +352,13 @@ public class ComputerUtilBlock {
|
|||||||
final List<Card> blockers = ComputerUtilBlock.getPossibleBlockers(attacker,
|
final List<Card> blockers = ComputerUtilBlock.getPossibleBlockers(attacker,
|
||||||
ComputerUtilBlock.getBlockersLeft(), combat, true);
|
ComputerUtilBlock.getBlockersLeft(), combat, true);
|
||||||
|
|
||||||
final List<Card> safeBlockers = ComputerUtilBlock.getSafeBlockers(attacker, blockers, combat);
|
final List<Card> safeBlockers = ComputerUtilBlock.getSafeBlockers(ai, attacker, blockers, combat);
|
||||||
List<Card> killingBlockers;
|
List<Card> killingBlockers;
|
||||||
|
|
||||||
if (safeBlockers.size() > 0) {
|
if (safeBlockers.size() > 0) {
|
||||||
// 1.Blockers that can destroy the attacker but won't get
|
// 1.Blockers that can destroy the attacker but won't get
|
||||||
// destroyed
|
// destroyed
|
||||||
killingBlockers = ComputerUtilBlock.getKillingBlockers(attacker, safeBlockers, combat);
|
killingBlockers = ComputerUtilBlock.getKillingBlockers(ai, attacker, safeBlockers, combat);
|
||||||
if (killingBlockers.size() > 0) {
|
if (killingBlockers.size() > 0) {
|
||||||
blocker = CardFactoryUtil.getWorstCreatureAI(killingBlockers);
|
blocker = CardFactoryUtil.getWorstCreatureAI(killingBlockers);
|
||||||
} else if (!attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
|
} else if (!attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
|
||||||
@@ -368,7 +368,7 @@ public class ComputerUtilBlock {
|
|||||||
} // no safe blockers
|
} // no safe blockers
|
||||||
else {
|
else {
|
||||||
// 3.Blockers that can destroy the attacker and have an upside when dying
|
// 3.Blockers that can destroy the attacker and have an upside when dying
|
||||||
killingBlockers = ComputerUtilBlock.getKillingBlockers(attacker, blockers, combat);
|
killingBlockers = ComputerUtilBlock.getKillingBlockers(ai, attacker, blockers, combat);
|
||||||
for (Card b : killingBlockers) {
|
for (Card b : killingBlockers) {
|
||||||
if ((b.hasKeyword("Undying") && b.getCounters(CounterType.P1P1) == 0)
|
if ((b.hasKeyword("Undying") && b.getCounters(CounterType.P1P1) == 0)
|
||||||
|| !b.getSVar("SacMe").equals("")) {
|
|| !b.getSVar("SacMe").equals("")) {
|
||||||
@@ -542,7 +542,7 @@ public class ComputerUtilBlock {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
killingBlockers = ComputerUtilBlock.getKillingBlockers(attacker,
|
killingBlockers = ComputerUtilBlock.getKillingBlockers(ai, attacker,
|
||||||
ComputerUtilBlock.getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true),
|
ComputerUtilBlock.getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true),
|
||||||
combat);
|
combat);
|
||||||
if ((killingBlockers.size() > 0) && ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
if ((killingBlockers.size() > 0) && ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||||
@@ -648,7 +648,7 @@ public class ComputerUtilBlock {
|
|||||||
* a {@link forge.game.phase.Combat} object.
|
* a {@link forge.game.phase.Combat} object.
|
||||||
* @return a {@link forge.game.phase.Combat} object.
|
* @return a {@link forge.game.phase.Combat} object.
|
||||||
*/
|
*/
|
||||||
private static Combat reinforceBlockersToKill(final Combat combat) {
|
private static Combat reinforceBlockersToKill(final Player ai, final Combat combat) {
|
||||||
|
|
||||||
List<Card> safeBlockers;
|
List<Card> safeBlockers;
|
||||||
List<Card> blockers;
|
List<Card> blockers;
|
||||||
@@ -664,7 +664,7 @@ public class ComputerUtilBlock {
|
|||||||
blockers.removeAll(combat.getBlockers(attacker));
|
blockers.removeAll(combat.getBlockers(attacker));
|
||||||
|
|
||||||
// Try to use safe blockers first
|
// Try to use safe blockers first
|
||||||
safeBlockers = ComputerUtilBlock.getSafeBlockers(attacker, blockers, combat);
|
safeBlockers = ComputerUtilBlock.getSafeBlockers(ai, attacker, blockers, combat);
|
||||||
for (final Card blocker : safeBlockers) {
|
for (final Card blocker : safeBlockers) {
|
||||||
final int damageNeeded = attacker.getKillDamage()
|
final int damageNeeded = attacker.getKillDamage()
|
||||||
+ ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, false);
|
+ ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, false);
|
||||||
@@ -808,7 +808,7 @@ public class ComputerUtilBlock {
|
|||||||
CardLists.sortAttackLowFirst(ComputerUtilBlock.getBlockersLeft());
|
CardLists.sortAttackLowFirst(ComputerUtilBlock.getBlockersLeft());
|
||||||
|
|
||||||
// == 1. choose best blocks first ==
|
// == 1. choose best blocks first ==
|
||||||
combat = ComputerUtilBlock.makeGoodBlocks(combat);
|
combat = ComputerUtilBlock.makeGoodBlocks(ai, combat);
|
||||||
combat = ComputerUtilBlock.makeGangBlocks(ai, combat);
|
combat = ComputerUtilBlock.makeGangBlocks(ai, combat);
|
||||||
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||||
combat = ComputerUtilBlock.makeTradeBlocks(ai, combat); // choose
|
combat = ComputerUtilBlock.makeTradeBlocks(ai, combat); // choose
|
||||||
@@ -830,7 +830,7 @@ public class ComputerUtilBlock {
|
|||||||
// Support blockers not destroying the attacker with more blockers to
|
// Support blockers not destroying the attacker with more blockers to
|
||||||
// try to kill the attacker
|
// try to kill the attacker
|
||||||
if (!ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
if (!ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||||
combat = ComputerUtilBlock.reinforceBlockersToKill(combat);
|
combat = ComputerUtilBlock.reinforceBlockersToKill(ai, combat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// == 2. If the AI life would still be in danger make a safer approach
|
// == 2. If the AI life would still be in danger make a safer approach
|
||||||
@@ -845,7 +845,7 @@ public class ComputerUtilBlock {
|
|||||||
// necessary
|
// necessary
|
||||||
// trade blocks
|
// trade blocks
|
||||||
// if life is in danger
|
// if life is in danger
|
||||||
combat = ComputerUtilBlock.makeGoodBlocks(combat);
|
combat = ComputerUtilBlock.makeGoodBlocks(ai, combat);
|
||||||
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||||
combat = ComputerUtilBlock.makeChumpBlocks(ai, combat); // choose
|
combat = ComputerUtilBlock.makeChumpBlocks(ai, combat); // choose
|
||||||
// necessary
|
// necessary
|
||||||
@@ -859,7 +859,7 @@ public class ComputerUtilBlock {
|
|||||||
combat = ComputerUtilBlock.reinforceBlockersAgainstTrample(ai, combat);
|
combat = ComputerUtilBlock.reinforceBlockersAgainstTrample(ai, combat);
|
||||||
}
|
}
|
||||||
combat = ComputerUtilBlock.makeGangBlocks(ai, combat);
|
combat = ComputerUtilBlock.makeGangBlocks(ai, combat);
|
||||||
combat = ComputerUtilBlock.reinforceBlockersToKill(combat);
|
combat = ComputerUtilBlock.reinforceBlockersToKill(ai, combat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// == 3. If the AI life would be in serious danger make an even safer
|
// == 3. If the AI life would be in serious danger make an even safer
|
||||||
@@ -878,7 +878,7 @@ public class ComputerUtilBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
if (!ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||||
combat = ComputerUtilBlock.makeGoodBlocks(combat);
|
combat = ComputerUtilBlock.makeGoodBlocks(ai, combat);
|
||||||
}
|
}
|
||||||
// Reinforce blockers blocking attackers with trample if life is
|
// Reinforce blockers blocking attackers with trample if life is
|
||||||
// still in danger
|
// still in danger
|
||||||
@@ -888,7 +888,7 @@ public class ComputerUtilBlock {
|
|||||||
combat = ComputerUtilBlock.makeGangBlocks(ai, combat);
|
combat = ComputerUtilBlock.makeGangBlocks(ai, combat);
|
||||||
// Support blockers not destroying the attacker with more blockers
|
// Support blockers not destroying the attacker with more blockers
|
||||||
// to try to kill the attacker
|
// to try to kill the attacker
|
||||||
combat = ComputerUtilBlock.reinforceBlockersToKill(combat);
|
combat = ComputerUtilBlock.reinforceBlockersToKill(ai, combat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign blockers that have to block
|
// assign blockers that have to block
|
||||||
|
|||||||
@@ -517,18 +517,19 @@ public class ComputerUtilCombat {
|
|||||||
* <p>
|
* <p>
|
||||||
* combatantWouldBeDestroyed.
|
* combatantWouldBeDestroyed.
|
||||||
* </p>
|
* </p>
|
||||||
|
* @param ai
|
||||||
*
|
*
|
||||||
* @param combatant
|
* @param combatant
|
||||||
* a {@link forge.Card} object.
|
* a {@link forge.Card} object.
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean combatantWouldBeDestroyed(final Card combatant) {
|
public static boolean combatantWouldBeDestroyed(Player ai, final Card combatant) {
|
||||||
|
|
||||||
if (combatant.isAttacking()) {
|
if (combatant.isAttacking()) {
|
||||||
return ComputerUtilCombat.attackerWouldBeDestroyed(combatant);
|
return ComputerUtilCombat.attackerWouldBeDestroyed(ai, combatant);
|
||||||
}
|
}
|
||||||
if (combatant.isBlocking()) {
|
if (combatant.isBlocking()) {
|
||||||
return ComputerUtilCombat.blockerWouldBeDestroyed(combatant);
|
return ComputerUtilCombat.blockerWouldBeDestroyed(ai, combatant);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -538,16 +539,17 @@ public class ComputerUtilCombat {
|
|||||||
* <p>
|
* <p>
|
||||||
* attackerWouldBeDestroyed.
|
* attackerWouldBeDestroyed.
|
||||||
* </p>
|
* </p>
|
||||||
|
* @param ai
|
||||||
*
|
*
|
||||||
* @param attacker
|
* @param attacker
|
||||||
* a {@link forge.Card} object.
|
* a {@link forge.Card} object.
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean attackerWouldBeDestroyed(final Card attacker) {
|
public static boolean attackerWouldBeDestroyed(Player ai, final Card attacker) {
|
||||||
final List<Card> blockers = Singletons.getModel().getGame().getCombat().getBlockers(attacker);
|
final List<Card> blockers = Singletons.getModel().getGame().getCombat().getBlockers(attacker);
|
||||||
|
|
||||||
for (final Card defender : blockers) {
|
for (final Card defender : blockers) {
|
||||||
if (ComputerUtilCombat.canDestroyAttacker(attacker, defender, Singletons.getModel().getGame().getCombat(), true)
|
if (ComputerUtilCombat.canDestroyAttacker(ai, attacker, defender, Singletons.getModel().getGame().getCombat(), true)
|
||||||
&& !(defender.hasKeyword("Wither") || defender.hasKeyword("Infect"))) {
|
&& !(defender.hasKeyword("Wither") || defender.hasKeyword("Infect"))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1343,6 +1345,7 @@ public class ComputerUtilCombat {
|
|||||||
* <p>
|
* <p>
|
||||||
* canDestroyAttacker.
|
* canDestroyAttacker.
|
||||||
* </p>
|
* </p>
|
||||||
|
* @param ai
|
||||||
*
|
*
|
||||||
* @param attacker
|
* @param attacker
|
||||||
* a {@link forge.Card} object.
|
* a {@link forge.Card} object.
|
||||||
@@ -1354,7 +1357,7 @@ public class ComputerUtilCombat {
|
|||||||
* a boolean.
|
* a boolean.
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean canDestroyAttacker(final Card attacker, final Card defender, final Combat combat,
|
public static boolean canDestroyAttacker(Player ai, final Card attacker, final Card defender, final Combat combat,
|
||||||
final boolean withoutAbilities) {
|
final boolean withoutAbilities) {
|
||||||
|
|
||||||
if (attacker.getName().equals("Sylvan Basilisk") && !defender.hasKeyword("Indestructible")) {
|
if (attacker.getName().equals("Sylvan Basilisk") && !defender.hasKeyword("Indestructible")) {
|
||||||
@@ -1375,7 +1378,7 @@ public class ComputerUtilCombat {
|
|||||||
}
|
}
|
||||||
} // flanking
|
} // flanking
|
||||||
|
|
||||||
if (((attacker.hasKeyword("Indestructible") || (ComputerUtil.canRegenerate(attacker) && !withoutAbilities)) && !(defender
|
if (((attacker.hasKeyword("Indestructible") || (ComputerUtil.canRegenerate(ai, attacker) && !withoutAbilities)) && !(defender
|
||||||
.hasKeyword("Wither") || defender.hasKeyword("Infect")))
|
.hasKeyword("Wither") || defender.hasKeyword("Infect")))
|
||||||
|| (attacker.hasKeyword("Persist") && !attacker.canHaveCountersPlacedOnIt(CounterType.M1M1) && (attacker
|
|| (attacker.hasKeyword("Persist") && !attacker.canHaveCountersPlacedOnIt(CounterType.M1M1) && (attacker
|
||||||
.getCounters(CounterType.M1M1) == 0))
|
.getCounters(CounterType.M1M1) == 0))
|
||||||
@@ -1471,18 +1474,19 @@ public class ComputerUtilCombat {
|
|||||||
* <p>
|
* <p>
|
||||||
* blockerWouldBeDestroyed.
|
* blockerWouldBeDestroyed.
|
||||||
* </p>
|
* </p>
|
||||||
|
* @param ai
|
||||||
*
|
*
|
||||||
* @param blocker
|
* @param blocker
|
||||||
* a {@link forge.Card} object.
|
* a {@link forge.Card} object.
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean blockerWouldBeDestroyed(final Card blocker) {
|
public static boolean blockerWouldBeDestroyed(Player ai, final Card blocker) {
|
||||||
// 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 = Singletons.getModel().getGame().getCombat().getAttackersBlockedBy(blocker);
|
final List<Card> attackers = Singletons.getModel().getGame().getCombat().getAttackersBlockedBy(blocker);
|
||||||
|
|
||||||
for (Card attacker : attackers) {
|
for (Card attacker : attackers) {
|
||||||
if (ComputerUtilCombat.canDestroyBlocker(blocker, attacker, Singletons.getModel().getGame().getCombat(), true)
|
if (ComputerUtilCombat.canDestroyBlocker(ai, blocker, attacker, Singletons.getModel().getGame().getCombat(), true)
|
||||||
&& !(attacker.hasKeyword("Wither") || attacker.hasKeyword("Infect"))) {
|
&& !(attacker.hasKeyword("Wither") || attacker.hasKeyword("Infect"))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1495,6 +1499,7 @@ public class ComputerUtilCombat {
|
|||||||
* <p>
|
* <p>
|
||||||
* canDestroyBlocker.
|
* canDestroyBlocker.
|
||||||
* </p>
|
* </p>
|
||||||
|
* @param ai
|
||||||
*
|
*
|
||||||
* @param defender
|
* @param defender
|
||||||
* a {@link forge.Card} object.
|
* a {@link forge.Card} object.
|
||||||
@@ -1506,7 +1511,7 @@ public class ComputerUtilCombat {
|
|||||||
* a boolean.
|
* a boolean.
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean canDestroyBlocker(final Card defender, final Card attacker, final Combat combat,
|
public static boolean canDestroyBlocker(Player ai, final Card defender, final Card attacker, final Combat combat,
|
||||||
final boolean withoutAbilities) {
|
final boolean withoutAbilities) {
|
||||||
|
|
||||||
int flankingMagnitude = 0;
|
int flankingMagnitude = 0;
|
||||||
@@ -1522,7 +1527,7 @@ public class ComputerUtilCombat {
|
|||||||
}
|
}
|
||||||
} // flanking
|
} // flanking
|
||||||
|
|
||||||
if (((defender.hasKeyword("Indestructible") || (ComputerUtil.canRegenerate(defender) && !withoutAbilities)) && !(attacker
|
if (((defender.hasKeyword("Indestructible") || (ComputerUtil.canRegenerate(ai, defender) && !withoutAbilities)) && !(attacker
|
||||||
.hasKeyword("Wither") || attacker.hasKeyword("Infect")))
|
.hasKeyword("Wither") || attacker.hasKeyword("Infect")))
|
||||||
|| (defender.hasKeyword("Persist") && !defender.canHaveCountersPlacedOnIt(CounterType.M1M1) && (defender
|
|| (defender.hasKeyword("Persist") && !defender.canHaveCountersPlacedOnIt(CounterType.M1M1) && (defender
|
||||||
.getCounters(CounterType.M1M1) == 0))
|
.getCounters(CounterType.M1M1) == 0))
|
||||||
|
|||||||
Reference in New Issue
Block a user