From cd9c815534e6a953278ca5f76a89c30a1dfe2838 Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Sun, 3 Feb 2013 17:30:25 +0000 Subject: [PATCH] removed some calls to IsComputer in favour of comparision with player passed as parameter checkConditions inlined ComputerUtilCombat recieve ai player as parameter --- .../card/abilityfactory/AbilityFactory.java | 27 +++------------ .../card/abilityfactory/ai/AttachAi.java | 2 +- .../card/abilityfactory/ai/ChangeZoneAi.java | 18 +++++----- .../card/abilityfactory/ai/DamageDealAi.java | 2 +- .../abilityfactory/ai/DamagePreventAi.java | 6 ++-- .../card/abilityfactory/ai/DestroyAi.java | 4 +-- .../card/abilityfactory/ai/LifeGainAi.java | 4 +-- .../card/abilityfactory/ai/MustBlockAi.java | 6 ++-- .../card/abilityfactory/ai/ProtectAi.java | 16 +++++---- .../card/abilityfactory/ai/PumpAiBase.java | 29 ++++++++-------- .../card/abilityfactory/ai/RegenerateAi.java | 6 ++-- .../abilityfactory/ai/RegenerateAllAi.java | 2 +- .../effects/ChooseTypeEffect.java | 1 + .../spellability/SpellAbilityCondition.java | 2 +- .../forge/game/ai/AiAttackController.java | 4 +-- src/main/java/forge/game/ai/ComputerUtil.java | 11 +++--- .../java/forge/game/ai/ComputerUtilBlock.java | 34 +++++++++---------- .../forge/game/ai/ComputerUtilCombat.java | 27 +++++++++------ 18 files changed, 96 insertions(+), 105 deletions(-) diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactory.java b/src/main/java/forge/card/abilityfactory/AbilityFactory.java index 3eaecf3fa49..03a031d17b7 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactory.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactory.java @@ -345,19 +345,6 @@ public class AbilityFactory { condition.setConditions(mapParams); } - /** - *

- * checkConditional. - *

- * - * @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 /** *

@@ -1579,13 +1566,7 @@ public class AbilityFactory { public static void passUnlessCost(final SpellAbility sa, final boolean usedStack, final GameState game) { final Card source = sa.getSourceCard(); final ApiType api = sa.getApi(); - if (api == null) { - sa.resolve(); - AbilityFactory.resolveSubAbilities(sa, usedStack, game); - return; - } - // Nothing to do - if (sa.getParam("UnlessCost") == null) { + if (api == null || sa.getParam("UnlessCost") == null) { sa.resolve(); AbilityFactory.resolveSubAbilities(sa, usedStack, game); return; @@ -1730,7 +1711,7 @@ public class AbilityFactory { final GameState game = Singletons.getModel().getGame(); // check conditions - if (AbilityFactory.checkConditional(sa)) { + if (sa.getConditions().areMet(sa)) { if (sa.isWrapper()) { sa.resolve(); AbilityFactory.resolveSubAbilities(sa, usedStack, game); @@ -1757,12 +1738,12 @@ public class AbilityFactory { // every resolving spellAbility will end here if (usedStack) { SpellAbility root = sa.getRootAbility(); - Singletons.getModel().getGame().getStack().finishResolving(root, false); + game.getStack().finishResolving(root, false); } return; } // check conditions - if (AbilityFactory.checkConditional(abSub)) { + if (abSub.getConditions().areMet(abSub)) { AbilityFactory.passUnlessCost(abSub, usedStack, game); } else { AbilityFactory.resolveSubAbilities(abSub, usedStack, game); diff --git a/src/main/java/forge/card/abilityfactory/ai/AttachAi.java b/src/main/java/forge/card/abilityfactory/ai/AttachAi.java index 5b28573467d..35999f81d38 100644 --- a/src/main/java/forge/card/abilityfactory/ai/AttachAi.java +++ b/src/main/java/forge/card/abilityfactory/ai/AttachAi.java @@ -816,7 +816,7 @@ public class AttachAi extends SpellAiLogic { // at some point can support attaching a different card // Don't equip if already equipping - if (attachSource.getEquippingCard() != null && attachSource.getEquippingCard().getController().isComputer()) { + if (attachSource.getEquippingCard() != null && attachSource.getEquippingCard().getController() == aiPlayer) { return null; } diff --git a/src/main/java/forge/card/abilityfactory/ai/ChangeZoneAi.java b/src/main/java/forge/card/abilityfactory/ai/ChangeZoneAi.java index f1a95e3d8c3..ee22bb1512d 100644 --- a/src/main/java/forge/card/abilityfactory/ai/ChangeZoneAi.java +++ b/src/main/java/forge/card/abilityfactory/ai/ChangeZoneAi.java @@ -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 - if (!AbilityFactory.checkConditional(sa)) { + if (!sa.getConditions().areMet(sa)) { final AbilitySub abSub = sa.getSubAbility(); if (abSub != null && !sa.isWrapper() && "True".equals(source.getSVar("AIPlayForSub"))) { - if (!AbilityFactory.checkConditional(abSub)) { + if (!abSub.getConditions().areMet(abSub)) { return false; } } else { @@ -269,7 +269,7 @@ public class ChangeZoneAi extends SpellAiLogic { for (final Player p : pDefined) { List list = p.getCardsIn(origin); - if ((type != null) && p.isComputer()) { + if ((type != null) && p == ai) { // AI only "knows" about his information list = CardLists.getValidCards(list, type, source.getController(), source); } @@ -402,7 +402,7 @@ public class ChangeZoneAi extends SpellAiLogic { List list = p.getCardsIn(origin); // Computer should "know" his deck - if (p.isComputer()) { + if (p == ai) { list = AbilityFactory.filterListByType(list, sa.getParam("ChangeType"), sa); } @@ -741,7 +741,7 @@ public class ChangeZoneAi extends SpellAiLogic { CardLists.sortByEvaluateCreature(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); return true; } @@ -812,7 +812,7 @@ public class ChangeZoneAi extends SpellAiLogic { @Override public boolean apply(final Card c) { for (Card aura : c.getEnchantedBy()) { - if (c.getOwner().isHuman() && aura.getController().equals(ai)) { + if (c.getOwner().isHostileTo(ai) && aura.getController().equals(ai)) { return false; } } @@ -1036,7 +1036,7 @@ public class ChangeZoneAi extends SpellAiLogic { if (!list.isEmpty()) { final Card attachedTo = list.get(0); // This code is for the Dragon auras - if (attachedTo.getController().isHuman()) { + if (attachedTo.getController().isHostileTo(ai)) { return false; } } @@ -1147,7 +1147,7 @@ public class ChangeZoneAi extends SpellAiLogic { 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() { @Override public boolean apply(final Card c) { @@ -1161,7 +1161,7 @@ public class ChangeZoneAi extends SpellAiLogic { } if (ZoneType.Exile.equals(destination) || origin.contains(ZoneType.Battlefield)) { // Exiling or bouncing stuff - if (player.isHuman()) { + if (player.isHostileTo(ai)) { c = CardFactoryUtil.getBestAI(fetchList); } else { c = CardFactoryUtil.getWorstAI(fetchList); diff --git a/src/main/java/forge/card/abilityfactory/ai/DamageDealAi.java b/src/main/java/forge/card/abilityfactory/ai/DamageDealAi.java index 8d3ef03605f..d63ae1203ff 100644 --- a/src/main/java/forge/card/abilityfactory/ai/DamageDealAi.java +++ b/src/main/java/forge/card/abilityfactory/ai/DamageDealAi.java @@ -155,7 +155,7 @@ public class DamageDealAi extends DamageAiBase { final List killables = CardLists.filter(hPlay, new Predicate() { @Override 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); } }); diff --git a/src/main/java/forge/card/abilityfactory/ai/DamagePreventAi.java b/src/main/java/forge/card/abilityfactory/ai/DamagePreventAi.java index da11ace1d2d..a1f2505b9fb 100644 --- a/src/main/java/forge/card/abilityfactory/ai/DamagePreventAi.java +++ b/src/main/java/forge/card/abilityfactory/ai/DamagePreventAi.java @@ -68,7 +68,7 @@ public class DamagePreventAi extends SpellAiLogic { for (final Object o : objects) { if (o instanceof Card) { final Card c = (Card) o; - flag |= ComputerUtilCombat.combatantWouldBeDestroyed(c); + flag |= ComputerUtilCombat.combatantWouldBeDestroyed(ai, c); } else if (o instanceof Player) { // Don't need to worry about Combat Damage during AI's turn final Player p = (Player) o; @@ -134,7 +134,7 @@ public class DamagePreventAi extends SpellAiLogic { CardLists.sortByEvaluateCreature(combatants); for (final Card c : combatants) { - if (ComputerUtilCombat.combatantWouldBeDestroyed(c)) { + if (ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) { tgt.addTarget(c); chance = true; break; @@ -195,7 +195,7 @@ public class DamagePreventAi extends SpellAiLogic { CardLists.sortByEvaluateCreature(combatants); if (Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { for (final Card c : combatants) { - if (ComputerUtilCombat.combatantWouldBeDestroyed(c)) { + if (ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) { tgt.addTarget(c); return true; } diff --git a/src/main/java/forge/card/abilityfactory/ai/DestroyAi.java b/src/main/java/forge/card/abilityfactory/ai/DestroyAi.java index 6e0c51f0f32..880397a8fb5 100644 --- a/src/main/java/forge/card/abilityfactory/ai/DestroyAi.java +++ b/src/main/java/forge/card/abilityfactory/ai/DestroyAi.java @@ -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) */ @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 // based on what the expected targets could be final Random r = MyRandom.getRandom(); @@ -105,7 +105,7 @@ public class DestroyAi extends SpellAiLogic { list = CardLists.filter(list, new Predicate() { @Override public boolean apply(final Card c) { - return ((c.getShield() == 0) && !ComputerUtil.canRegenerate(c)); + return ((c.getShield() == 0) && !ComputerUtil.canRegenerate(ai, c)); } }); } diff --git a/src/main/java/forge/card/abilityfactory/ai/LifeGainAi.java b/src/main/java/forge/card/abilityfactory/ai/LifeGainAi.java index 280d31ee1b1..0107eeeacf8 100644 --- a/src/main/java/forge/card/abilityfactory/ai/LifeGainAi.java +++ b/src/main/java/forge/card/abilityfactory/ai/LifeGainAi.java @@ -52,10 +52,10 @@ public class LifeGainAi extends SpellAiLogic { } // 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(); if (abSub != null && !sa.isWrapper() && "True".equals(source.getSVar("AIPlayForSub"))) { - if (!AbilityFactory.checkConditional(abSub)) { + if (!abSub.getConditions().areMet(abSub)) { return false; } } else { diff --git a/src/main/java/forge/card/abilityfactory/ai/MustBlockAi.java b/src/main/java/forge/card/abilityfactory/ai/MustBlockAi.java index 640d3d2f6e2..a4fcb326f2c 100644 --- a/src/main/java/forge/card/abilityfactory/ai/MustBlockAi.java +++ b/src/main/java/forge/card/abilityfactory/ai/MustBlockAi.java @@ -34,7 +34,7 @@ public class MustBlockAi extends SpellAiLogic { } @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 Target abTgt = sa.getTarget(); @@ -73,10 +73,10 @@ public class MustBlockAi extends SpellAiLogic { if (!CombatUtil.canBlock(definedAttacker, c)) { return false; } - if (ComputerUtilCombat.canDestroyAttacker(definedAttacker, c, null, false)) { + if (ComputerUtilCombat.canDestroyAttacker(ai, definedAttacker, c, null, false)) { return false; } - if (!ComputerUtilCombat.canDestroyBlocker(c, definedAttacker, null, false)) { + if (!ComputerUtilCombat.canDestroyBlocker(ai, c, definedAttacker, null, false)) { return false; } c.setTapped(tapped); diff --git a/src/main/java/forge/card/abilityfactory/ai/ProtectAi.java b/src/main/java/forge/card/abilityfactory/ai/ProtectAi.java index 13c4e626737..facfb5106c3 100644 --- a/src/main/java/forge/card/abilityfactory/ai/ProtectAi.java +++ b/src/main/java/forge/card/abilityfactory/ai/ProtectAi.java @@ -15,6 +15,7 @@ import forge.card.cardfactory.CardFactoryUtil; import forge.card.cost.Cost; import forge.card.spellability.SpellAbility; import forge.card.spellability.Target; +import forge.game.GameState; import forge.game.ai.ComputerUtilCombat; import forge.game.ai.ComputerUtilCost; import forge.game.phase.PhaseType; @@ -66,7 +67,8 @@ public class ProtectAi extends SpellAiLogic { */ private static List getProtectCreatures(final Player ai, final SpellAbility sa) { final ArrayList gains = AbilityFactory.getProtectionList(sa); - + final GameState game = Singletons.getModel().getGame(); + List list = ai.getCreaturesInPlay(); list = CardLists.filter(list, new Predicate() { @Override @@ -81,8 +83,8 @@ public class ProtectAi extends SpellAiLogic { } // will the creature attack (only relevant for sorcery speed)? - if (Singletons.getModel().getGame().getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) - && Singletons.getModel().getGame().getPhaseHandler().isPlayerTurn(ai) + if (game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) + && game.getPhaseHandler().isPlayerTurn(ai) && CardFactoryUtil.doesCreatureAttackAI(ai, c)) { return true; } @@ -90,14 +92,14 @@ public class ProtectAi extends SpellAiLogic { // is the creature blocking and unable to destroy the attacker // or would be destroyed itself? if (c.isBlocking() - && (ComputerUtilCombat.blockerWouldBeDestroyed(c))) { + && (ComputerUtilCombat.blockerWouldBeDestroyed(ai, c))) { return true; } // is the creature in blocked and the blocker would survive - if (Singletons.getModel().getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS) - && Singletons.getModel().getGame().getCombat().isAttacking(c) && Singletons.getModel().getGame().getCombat().isBlocked(c) - && ComputerUtilCombat.blockerWouldBeDestroyed(Singletons.getModel().getGame().getCombat().getBlockers(c).get(0))) { + if (game.getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS) + && game.getCombat().isAttacking(c) && game.getCombat().isBlocked(c) + && ComputerUtilCombat.blockerWouldBeDestroyed(ai, game.getCombat().getBlockers(c).get(0))) { return true; } diff --git a/src/main/java/forge/card/abilityfactory/ai/PumpAiBase.java b/src/main/java/forge/card/abilityfactory/ai/PumpAiBase.java index 3d25ba6bd76..767708f9c5e 100644 --- a/src/main/java/forge/card/abilityfactory/ai/PumpAiBase.java +++ b/src/main/java/forge/card/abilityfactory/ai/PumpAiBase.java @@ -16,6 +16,7 @@ import forge.card.abilityfactory.AbilityFactory; import forge.card.abilityfactory.SpellAiLogic; import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.SpellAbility; +import forge.game.GameState; import forge.game.ai.ComputerUtilCombat; import forge.game.phase.Combat; import forge.game.phase.CombatUtil; @@ -223,7 +224,7 @@ public abstract class PumpAiBase extends SpellAiLogic { List attackers = combat.getAttackers(); for (Card attacker : attackers) { if (CombatUtil.canBlock(attacker, card, combat) - && !ComputerUtilCombat.canDestroyAttacker(attacker, card, combat, false)) { + && !ComputerUtilCombat.canDestroyAttacker(ai, attacker, card, combat, false)) { return true; } } @@ -232,7 +233,7 @@ public abstract class PumpAiBase extends SpellAiLogic { List blockers = opp.getCreaturesInPlay(); for (Card blocker : blockers) { if (CombatUtil.canBlock(card, blocker, combat) - && !ComputerUtilCombat.canDestroyBlocker(blocker, card, combat, false)) { + && !ComputerUtilCombat.canDestroyBlocker(ai, blocker, card, combat, false)) { 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, final List keywords) { - PhaseHandler phase = Singletons.getModel().getGame().getPhaseHandler(); + final GameState game = Singletons.getModel().getGame(); + PhaseHandler phase = game.getPhaseHandler(); if (!c.canBeTargetedBy(sa)) { return false; @@ -408,36 +410,35 @@ public abstract class PumpAiBase extends SpellAiLogic { // is the creature blocking and unable to destroy the attacker // or would be destroyed itself? 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; } List blockedBy = Singletons.getModel().getGame().getCombat().getAttackersBlockedBy(c); // For now, Only care the first creature blocked by a card. // 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; } } // is the creature unblocked and the spell will pump its power? if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) - && Singletons.getModel().getGame().getCombat().isAttacking(c) - && Singletons.getModel().getGame().getCombat().isUnblocked(c) && attack > 0) { + && game.getCombat().isAttacking(c) && game.getCombat().isUnblocked(c) && attack > 0) { return true; } // is the creature blocked and the blocker would survive if (phase.is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) && attack > 0 - && Singletons.getModel().getGame().getCombat().isAttacking(c) - && Singletons.getModel().getGame().getCombat().isBlocked(c) - && Singletons.getModel().getGame().getCombat().getBlockers(c) != null - && !Singletons.getModel().getGame().getCombat().getBlockers(c).isEmpty() - && !ComputerUtilCombat.blockerWouldBeDestroyed(Singletons.getModel().getGame().getCombat().getBlockers(c).get(0))) { + && game.getCombat().isAttacking(c) + && game.getCombat().isBlocked(c) + && game.getCombat().getBlockers(c) != null + && !game.getCombat().getBlockers(c).isEmpty() + && !ComputerUtilCombat.blockerWouldBeDestroyed(ai, game.getCombat().getBlockers(c).get(0))) { return true; } // if the life of the computer is in danger, try to pump blockers blocking Tramplers - List blockedBy = Singletons.getModel().getGame().getCombat().getAttackersBlockedBy(c); + List blockedBy = game.getCombat().getAttackersBlockedBy(c); boolean attackerHasTrample = false; for (Card b : blockedBy) { attackerHasTrample |= b.hasKeyword("Trample"); @@ -448,7 +449,7 @@ public abstract class PumpAiBase extends SpellAiLogic { && c.isBlocking() && defense > 0 && attackerHasTrample - && (sa.isAbility() || ComputerUtilCombat.lifeInDanger(ai, Singletons.getModel().getGame().getCombat()))) { + && (sa.isAbility() || ComputerUtilCombat.lifeInDanger(ai, game.getCombat()))) { return true; } diff --git a/src/main/java/forge/card/abilityfactory/ai/RegenerateAi.java b/src/main/java/forge/card/abilityfactory/ai/RegenerateAi.java index 93c8160b78b..139aafccb8f 100644 --- a/src/main/java/forge/card/abilityfactory/ai/RegenerateAi.java +++ b/src/main/java/forge/card/abilityfactory/ai/RegenerateAi.java @@ -95,7 +95,7 @@ public class RegenerateAi extends SpellAiLogic { for (final Card c : list) { 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); for (final Card c : combatants) { - if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(c)) { + if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) { tgt.addTarget(c); chance = true; break; @@ -190,7 +190,7 @@ public class RegenerateAi extends SpellAiLogic { CardLists.sortByEvaluateCreature(combatants); if (Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { for (final Card c : combatants) { - if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(c)) { + if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) { tgt.addTarget(c); return true; } diff --git a/src/main/java/forge/card/abilityfactory/ai/RegenerateAllAi.java b/src/main/java/forge/card/abilityfactory/ai/RegenerateAllAi.java index 4a9a9e906eb..45e7b04176c 100644 --- a/src/main/java/forge/card/abilityfactory/ai/RegenerateAllAi.java +++ b/src/main/java/forge/card/abilityfactory/ai/RegenerateAllAi.java @@ -68,7 +68,7 @@ public class RegenerateAllAi extends SpellAiLogic { final List combatants = CardLists.filter(list, CardPredicates.Presets.CREATURES); for (final Card c : combatants) { - if (c.getShield() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(c)) { + if (c.getShield() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c)) { numSaved++; } } diff --git a/src/main/java/forge/card/abilityfactory/effects/ChooseTypeEffect.java b/src/main/java/forge/card/abilityfactory/effects/ChooseTypeEffect.java index 5cf335ed891..0598ad5af9a 100644 --- a/src/main/java/forge/card/abilityfactory/effects/ChooseTypeEffect.java +++ b/src/main/java/forge/card/abilityfactory/effects/ChooseTypeEffect.java @@ -124,6 +124,7 @@ public class ChooseTypeEffect extends SpellEffect { GuiChoose.one("Computer picked: ", new String[]{chosen}); chosenType = chosen; } + if (CardUtil.isACreatureType(chosenType) && !invalidTypes.contains(chosenType)) { valid = true; card.setChosenType(chosenType); diff --git a/src/main/java/forge/card/spellability/SpellAbilityCondition.java b/src/main/java/forge/card/spellability/SpellAbilityCondition.java index 5ee97898496..fa6a5c80312 100644 --- a/src/main/java/forge/card/spellability/SpellAbilityCondition.java +++ b/src/main/java/forge/card/spellability/SpellAbilityCondition.java @@ -166,7 +166,7 @@ public class SpellAbilityCondition extends SpellAbilityVariables { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - public final boolean checkConditions(final SpellAbility sa) { + public final boolean areMet(final SpellAbility sa) { Player activator = sa.getActivatingPlayer(); if (activator == null) { diff --git a/src/main/java/forge/game/ai/AiAttackController.java b/src/main/java/forge/game/ai/AiAttackController.java index 91c8ea9a80d..9c07fdc7826 100644 --- a/src/main/java/forge/game/ai/AiAttackController.java +++ b/src/main/java/forge/game/ai/AiAttackController.java @@ -901,7 +901,7 @@ public class AiAttackController { if ((isWorthLessThanAllKillers || canKillAllDangerous || numberOfPossibleBlockers < 2) && CombatUtil.canBlock(attacker, defender)) { 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)) { canBeKilledByOne = true; // there is a single creature on // the battlefield that can kill @@ -915,7 +915,7 @@ public class AiAttackController { } // see if this attacking creature can destroy this defender, if // 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; if (!canKillAllDangerous) { continue; diff --git a/src/main/java/forge/game/ai/ComputerUtil.java b/src/main/java/forge/game/ai/ComputerUtil.java index 3a3806caf8b..df1d13cab8e 100644 --- a/src/main/java/forge/game/ai/ComputerUtil.java +++ b/src/main/java/forge/game/ai/ComputerUtil.java @@ -415,7 +415,7 @@ public class ComputerUtil { 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 } @@ -473,7 +473,7 @@ public class ComputerUtil { } else { 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 } @@ -588,7 +588,7 @@ public class ComputerUtil { public static List chooseReturnType(final Player ai, final String type, final Card activate, final Card target, final int amount) { final List typeList = 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 typeList.remove(target); } @@ -709,12 +709,13 @@ public class ComputerUtil { *

* canRegenerate. *

+ * @param ai * * @param card * a {@link forge.Card} object. * @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.")) { return false; @@ -736,7 +737,7 @@ public class ComputerUtil { continue; // Can't play ability } - if (controller.isComputer()) { + if (controller == ai) { final Cost abCost = sa.getPayCosts(); if (abCost != null) { // AI currently disabled for these costs diff --git a/src/main/java/forge/game/ai/ComputerUtilBlock.java b/src/main/java/forge/game/ai/ComputerUtilBlock.java index a5e5183fa19..b7ba67f67a6 100644 --- a/src/main/java/forge/game/ai/ComputerUtilBlock.java +++ b/src/main/java/forge/game/ai/ComputerUtilBlock.java @@ -229,11 +229,11 @@ public class ComputerUtilBlock { * a {@link forge.game.phase.Combat} object. * @return a {@link forge.CardList} object. */ - private static List getSafeBlockers(final Card attacker, final List blockersLeft, final Combat combat) { + private static List getSafeBlockers(final Player ai, final Card attacker, final List blockersLeft, final Combat combat) { final List blockers = new ArrayList(); for (final Card b : blockersLeft) { - if (!ComputerUtilCombat.canDestroyBlocker(b, attacker, combat, false)) { + if (!ComputerUtilCombat.canDestroyBlocker(ai, b, attacker, combat, false)) { blockers.add(b); } } @@ -255,11 +255,11 @@ public class ComputerUtilBlock { * a {@link forge.game.phase.Combat} object. * @return a {@link forge.CardList} object. */ - private static List getKillingBlockers(final Card attacker, final List blockersLeft, final Combat combat) { + private static List getKillingBlockers(final Player ai, final Card attacker, final List blockersLeft, final Combat combat) { final List blockers = new ArrayList(); for (final Card b : blockersLeft) { - if (ComputerUtilCombat.canDestroyAttacker(attacker, b, combat, false)) { + if (ComputerUtilCombat.canDestroyAttacker(ai, attacker, b, combat, false)) { blockers.add(b); } } @@ -337,7 +337,7 @@ public class ComputerUtilBlock { * 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 currentAttackers = new ArrayList(ComputerUtilBlock.getAttackersLeft()); @@ -352,13 +352,13 @@ public class ComputerUtilBlock { final List blockers = ComputerUtilBlock.getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true); - final List safeBlockers = ComputerUtilBlock.getSafeBlockers(attacker, blockers, combat); + final List safeBlockers = ComputerUtilBlock.getSafeBlockers(ai, attacker, blockers, combat); List killingBlockers; if (safeBlockers.size() > 0) { // 1.Blockers that can destroy the attacker but won't get // destroyed - killingBlockers = ComputerUtilBlock.getKillingBlockers(attacker, safeBlockers, combat); + killingBlockers = ComputerUtilBlock.getKillingBlockers(ai, attacker, safeBlockers, combat); if (killingBlockers.size() > 0) { blocker = CardFactoryUtil.getWorstCreatureAI(killingBlockers); } 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 else { // 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) { if ((b.hasKeyword("Undying") && b.getCounters(CounterType.P1P1) == 0) || !b.getSVar("SacMe").equals("")) { @@ -542,7 +542,7 @@ public class ComputerUtilBlock { continue; } - killingBlockers = ComputerUtilBlock.getKillingBlockers(attacker, + killingBlockers = ComputerUtilBlock.getKillingBlockers(ai, attacker, ComputerUtilBlock.getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true), combat); if ((killingBlockers.size() > 0) && ComputerUtilCombat.lifeInDanger(ai, combat)) { @@ -648,7 +648,7 @@ public class ComputerUtilBlock { * 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 safeBlockers; List blockers; @@ -664,7 +664,7 @@ public class ComputerUtilBlock { blockers.removeAll(combat.getBlockers(attacker)); // Try to use safe blockers first - safeBlockers = ComputerUtilBlock.getSafeBlockers(attacker, blockers, combat); + safeBlockers = ComputerUtilBlock.getSafeBlockers(ai, attacker, blockers, combat); for (final Card blocker : safeBlockers) { final int damageNeeded = attacker.getKillDamage() + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, false); @@ -808,7 +808,7 @@ public class ComputerUtilBlock { CardLists.sortAttackLowFirst(ComputerUtilBlock.getBlockersLeft()); // == 1. choose best blocks first == - combat = ComputerUtilBlock.makeGoodBlocks(combat); + combat = ComputerUtilBlock.makeGoodBlocks(ai, combat); combat = ComputerUtilBlock.makeGangBlocks(ai, combat); if (ComputerUtilCombat.lifeInDanger(ai, combat)) { combat = ComputerUtilBlock.makeTradeBlocks(ai, combat); // choose @@ -830,7 +830,7 @@ public class ComputerUtilBlock { // Support blockers not destroying the attacker with more blockers to // try to kill the attacker 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 @@ -845,7 +845,7 @@ public class ComputerUtilBlock { // necessary // trade blocks // if life is in danger - combat = ComputerUtilBlock.makeGoodBlocks(combat); + combat = ComputerUtilBlock.makeGoodBlocks(ai, combat); if (ComputerUtilCombat.lifeInDanger(ai, combat)) { combat = ComputerUtilBlock.makeChumpBlocks(ai, combat); // choose // necessary @@ -859,7 +859,7 @@ public class ComputerUtilBlock { combat = ComputerUtilBlock.reinforceBlockersAgainstTrample(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 @@ -878,7 +878,7 @@ public class ComputerUtilBlock { } if (!ComputerUtilCombat.lifeInDanger(ai, combat)) { - combat = ComputerUtilBlock.makeGoodBlocks(combat); + combat = ComputerUtilBlock.makeGoodBlocks(ai, combat); } // Reinforce blockers blocking attackers with trample if life is // still in danger @@ -888,7 +888,7 @@ public class ComputerUtilBlock { combat = ComputerUtilBlock.makeGangBlocks(ai, combat); // Support blockers not destroying the attacker with more blockers // to try to kill the attacker - combat = ComputerUtilBlock.reinforceBlockersToKill(combat); + combat = ComputerUtilBlock.reinforceBlockersToKill(ai, combat); } // assign blockers that have to block diff --git a/src/main/java/forge/game/ai/ComputerUtilCombat.java b/src/main/java/forge/game/ai/ComputerUtilCombat.java index d8182736aea..72f3ff3e1b1 100644 --- a/src/main/java/forge/game/ai/ComputerUtilCombat.java +++ b/src/main/java/forge/game/ai/ComputerUtilCombat.java @@ -517,18 +517,19 @@ public class ComputerUtilCombat { *

* combatantWouldBeDestroyed. *

+ * @param ai * * @param combatant * a {@link forge.Card} object. * @return a boolean. */ - public static boolean combatantWouldBeDestroyed(final Card combatant) { + public static boolean combatantWouldBeDestroyed(Player ai, final Card combatant) { if (combatant.isAttacking()) { - return ComputerUtilCombat.attackerWouldBeDestroyed(combatant); + return ComputerUtilCombat.attackerWouldBeDestroyed(ai, combatant); } if (combatant.isBlocking()) { - return ComputerUtilCombat.blockerWouldBeDestroyed(combatant); + return ComputerUtilCombat.blockerWouldBeDestroyed(ai, combatant); } return false; } @@ -538,16 +539,17 @@ public class ComputerUtilCombat { *

* attackerWouldBeDestroyed. *

+ * @param ai * * @param attacker * a {@link forge.Card} object. * @return a boolean. */ - public static boolean attackerWouldBeDestroyed(final Card attacker) { + public static boolean attackerWouldBeDestroyed(Player ai, final Card attacker) { final List blockers = Singletons.getModel().getGame().getCombat().getBlockers(attacker); 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"))) { return true; } @@ -1343,6 +1345,7 @@ public class ComputerUtilCombat { *

* canDestroyAttacker. *

+ * @param ai * * @param attacker * a {@link forge.Card} object. @@ -1354,7 +1357,7 @@ public class ComputerUtilCombat { * 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) { if (attacker.getName().equals("Sylvan Basilisk") && !defender.hasKeyword("Indestructible")) { @@ -1375,7 +1378,7 @@ public class ComputerUtilCombat { } } // 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"))) || (attacker.hasKeyword("Persist") && !attacker.canHaveCountersPlacedOnIt(CounterType.M1M1) && (attacker .getCounters(CounterType.M1M1) == 0)) @@ -1471,18 +1474,19 @@ public class ComputerUtilCombat { *

* blockerWouldBeDestroyed. *

+ * @param ai * * @param blocker * a {@link forge.Card} object. * @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 // This needs to expand to tally up damage final List attackers = Singletons.getModel().getGame().getCombat().getAttackersBlockedBy(blocker); 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"))) { return true; } @@ -1495,6 +1499,7 @@ public class ComputerUtilCombat { *

* canDestroyBlocker. *

+ * @param ai * * @param defender * a {@link forge.Card} object. @@ -1506,7 +1511,7 @@ public class ComputerUtilCombat { * 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) { int flankingMagnitude = 0; @@ -1522,7 +1527,7 @@ public class ComputerUtilCombat { } } // 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"))) || (defender.hasKeyword("Persist") && !defender.canHaveCountersPlacedOnIt(CounterType.M1M1) && (defender .getCounters(CounterType.M1M1) == 0))