From b39d9b93279bd9ee2d0597871a8f20cd614d9b4a Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Sun, 7 Oct 2012 20:58:06 +0000 Subject: [PATCH] Another portion of removal of global getters getXXXPlayer --- src/main/java/forge/Card.java | 13 +- src/main/java/forge/CardDamageHistory.java | 159 +++------------ src/main/java/forge/CardPredicates.java | 13 +- src/main/java/forge/CardUtil.java | 8 +- src/main/java/forge/GameActionUtil.java | 26 +-- .../AbilityFactoryAlterLife.java | 14 +- .../AbilityFactoryChangeZone.java | 28 +-- .../abilityfactory/AbilityFactoryChoose.java | 36 ++-- .../AbilityFactoryCounterMagic.java | 2 +- .../AbilityFactoryCounters.java | 20 +- .../AbilityFactoryDealDamage.java | 2 +- .../abilityfactory/AbilityFactoryDebuff.java | 2 +- .../abilityfactory/AbilityFactoryDestroy.java | 4 +- .../abilityfactory/AbilityFactoryEffect.java | 18 +- .../abilityfactory/AbilityFactoryMana.java | 19 +- .../AbilityFactoryPermanentState.java | 60 ++---- .../abilityfactory/AbilityFactoryPlay.java | 24 +-- .../AbilityFactoryPreventDamage.java | 46 ++--- .../AbilityFactoryProtection.java | 66 +++--- .../abilityfactory/AbilityFactoryPump.java | 183 ++++++++--------- .../AbilityFactoryRegenerate.java | 34 ++-- .../abilityfactory/AbilityFactoryReveal.java | 8 +- .../abilityfactory/AbilityFactoryToken.java | 4 +- .../abilityfactory/AbilityFactoryTurns.java | 31 +-- .../AbilityFactoryZoneAffecting.java | 22 +- .../forge/card/cardfactory/CardFactory.java | 4 +- .../cardfactory/CardFactorySorceries.java | 4 +- src/main/java/forge/card/cost/CostDamage.java | 2 +- .../java/forge/card/cost/CostDiscard.java | 12 +- src/main/java/forge/card/cost/CostExile.java | 4 +- .../java/forge/card/cost/CostGainLife.java | 6 +- src/main/java/forge/card/cost/CostMana.java | 2 +- src/main/java/forge/card/cost/CostMill.java | 5 +- src/main/java/forge/card/cost/CostPart.java | 2 +- .../java/forge/card/cost/CostPayLife.java | 5 +- .../java/forge/card/cost/CostPayment.java | 7 +- .../java/forge/card/cost/CostPutCounter.java | 5 +- .../forge/card/cost/CostRemoveCounter.java | 8 +- src/main/java/forge/card/cost/CostReturn.java | 2 +- src/main/java/forge/card/cost/CostReveal.java | 11 +- .../java/forge/card/cost/CostSacrifice.java | 4 +- src/main/java/forge/card/cost/CostTap.java | 2 +- .../java/forge/card/cost/CostTapType.java | 4 +- src/main/java/forge/card/cost/CostUntap.java | 2 +- .../java/forge/card/cost/CostUntapType.java | 4 +- src/main/java/forge/card/cost/CostUtil.java | 24 +-- .../card/spellability/SpellPermanent.java | 13 +- .../java/forge/game/phase/CombatUtil.java | 2 +- .../java/forge/game/phase/PhaseHandler.java | 5 +- src/main/java/forge/game/phase/Upkeep.java | 4 +- src/main/java/forge/game/player/AIPlayer.java | 2 +- .../forge/game/player/ComputerAIGeneral.java | 63 +++--- .../java/forge/game/player/ComputerUtil.java | 192 +++++++----------- src/main/java/forge/game/player/Player.java | 5 +- .../gauntlet/CSubmenuGauntletContests.java | 13 +- .../home/gauntlet/CSubmenuGauntletLoad.java | 15 +- src/main/java/forge/model/FModel.java | 7 +- 57 files changed, 557 insertions(+), 725 deletions(-) diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index 4e63f071795..7ceec439455 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -1362,7 +1362,7 @@ public class Card extends GameEntity implements Comparable { continue; } } - ComputerUtil.playSpellAbilityWithoutPayingManaCost(sa); + ComputerUtil.playSpellAbilityWithoutPayingManaCost(c.getOwner(), sa); break; } } @@ -6920,20 +6920,15 @@ public class Card extends GameEntity implements Comparable { return false; } } else if (property.startsWith("dealtDamageToYouThisTurn")) { - if (!(this.getDamageHistory().getDealtDmgToHumanThisTurn() && sourceController.isHuman()) - && !(this.getDamageHistory().getDealtDmgToComputerThisTurn() && sourceController.isComputer())) { + if ( !this.getDamageHistory().getThisTurnDamaged().contains(sourceController) ) { return false; } } else if (property.startsWith("controllerWasDealtCombatDamageByThisTurn")) { - if (!(source.getDamageHistory().getDealtCombatDmgToHumanThisTurn() && this.getController().equals(AllZone.getHumanPlayer())) - && !(source.getDamageHistory().getDealtCombatDmgToComputerThisTurn() && this.getController().equals( - AllZone.getComputerPlayer()))) { + if ( !this.getDamageHistory().getThisTurnCombatDamaged().contains(sourceController) ) { return false; } } else if (property.startsWith("controllerWasDealtDamageByThisTurn")) { - if (!(source.getDamageHistory().getDealtDmgToHumanThisTurn() && this.getController().equals(AllZone.getHumanPlayer())) - && !(source.getDamageHistory().getDealtDmgToComputerThisTurn() && this.getController() - .equals(AllZone.getComputerPlayer()))) { + if ( !this.getDamageHistory().getThisTurnDamaged().contains(sourceController) ) { return false; } } else if (property.startsWith("wasDealtDamageThisTurn")) { diff --git a/src/main/java/forge/CardDamageHistory.java b/src/main/java/forge/CardDamageHistory.java index 817fdd30710..93f6e0958e2 100644 --- a/src/main/java/forge/CardDamageHistory.java +++ b/src/main/java/forge/CardDamageHistory.java @@ -1,5 +1,10 @@ package forge; +import java.util.ArrayList; +import java.util.List; + +import forge.game.player.Player; + /** * TODO: Write javadoc for this type. * @@ -14,12 +19,10 @@ public class CardDamageHistory { private boolean creatureBlockedThisTurn = false; private boolean creatureGotBlockedThisCombat = false; private boolean creatureGotBlockedThisTurn = false; - private boolean dealtDmgToHumanThisTurn = false; - private boolean dealtDmgToComputerThisTurn = false; - private boolean dealtDmgToHumanThisGame = false; - private boolean dealtDmgToComputerThisGame = false; - private boolean dealtCombatDmgToHumanThisTurn = false; - private boolean dealtCombatDmgToComputerThisTurn = false; + + private final List thisTurnDamaged = new ArrayList(2); + private final List thisTurnCombatDamaged = new ArrayList(2); + private final List thisGameDamaged = new ArrayList(2); // used to see if an attacking creature with a triggering attack ability // triggered this phase: /** @@ -200,137 +203,37 @@ public class CardDamageHistory { public final boolean getCreatureGotBlockedThisTurn() { return this.creatureGotBlockedThisTurn; } - /** - *

- * Setter for the field dealtDmgToHumanThisTurn. - *

- * - * @param b - * a boolean. - */ - public final void setDealtDmgToHumanThisTurn(final boolean b) { - this.dealtDmgToHumanThisTurn = b; - if (b) { - this.setDealtDmgToHumanThisGame(true); - } + public final List getThisTurnDamaged() { + return thisTurnDamaged; + } + public final List getThisTurnCombatDamaged() { + return thisTurnCombatDamaged; + } + public final List getThisGameDamaged() { + return thisGameDamaged; } /** - *

- * Getter for the field dealtDmgToHumanThisTurn. - *

- * - * @return a boolean. + * TODO: Write javadoc for this method. + * @param player */ - public final boolean getDealtDmgToHumanThisTurn() { - return this.dealtDmgToHumanThisTurn; + public void registerCombatDamage(Player player) { + if ( !thisTurnCombatDamaged.contains(player) ) + thisTurnCombatDamaged.add(player); } /** - *

- * Setter for the field dealtDmgToComputerThisTurn. - *

- * - * @param b - * a boolean. + * TODO: Write javadoc for this method. */ - public final void setDealtDmgToComputerThisTurn(final boolean b) { - this.dealtDmgToComputerThisTurn = b; - if (b) { - this.setDealtDmgToComputerThisGame(true); - } + public void newTurn() { + thisTurnCombatDamaged.clear(); + thisTurnDamaged.clear(); } /** - *

- * Getter for the field dealtCombatDmgToComputerThisGame. - *

- * - * @return a boolean. + * TODO: Write javadoc for this method. + * @param player */ - public final boolean getDealtDmgToComputerThisTurn() { - return this.dealtDmgToComputerThisTurn; - } - /** - *

- * Setter for the field dealtDmgToHumanThisGame. - *

- * - * @param b - * a boolean. - */ - public final void setDealtDmgToHumanThisGame(final boolean b) { - this.dealtDmgToHumanThisGame = b; - } - /** - *

- * Getter for the field dealtDmgToHumanThisGame. - *

- * - * @return a boolean. - */ - public final boolean getDealtDmgToHumanThisGame() { - return this.dealtDmgToHumanThisGame; - } - /** - *

- * Setter for the field dealtDmgToComputerThisGame. - *

- * - * @param b - * a boolean. - */ - public final void setDealtDmgToComputerThisGame(final boolean b) { - this.dealtDmgToComputerThisGame = b; - } - /** - *

- * Getter for the field dealtCombatDmgToComputerThisGame. - *

- * - * @return a boolean. - */ - public final boolean getDealtDmgToComputerThisGame() { - return this.dealtDmgToComputerThisGame; - } - /** - *

- * Setter for the field dealtCombatDmgToHumanThisTurn. - *

- * - * @param b - * a boolean. - */ - public final void setDealtCombatDmgToHumanThisTurn(final boolean b) { - this.dealtCombatDmgToHumanThisTurn = b; - } - /** - *

- * Getter for the field dealtDmgToHumanThisTurn. - *

- * - * @return a boolean. - */ - public final boolean getDealtCombatDmgToHumanThisTurn() { - return this.dealtCombatDmgToHumanThisTurn; - } - /** - *

- * Setter for the field dealtCombatDmgToComputerThisTurn. - *

- * - * @param b - * a boolean. - */ - public final void setDealtCombatDmgToComputerThisTurn(final boolean b) { - this.dealtCombatDmgToComputerThisTurn = b; - } - /** - *

- * Getter for the field dealtDmgToComputerThisTurn. - *

- * - * @return a boolean. - */ - public final boolean getDealtCombatDmgToComputerThisTurn() { - return this.dealtCombatDmgToComputerThisTurn; + public void registerDamage(Player player) { + if ( !thisTurnDamaged.contains(player) ) + thisTurnDamaged.add(player); } } diff --git a/src/main/java/forge/CardPredicates.java b/src/main/java/forge/CardPredicates.java index 8865418b3de..dd14deb1950 100644 --- a/src/main/java/forge/CardPredicates.java +++ b/src/main/java/forge/CardPredicates.java @@ -106,11 +106,20 @@ public final class CardPredicates { return new Predicate() { @Override public boolean apply(final Card c) { - return (c.isCreature() && CombatUtil.canBlock(attacker, c)); + return c.isCreature() && CombatUtil.canBlock(attacker, c); } }; } + public final static Predicate possibleBlockerForAtLeastOne(final Iterable attackers) { + return new Predicate() { + @Override + public boolean apply(final Card c) { + return c.isCreature() && CombatUtil.canBlockAtLeastOne(c, attackers); + } + }; + } + public static final Predicate possibleAttackers = new Predicate() { @Override public boolean apply(final Card c) { @@ -181,7 +190,7 @@ public final class CardPredicates { return c.isCreature() && CombatUtil.canAttack(c); } }; - + /** * a Predicate to get all enchantments. */ diff --git a/src/main/java/forge/CardUtil.java b/src/main/java/forge/CardUtil.java index 70dd6465bbd..d6d90f6ba62 100644 --- a/src/main/java/forge/CardUtil.java +++ b/src/main/java/forge/CardUtil.java @@ -38,7 +38,7 @@ import forge.card.CardManaCost; import forge.card.EditionInfo; import forge.card.mana.ManaCost; import forge.control.input.InputPayManaCostUtil; -import forge.game.zone.PlayerZone; +import forge.game.player.Player; import forge.game.zone.ZoneType; import forge.gui.GuiDisplayUtil; import forge.item.CardPrinted; @@ -627,10 +627,10 @@ public final class CardUtil { final Card src) { List res = new ArrayList(); if (to != ZoneType.Stack) { - res.addAll(((PlayerZone) AllZone.getComputerPlayer().getZone(to)).getCardsAddedThisTurn(from)); - res.addAll(((PlayerZone) AllZone.getHumanPlayer().getZone(to)).getCardsAddedThisTurn(from)); + for (Player p : AllZone.getPlayersInGame()) + res.addAll(p.getZone(to).getCardsAddedThisTurn(from)); } else { - res.addAll(((PlayerZone) AllZone.getStackZone()).getCardsAddedThisTurn(from)); + res.addAll(AllZone.getStackZone().getCardsAddedThisTurn(from)); } res = CardLists.getValidCards(res, valid, src.getController(), src); diff --git a/src/main/java/forge/GameActionUtil.java b/src/main/java/forge/GameActionUtil.java index 70b02d040d5..93c693bb5d7 100644 --- a/src/main/java/forge/GameActionUtil.java +++ b/src/main/java/forge/GameActionUtil.java @@ -158,8 +158,9 @@ public final class GameActionUtil { GuiChoose.oneOrNone("Revealed cards:", revealed); if (cascadedCard != null) { + Player p = cascadedCard.getController(); - if (cascadedCard.getController().isHuman()) { + if (p.isHuman()) { final StringBuilder title = new StringBuilder(); title.append(cascCard.getName()).append(" - Cascade Ability"); final StringBuilder question = new StringBuilder(); @@ -188,7 +189,7 @@ public final class GameActionUtil { continue; } } - ComputerUtil.playSpellAbilityWithoutPayingManaCost(sa); + ComputerUtil.playSpellAbilityWithoutPayingManaCost(p, sa); revealed.remove(cascadedCard); break; } @@ -290,8 +291,9 @@ public final class GameActionUtil { GuiChoose.oneOrNone("Revealed cards:", revealed); for (int i = 0; i < rippleMax; i++) { if (rippledCards[i] != null) { + Player p = rippledCards[i].getController(); - if (rippledCards[i].getController().isHuman()) { + if (p.isHuman()) { final Object[] possibleValues = { "Yes", "No" }; final Object q = JOptionPane.showOptionDialog(null, "Cast " + rippledCards[i].getName() + "?", "Ripple", @@ -316,7 +318,7 @@ public final class GameActionUtil { continue; } } - ComputerUtil.playSpellAbilityWithoutPayingManaCost(sa); + ComputerUtil.playSpellAbilityWithoutPayingManaCost(p, sa); revealed.remove(rippledCards[i]); break; } @@ -887,13 +889,8 @@ public final class GameActionUtil { if (c.getName().equals("Whirling Dervish") || c.getName().equals("Dunerider Outlaw")) { GameActionUtil.playerCombatDamageWhirlingDervish(c); } - - if (player.equals(AllZone.getHumanPlayer())) { - c.getDamageHistory().setDealtDmgToHumanThisTurn(true); - } - if (player.equals(AllZone.getComputerPlayer())) { - c.getDamageHistory().setDealtDmgToComputerThisTurn(true); - } + + c.getDamageHistory().registerDamage(player); } // restricted to combat damage, restricted to players @@ -978,12 +975,7 @@ public final class GameActionUtil { GameActionUtil.executeCelestialMantle(c); } - if (player.equals(AllZone.getHumanPlayer())) { - c.getDamageHistory().setDealtCombatDmgToHumanThisTurn(true); - } - if (player.equals(AllZone.getComputerPlayer())) { - c.getDamageHistory().setDealtCombatDmgToComputerThisTurn(true); - } + c.getDamageHistory().registerCombatDamage(player); } // executeCombatDamageToPlayerEffects /** diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryAlterLife.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryAlterLife.java index d7d28f95c12..41f03200f95 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryAlterLife.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryAlterLife.java @@ -334,7 +334,7 @@ public class AbilityFactoryAlterLife { && CombatUtil.lifeInDanger(AllZone.getCombat())); if (abCost != null && !lifeCritical) { - if (!CostUtil.checkSacrificeCost(abCost, source, false)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, source, false)) { return false; } @@ -342,7 +342,7 @@ public class AbilityFactoryAlterLife { return false; } - if (!CostUtil.checkDiscardCost(abCost, source)) { + if (!CostUtil.checkDiscardCost(ai, abCost, source)) { return false; } @@ -760,11 +760,11 @@ public class AbilityFactoryAlterLife { return false; } - if (!CostUtil.checkDiscardCost(abCost, source)) { + if (!CostUtil.checkDiscardCost(ai, abCost, source)) { return false; } - if (!CostUtil.checkSacrificeCost(abCost, source)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, source)) { return false; } @@ -1242,7 +1242,7 @@ public class AbilityFactoryAlterLife { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private static boolean poisonCanPlayAI(final Player aiPlayer, final AbilityFactory af, final SpellAbility sa) { + private static boolean poisonCanPlayAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { final Cost abCost = sa.getPayCosts(); final Card source = sa.getSourceCard(); final HashMap params = af.getMapParams(); @@ -1261,7 +1261,7 @@ public class AbilityFactoryAlterLife { return false; } - if (!CostUtil.checkSacrificeCost(abCost, source)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, source)) { return false; } } @@ -1280,7 +1280,7 @@ public class AbilityFactoryAlterLife { if (sa.getTarget() != null) { tgt.resetTargets(); - sa.getTarget().addTarget(aiPlayer.getOpponent()); + sa.getTarget().addTarget(ai.getOpponent()); } return true; diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java index 5f33d3ac1a3..3a6e94c898b 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java @@ -491,7 +491,7 @@ public final class AbilityFactoryChangeZone { if (abCost != null) { // AI currently disabled for these costs - if (!CostUtil.checkSacrificeCost(abCost, source) + if (!CostUtil.checkSacrificeCost(ai, abCost, source) && !(destination.equals("Battlefield") && !source.isLand())) { return false; } @@ -500,12 +500,12 @@ public final class AbilityFactoryChangeZone { return false; } - if (!CostUtil.checkDiscardCost(abCost, source)) { + if (!CostUtil.checkDiscardCost(ai, abCost, source)) { for (final CostPart part : abCost.getCostParts()) { if (part instanceof CostDiscard) { CostDiscard cd = (CostDiscard) part; // this is mainly for typecycling - if (!cd.getThis() || !ComputerUtil.isWorseThanDraw(source)) { + if (!cd.getThis() || !ComputerUtil.isWorseThanDraw(ai, source)) { return false; } } @@ -1491,7 +1491,7 @@ public final class AbilityFactoryChangeZone { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private static boolean changeKnownOriginCanPlayAI(final Player aiPlayer, final AbilityFactory af, final SpellAbility sa) { + private static boolean changeKnownOriginCanPlayAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { // Retrieve either this card, or target Cards in Graveyard final Cost abCost = af.getAbCost(); final Card source = sa.getSourceCard(); @@ -1504,7 +1504,7 @@ public final class AbilityFactoryChangeZone { if (abCost != null) { // AI currently disabled for these costs - if (!CostUtil.checkSacrificeCost(abCost, source)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, source)) { return false; } @@ -1512,7 +1512,7 @@ public final class AbilityFactoryChangeZone { return false; } - if (!CostUtil.checkDiscardCost(abCost, source)) { + if (!CostUtil.checkDiscardCost(ai, abCost, source)) { return false; } @@ -1526,7 +1526,7 @@ public final class AbilityFactoryChangeZone { final Target tgt = sa.getTarget(); if (tgt != null) { - if (!AbilityFactoryChangeZone.changeKnownPreferredTarget(aiPlayer, af, sa, false)) { + if (!AbilityFactoryChangeZone.changeKnownPreferredTarget(ai, af, sa, false)) { return false; } } else { @@ -1563,7 +1563,7 @@ public final class AbilityFactoryChangeZone { return false; } - final ArrayList objects = AbilityFactory.predictThreatenedObjects(aiPlayer, af); + final ArrayList objects = AbilityFactory.predictThreatenedObjects(ai, af); boolean contains = false; for (final Card c : retrieval) { if (objects.contains(c)) { @@ -1577,7 +1577,7 @@ public final class AbilityFactoryChangeZone { } // don't return something to your hand if your hand is full of good stuff if (destination.equals(ZoneType.Hand) && origin.equals(ZoneType.Graveyard)) { - int handSize = aiPlayer.getCardsIn(ZoneType.Hand).size(); + int handSize = ai.getCardsIn(ZoneType.Hand).size(); if (Singletons.getModel().getGameState().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN1)) { return false; } @@ -1585,8 +1585,8 @@ public final class AbilityFactoryChangeZone { && handSize > 1) { return false; } - if (Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(aiPlayer) - && handSize >= aiPlayer.getMaxHandSize()) { + if (Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(ai) + && handSize >= ai.getMaxHandSize()) { return false; } } @@ -1848,7 +1848,7 @@ public final class AbilityFactoryChangeZone { } return false; } else { - if (!ComputerUtil.shouldCastLessThanMax(source)) { + if (!ComputerUtil.shouldCastLessThanMax(ai, source)) { return false; } break; @@ -1959,7 +1959,7 @@ public final class AbilityFactoryChangeZone { tgt.resetTargets(); return false; } else { - if (!ComputerUtil.shouldCastLessThanMax(source)) { + if (!ComputerUtil.shouldCastLessThanMax(ai, source)) { return false; } break; @@ -2575,7 +2575,7 @@ public final class AbilityFactoryChangeZone { return false; } - if (!CostUtil.checkDiscardCost(abCost, source)) { + if (!CostUtil.checkDiscardCost(ai, abCost, source)) { return false; } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryChoose.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryChoose.java index 04837cc13c2..debebc7de95 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryChoose.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryChoose.java @@ -375,6 +375,8 @@ public final class AbilityFactoryChoose { card.setChosenType(choice); } } else { + Player ai = sa.getActivatingPlayer(); + Player opp = ai.getOpponent(); String chosen = ""; if (params.containsKey("AILogic")) { final String logic = params.get("AILogic"); @@ -383,22 +385,19 @@ public final class AbilityFactoryChoose { .getCardsIn(ZoneType.Battlefield)); } if (logic.equals("MostProminentComputerControls")) { - chosen = CardFactoryUtil.getMostProminentCreatureType(AllZone.getComputerPlayer() - .getCardsIn(ZoneType.Battlefield)); + chosen = CardFactoryUtil.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Battlefield)); } if (logic.equals("MostProminentHumanControls")) { - chosen = CardFactoryUtil.getMostProminentCreatureType(AllZone.getHumanPlayer() - .getCardsIn(ZoneType.Battlefield)); + chosen = CardFactoryUtil.getMostProminentCreatureType(opp.getCardsIn(ZoneType.Battlefield)); if (!CardUtil.isACreatureType(chosen) || invalidTypes.contains(chosen)) { - chosen = CardFactoryUtil.getMostProminentCreatureType(CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), AllZone.getHumanPlayer())); + chosen = CardFactoryUtil.getMostProminentCreatureType(CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), opp)); } } if (logic.equals("MostProminentInComputerDeck")) { - chosen = CardFactoryUtil.getMostProminentCreatureType(CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), AllZone.getComputerPlayer())); + chosen = CardFactoryUtil.getMostProminentCreatureType(CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), ai)); } if (logic.equals("MostProminentInComputerGraveyard")) { - chosen = CardFactoryUtil.getMostProminentCreatureType(AllZone.getComputerPlayer() - .getCardsIn(ZoneType.Graveyard)); + chosen = CardFactoryUtil.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Graveyard)); } } if (!CardUtil.isACreatureType(chosen) || invalidTypes.contains(chosen)) { @@ -725,14 +724,16 @@ public final class AbilityFactoryChoose { } } else { List chosen = new ArrayList(); + Player ai = sa.getActivatingPlayer(); + Player opp = ai.getOpponent(); if (params.containsKey("AILogic")) { final String logic = params.get("AILogic"); if (logic.equals("MostProminentInHumanDeck")) { - chosen.add(CardFactoryUtil.getMostProminentColor(CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), AllZone.getHumanPlayer()))); + chosen.add(CardFactoryUtil.getMostProminentColor(CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), opp))); } else if (logic.equals("MostProminentInComputerDeck")) { - chosen.add(CardFactoryUtil.getMostProminentColor(CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), AllZone.getComputerPlayer()))); + chosen.add(CardFactoryUtil.getMostProminentColor(CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), ai))); } else if (logic.equals("MostProminentDualInComputerDeck")) { - List prominence = CardFactoryUtil.getColorByProminence(CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), AllZone.getComputerPlayer())); + List prominence = CardFactoryUtil.getColorByProminence(CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), ai)); chosen.add(prominence.get(0)); chosen.add(prominence.get(1)); } @@ -740,15 +741,14 @@ public final class AbilityFactoryChoose { chosen.add(CardFactoryUtil.getMostProminentColor(AllZoneUtil.getCardsInGame())); } else if (logic.equals("MostProminentHumanCreatures")) { - List list = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer()); + List list = AllZoneUtil.getCreaturesInPlay(opp); if (list.isEmpty()) { - list = CardLists.filter(CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), AllZone.getHumanPlayer()), CardPredicates.Presets.CREATURES); + list = CardLists.filter(CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), opp), CardPredicates.Presets.CREATURES); } chosen.add(CardFactoryUtil.getMostProminentColor(list)); } else if (logic.equals("MostProminentComputerControls")) { - chosen.add(CardFactoryUtil.getMostProminentColor(AllZone.getComputerPlayer().getCardsIn( - ZoneType.Battlefield))); + chosen.add(CardFactoryUtil.getMostProminentColor(ai.getCardsIn(ZoneType.Battlefield))); } else if (logic.equals("MostProminentPermanent")) { final List list = AllZoneUtil.getCardsIn(ZoneType.Battlefield); @@ -1640,11 +1640,9 @@ public final class AbilityFactoryChoose { if (params.containsKey("AILogic")) { final String logic = params.get("AILogic"); if (logic.equals("MostProminentInComputerDeck")) { - chosen = CardFactoryUtil.getMostProminentCardName(AllZone.getComputerPlayer() - .getCardsIn(ZoneType.Library)); + chosen = CardFactoryUtil.getMostProminentCardName(p.getCardsIn(ZoneType.Library)); } else if (logic.equals("MostProminentInHumanDeck")) { - chosen = CardFactoryUtil.getMostProminentCardName(AllZone.getHumanPlayer() - .getCardsIn(ZoneType.Library)); + chosen = CardFactoryUtil.getMostProminentCardName(p.getOpponent().getCardsIn(ZoneType.Library)); } } else { List list = CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), p.getOpponent()); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryCounterMagic.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryCounterMagic.java index aeb32f0982d..ad5c079a1c9 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryCounterMagic.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryCounterMagic.java @@ -255,7 +255,7 @@ public class AbilityFactoryCounterMagic { if (abCost != null) { // AI currently disabled for these costs - if (!CostUtil.checkSacrificeCost(abCost, source)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, source)) { return false; } if (!CostUtil.checkLifeCost(abCost, source, 4, null)) { diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java index 6b15390cc4a..1a92e8f97a3 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java @@ -337,15 +337,15 @@ public class AbilityFactoryCounters { return false; } - if (!CostUtil.checkDiscardCost(abCost, source)) { + if (!CostUtil.checkDiscardCost(ai, abCost, source)) { return false; } - if (!CostUtil.checkSacrificeCost(abCost, source)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, source)) { return false; } - if (!CostUtil.checkCreatureSacrificeCost(abCost, source)) { + if (!CostUtil.checkCreatureSacrificeCost(ai, abCost, source)) { return false; } @@ -805,7 +805,7 @@ public class AbilityFactoryCounters { @Override public boolean canPlayAI() { - return AbilityFactoryCounters.removeCanPlayAI(af, this); + return AbilityFactoryCounters.removeCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -848,7 +848,7 @@ public class AbilityFactoryCounters { // then call xCount with that card to properly calculate the // amount // Or choosing how many to sacrifice - return AbilityFactoryCounters.removeCanPlayAI(af, this); + return AbilityFactoryCounters.removeCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -989,7 +989,7 @@ public class AbilityFactoryCounters { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private static boolean removeCanPlayAI(final AbilityFactory af, final SpellAbility sa) { + private static boolean removeCanPlayAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { // AI needs to be expanded, since this function can be pretty complex // based on what // the expected targets could be @@ -1015,11 +1015,11 @@ public class AbilityFactoryCounters { return false; } - if (!CostUtil.checkDiscardCost(abCost, source)) { + if (!CostUtil.checkDiscardCost(ai, abCost, source)) { return false; } - if (!CostUtil.checkSacrificeCost(abCost, source)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, source)) { return false; } @@ -1870,11 +1870,11 @@ public class AbilityFactoryCounters { return false; } - if (!CostUtil.checkDiscardCost(abCost, source)) { + if (!CostUtil.checkDiscardCost(ai, abCost, source)) { return false; } - if (!CostUtil.checkSacrificeCost(abCost, source)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, source)) { return false; } } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryDealDamage.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryDealDamage.java index bf5b2b677de..583ef314748 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryDealDamage.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryDealDamage.java @@ -398,7 +398,7 @@ public class AbilityFactoryDealDamage { return false; } - if (!CostUtil.checkSacrificeCost(abCost, source)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, source)) { return false; } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryDebuff.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryDebuff.java index fd3ff8f12bd..6955ccbbc60 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryDebuff.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryDebuff.java @@ -304,7 +304,7 @@ public final class AbilityFactoryDebuff { final Cost cost = sa.getPayCosts(); // temporarily disabled until AI is improved - if (!CostUtil.checkCreatureSacrificeCost(cost, source)) { + if (!CostUtil.checkCreatureSacrificeCost(ai, cost, source)) { return false; } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryDestroy.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryDestroy.java index ad106900950..69ba2844713 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryDestroy.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryDestroy.java @@ -229,7 +229,7 @@ public class AbilityFactoryDestroy { List list; if (abCost != null) { - if (!CostUtil.checkSacrificeCost(abCost, source)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, source)) { return false; } @@ -237,7 +237,7 @@ public class AbilityFactoryDestroy { return false; } - if (!CostUtil.checkDiscardCost(abCost, source)) { + if (!CostUtil.checkDiscardCost(ai, abCost, source)) { return false; } } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java index 0931e9b5bd0..ef5a0cd6e2e 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryEffect.java @@ -97,7 +97,7 @@ public class AbilityFactoryEffect { @Override public boolean canPlayAI() { - return AbilityFactoryEffect.effectCanPlayAI(this.af, this); + return AbilityFactoryEffect.effectCanPlayAI(getActivatingPlayer(), this.af, this); } @Override @@ -141,7 +141,7 @@ public class AbilityFactoryEffect { @Override public boolean canPlayAI() { - return AbilityFactoryEffect.effectCanPlayAI(this.af, this); + return AbilityFactoryEffect.effectCanPlayAI(getActivatingPlayer(), this.af, this); } @Override @@ -189,7 +189,7 @@ public class AbilityFactoryEffect { @Override public boolean canPlayAI() { - return AbilityFactoryEffect.effectCanPlayAI(this.af, this); + return AbilityFactoryEffect.effectCanPlayAI(getActivatingPlayer(), this.af, this); } @Override @@ -253,7 +253,7 @@ public class AbilityFactoryEffect { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - public static boolean effectCanPlayAI(final AbilityFactory af, final SpellAbility sa) { + public static boolean effectCanPlayAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { final Random r = MyRandom.getRandom(); final HashMap params = af.getMapParams(); boolean randomReturn = r.nextFloat() <= .6667; @@ -263,7 +263,7 @@ public class AbilityFactoryEffect { logic = params.get("AILogic"); final PhaseHandler phase = Singletons.getModel().getGameState().getPhaseHandler(); if (logic.equals("BeginningOfOppTurn")) { - if (phase.isPlayerTurn(AllZone.getComputerPlayer()) || phase.getPhase().isAfter(PhaseType.DRAW)) { + if (phase.isPlayerTurn(ai.getOpponent()) || phase.getPhase().isAfter(PhaseType.DRAW)) { return false; } randomReturn = true; @@ -299,8 +299,8 @@ public class AbilityFactoryEffect { } else if (logic.equals("Always")) { randomReturn = true; } else if (logic.equals("Evasion")) { - List comp = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer()); - List human = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer()); + List comp = AllZoneUtil.getCreaturesInPlay(ai); + List human = AllZoneUtil.getCreaturesInPlay(ai.getOpponent()); // only count creatures that can attack or block comp = CardLists.filter(comp, new Predicate() { @@ -340,9 +340,9 @@ public class AbilityFactoryEffect { if (tgt != null && tgt.canTgtPlayer()) { tgt.resetTargets(); if (tgt.canOnlyTgtOpponent() || logic.equals("BeginningOfOppTurn")) { - tgt.addTarget(AllZone.getHumanPlayer()); + tgt.addTarget(ai.getOpponent()); } else { - tgt.addTarget(AllZone.getComputerPlayer()); + tgt.addTarget(ai); } } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryMana.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryMana.java index 83456f129af..bb57e9cf44d 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryMana.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryMana.java @@ -338,8 +338,9 @@ public class AbilityFactoryMana { int amount = params.containsKey("Amount") ? AbilityFactory.calculateAmount(af.getHostCard(), params.get("Amount"), sa) : 1; if (tgt == null || p.canBeTargetedBy(sa)) { + Player activator = sa.getActivatingPlayer(); // AI color choice is set in ComputerUtils so only human players need to make a choice - if (sa.getActivatingPlayer().isHuman()) { + if (activator.isHuman()) { //String colorsNeeded = abMana.getExpressChoice(); String[] colorsProduced = abMana.getComboColors().split(" "); final StringBuilder choiceString = new StringBuilder(); @@ -378,7 +379,7 @@ public class AbilityFactoryMana { final String logic = params.get("AILogic"); String chosen = Constant.Color.BLACK; if (logic.equals("MostProminentInComputerHand")) { - chosen = CardFactoryUtil.getMostProminentColor(AllZone.getComputerPlayer().getCardsIn( + chosen = CardFactoryUtil.getMostProminentColor(activator.getCardsIn( ZoneType.Hand)); } GuiChoose.one("Computer picked: ", new String[]{chosen}); @@ -397,8 +398,9 @@ public class AbilityFactoryMana { else if (abMana.isAnyMana()) { for (Player p : tgtPlayers) { if (tgt == null || p.canBeTargetedBy(sa)) { + Player act = sa.getActivatingPlayer(); // AI color choice is set in ComputerUtils so only human players need to make a choice - if (sa.getActivatingPlayer().isHuman()) { + if (act.isHuman()) { String colorsNeeded = abMana.getExpressChoice(); String choice = ""; if (colorsNeeded.length() == 1) { @@ -433,8 +435,7 @@ public class AbilityFactoryMana { final String logic = params.get("AILogic"); String chosen = Constant.Color.BLACK; if (logic.equals("MostProminentInComputerHand")) { - chosen = CardFactoryUtil.getMostProminentColor(AllZone.getComputerPlayer().getCardsIn( - ZoneType.Hand)); + chosen = CardFactoryUtil.getMostProminentColor(act.getCardsIn(ZoneType.Hand)); } GuiChoose.one("Computer picked: ", new String[]{chosen}); abMana.setExpressChoice(InputPayManaCostUtil.getShortColorString(chosen)); @@ -1131,7 +1132,7 @@ public class AbilityFactoryMana { @Override public boolean chkAIDrawback() { - return AbilityFactoryMana.drainManaPlayDrawbackAI(af, this); + return AbilityFactoryMana.drainManaPlayDrawbackAI(getActivatingPlayer(), af, this); } @Override @@ -1288,7 +1289,7 @@ public class AbilityFactoryMana { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private static boolean drainManaPlayDrawbackAI(final AbilityFactory af, final SpellAbility sa) { + private static boolean drainManaPlayDrawbackAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { // AI cannot use this properly until he can use SAs during Humans turn final HashMap params = af.getMapParams(); final Target tgt = sa.getTarget(); @@ -1299,12 +1300,12 @@ public class AbilityFactoryMana { if (tgt == null) { final ArrayList defined = AbilityFactory.getDefinedPlayers(source, params.get("Defined"), sa); - if (defined.contains(AllZone.getComputerPlayer())) { + if (defined.contains(ai)) { return false; } } else { tgt.resetTargets(); - tgt.addTarget(AllZone.getHumanPlayer()); + tgt.addTarget(ai.getOpponent()); } final AbilitySub subAb = sa.getSubAbility(); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java index f60217a6406..2c0bd69b0a0 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryPermanentState.java @@ -42,7 +42,6 @@ import forge.card.spellability.AbilitySub; import forge.card.spellability.Spell; import forge.card.spellability.SpellAbility; import forge.card.spellability.Target; -import forge.game.phase.CombatUtil; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; import forge.game.player.ComputerUtil; @@ -638,7 +637,7 @@ public class AbilityFactoryPermanentState { if (p.isHuman()) { AllZone.getInputControl().setInput(CardFactoryUtil.inputUntapUpToNType(num, valid)); } else { - List list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); + List list = p.getCardsIn(ZoneType.Battlefield); list = CardLists.getType(list, valid); list = CardLists.filter(list, Presets.TAPPED); @@ -940,7 +939,7 @@ public class AbilityFactoryPermanentState { return true; } else if (mandatory) { // not enough preferred targets, but mandatory so keep going: - return AbilityFactoryPermanentState.tapUnpreferredTargeting(af, sa, mandatory); + return AbilityFactoryPermanentState.tapUnpreferredTargeting(ai, af, sa, mandatory); } } @@ -1024,7 +1023,7 @@ public class AbilityFactoryPermanentState { } return false; } else { - if (!ComputerUtil.shouldCastLessThanMax(source)) { + if (!ComputerUtil.shouldCastLessThanMax(ai, source)) { return false; } break; @@ -1036,37 +1035,20 @@ public class AbilityFactoryPermanentState { && phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS)) { // Tap creatures possible blockers before combat during AI's turn. + List attackers; if (phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) { //Combat has already started - final List attackers = AllZone.getCombat().getAttackerList(); - List creatureList = CardLists.filter(tapList, new Predicate() { - @Override - public boolean apply(final Card c) { - if (c.isCreature()) { - return CombatUtil.canBlockAtLeastOne(c, attackers); - } - return false; - } - }); - if (!attackers.isEmpty() && !creatureList.isEmpty()) { - choice = CardFactoryUtil.getBestCreatureAI(creatureList); - } + attackers = AllZone.getCombat().getAttackerList(); } else { - final List attackers = ComputerUtil.getPossibleAttackers(); + attackers = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES_CAN_ATTACK); attackers.remove(sa.getSourceCard()); - List creatureList = CardLists.filter(tapList, new Predicate() { - @Override - public boolean apply(final Card c) { - if (c.isCreature()) { - return CombatUtil.canBlockAtLeastOne(c, attackers); - } - return false; - } - }); - if (!attackers.isEmpty() && creatureList.size() == 1) { - choice = CardFactoryUtil.getBestCreatureAI(creatureList); - } } + Predicate findBlockers = CardPredicates.possibleBlockerForAtLeastOne(attackers); + List creatureList = CardLists.filter(tapList, findBlockers); + if (!attackers.isEmpty() && !creatureList.isEmpty()) { + choice = CardFactoryUtil.getBestCreatureAI(creatureList); + } + } else if (phase.isPlayerTurn(opp) && phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)) { // Tap creatures possible blockers before combat during AI's turn. @@ -1087,7 +1069,7 @@ public class AbilityFactoryPermanentState { } return false; } else { - if (!ComputerUtil.shouldCastLessThanMax(source)) { + if (!ComputerUtil.shouldCastLessThanMax(ai, source)) { return false; } break; @@ -1114,7 +1096,7 @@ public class AbilityFactoryPermanentState { * a boolean. * @return a boolean. */ - private static boolean tapUnpreferredTargeting(final AbilityFactory af, final SpellAbility sa, + private static boolean tapUnpreferredTargeting(final Player ai, final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { final Card source = sa.getSourceCard(); final Target tgt = sa.getTarget(); @@ -1127,21 +1109,21 @@ public class AbilityFactoryPermanentState { final String[] tappablePermanents = { "Enchantment", "Planeswalker" }; List tapList = CardLists.getValidCards(list, tappablePermanents, source.getController(), source); - if (AbilityFactoryPermanentState.tapTargetList(af, sa, tapList, mandatory)) { + if (AbilityFactoryPermanentState.tapTargetList(ai, af, sa, tapList, mandatory)) { return true; } // try to just tap already tapped things tapList = CardLists.filter(list, Presets.TAPPED); - if (AbilityFactoryPermanentState.tapTargetList(af, sa, tapList, mandatory)) { + if (AbilityFactoryPermanentState.tapTargetList(ai, af, sa, tapList, mandatory)) { return true; } // just tap whatever we can tapList = list; - if (AbilityFactoryPermanentState.tapTargetList(af, sa, tapList, mandatory)) { + if (AbilityFactoryPermanentState.tapTargetList(ai, af, sa, tapList, mandatory)) { return true; } @@ -1163,7 +1145,7 @@ public class AbilityFactoryPermanentState { * a boolean. * @return a boolean. */ - private static boolean tapTargetList(final AbilityFactory af, final SpellAbility sa, final List tapList, + private static boolean tapTargetList(final Player ai, final AbilityFactory af, final SpellAbility sa, final List tapList, final boolean mandatory) { final Card source = sa.getSourceCard(); final Target tgt = sa.getTarget(); @@ -1186,7 +1168,7 @@ public class AbilityFactoryPermanentState { } return false; } else { - if (!ComputerUtil.shouldCastLessThanMax(source)) { + if (!ComputerUtil.shouldCastLessThanMax(ai, source)) { return false; } break; @@ -1207,7 +1189,7 @@ public class AbilityFactoryPermanentState { } return false; } else { - if (!ComputerUtil.shouldCastLessThanMax(source)) { + if (!ComputerUtil.shouldCastLessThanMax(ai, source)) { return false; } break; @@ -2180,7 +2162,7 @@ public class AbilityFactoryPermanentState { return true; } else if (mandatory) { // not enough preferred targets, but mandatory so keep going: - return AbilityFactoryPermanentState.tapUnpreferredTargeting(af, sa, mandatory); + return AbilityFactoryPermanentState.tapUnpreferredTargeting(ai, af, sa, mandatory); } } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryPlay.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryPlay.java index 4d2cbaff216..c7dadb72f7e 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryPlay.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryPlay.java @@ -96,7 +96,7 @@ public final class AbilityFactoryPlay { @Override public boolean canPlayAI() { - return AbilityFactoryPlay.playCanPlayAI(af, this); + return AbilityFactoryPlay.playCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -106,7 +106,7 @@ public final class AbilityFactoryPlay { @Override public boolean doTrigger(final boolean mandatory) { - return AbilityFactoryPlay.playTriggerAI(af, this, mandatory); + return AbilityFactoryPlay.playTriggerAI(getActivatingPlayer(), af, this, mandatory); } } final SpellAbility abCopySpell = new AbilityPlay(af.getHostCard(), af.getAbCost(), af.getAbTgt()); @@ -134,7 +134,7 @@ public final class AbilityFactoryPlay { @Override public boolean canPlayAI() { - return AbilityFactoryPlay.playCanPlayAI(af, this); + return AbilityFactoryPlay.playCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -144,7 +144,7 @@ public final class AbilityFactoryPlay { @Override public boolean canPlayFromEffectAI(final boolean mandatory, final boolean withOutManaCost) { - return AbilityFactoryPlay.playTriggerAI(af, this, mandatory); + return AbilityFactoryPlay.playTriggerAI(getActivatingPlayer(), af, this, mandatory); } }; @@ -193,7 +193,7 @@ public final class AbilityFactoryPlay { @Override public boolean doTrigger(final boolean mandatory) { - return AbilityFactoryPlay.playTriggerAI(af, this, mandatory); + return AbilityFactoryPlay.playTriggerAI(getActivatingPlayer(), af, this, mandatory); } } final SpellAbility dbCopySpell = new DrawbackPlay(af.getHostCard(), af.getAbTgt()); @@ -266,7 +266,7 @@ public final class AbilityFactoryPlay { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private static boolean playCanPlayAI(final AbilityFactory af, final SpellAbility sa) { + private static boolean playCanPlayAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { final Cost abCost = af.getAbCost(); final Card source = af.getHostCard(); final HashMap params = af.getMapParams(); @@ -274,7 +274,7 @@ public final class AbilityFactoryPlay { if (abCost != null) { // AI currently disabled for these costs - if (!CostUtil.checkSacrificeCost(abCost, source)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, source)) { return false; } @@ -282,7 +282,7 @@ public final class AbilityFactoryPlay { return false; } - if (!CostUtil.checkDiscardCost(abCost, source)) { + if (!CostUtil.checkDiscardCost(ai, abCost, source)) { return false; } @@ -304,7 +304,7 @@ public final class AbilityFactoryPlay { if (tgt != null) { ZoneType zone = tgt.getZone().get(0); cards = AllZoneUtil.getCardsIn(zone); - cards = CardLists.getValidCards(cards, tgt.getValidTgts(), AllZone.getComputerPlayer(), source); + cards = CardLists.getValidCards(cards, tgt.getValidTgts(), ai, source); if (cards.isEmpty()) { return false; } @@ -331,13 +331,13 @@ public final class AbilityFactoryPlay { * a boolean. * @return a boolean. */ - private static boolean playTriggerAI(final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { + private static boolean playTriggerAI(final Player ai, final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { if (mandatory) { return true; } - return playCanPlayAI(af, sa); + return playCanPlayAI(ai, af, sa); } /** @@ -505,7 +505,7 @@ public final class AbilityFactoryPlay { if (tgtSA instanceof Spell) { Spell spell = (Spell) tgtSA; if (spell.canPlayFromEffectAI(!optional, true) || !optional) { - ComputerUtil.playSpellAbilityWithoutPayingManaCost(tgtSA); + ComputerUtil.playSpellAbilityWithoutPayingManaCost(controller, tgtSA); if (remember) { source.addRemembered(tgtSA.getSourceCard()); } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryPreventDamage.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryPreventDamage.java index 899b35fc326..5f4cb2234c1 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryPreventDamage.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryPreventDamage.java @@ -85,7 +85,7 @@ public class AbilityFactoryPreventDamage { @Override public boolean canPlayAI() { - return AbilityFactoryPreventDamage.preventDamageCanPlayAI(af, this); + return AbilityFactoryPreventDamage.preventDamageCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -124,7 +124,7 @@ public class AbilityFactoryPreventDamage { @Override public boolean canPlayAI() { - return AbilityFactoryPreventDamage.preventDamageCanPlayAI(af, this); + return AbilityFactoryPreventDamage.preventDamageCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -272,7 +272,7 @@ public class AbilityFactoryPreventDamage { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private static boolean preventDamageCanPlayAI(final AbilityFactory af, final SpellAbility sa) { + private static boolean preventDamageCanPlayAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); final Card hostCard = af.getHostCard(); boolean chance = false; @@ -284,11 +284,11 @@ public class AbilityFactoryPreventDamage { return false; } - if (!CostUtil.checkDiscardCost(cost, hostCard)) { + if (!CostUtil.checkDiscardCost(ai, cost, hostCard)) { return false; } - if (!CostUtil.checkSacrificeCost(cost, hostCard)) { + if (!CostUtil.checkSacrificeCost(ai, cost, hostCard)) { return false; } @@ -345,14 +345,14 @@ public class AbilityFactoryPreventDamage { final ArrayList objects = new ArrayList(); // AbilityFactory.predictThreatenedObjects(af); - if (objects.contains(AllZone.getComputerPlayer())) { - tgt.addTarget(AllZone.getComputerPlayer()); + if (objects.contains(ai)) { + tgt.addTarget(ai); } final List threatenedTargets = new ArrayList(); // filter AIs battlefield by what I can target - List targetables = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); - targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), AllZone.getComputerPlayer(), hostCard); + List targetables = ai.getCardsIn(ZoneType.Battlefield); + targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, hostCard); for (final Card c : targetables) { if (objects.contains(c)) { @@ -368,15 +368,15 @@ public class AbilityFactoryPreventDamage { } // Protect combatants else if (Singletons.getModel().getGameState().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { - if (sa.canTarget(AllZone.getComputerPlayer()) && CombatUtil.wouldLoseLife(AllZone.getCombat()) + if (sa.canTarget(ai) && CombatUtil.wouldLoseLife(AllZone.getCombat()) && (CombatUtil.lifeInDanger(AllZone.getCombat()) || sa.isAbility()) - && Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(AllZone.getHumanPlayer())) { - tgt.addTarget(AllZone.getComputerPlayer()); + && Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(ai.getOpponent())) { + tgt.addTarget(ai); chance = true; } else { // filter AIs battlefield by what I can target - List targetables = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); - targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), AllZone.getComputerPlayer(), hostCard); + List targetables = ai.getCardsIn(ZoneType.Battlefield); + targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, hostCard); if (targetables.size() == 0) { return false; @@ -428,7 +428,7 @@ public class AbilityFactoryPreventDamage { // If there's no target on the trigger, just say yes. chance = true; } else { - chance = AbilityFactoryPreventDamage.preventDamageMandatoryTarget(af, sa, mandatory); + chance = AbilityFactoryPreventDamage.preventDamageMandatoryTarget(ai, af, sa, mandatory); } final AbilitySub subAb = sa.getSubAbility(); @@ -452,15 +452,15 @@ public class AbilityFactoryPreventDamage { * a boolean. * @return a boolean. */ - private static boolean preventDamageMandatoryTarget(final AbilityFactory af, final SpellAbility sa, + private static boolean preventDamageMandatoryTarget(final Player ai, final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { final Card hostCard = af.getHostCard(); final Target tgt = sa.getTarget(); tgt.resetTargets(); // filter AIs battlefield by what I can target List targetables = AllZoneUtil.getCardsIn(ZoneType.Battlefield); - targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), AllZone.getComputerPlayer(), hostCard); - final List compTargetables = CardLists.filterControlledBy(targetables, AllZone.getComputerPlayer()); + targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, hostCard); + final List compTargetables = CardLists.filterControlledBy(targetables, ai); if (targetables.size() == 0) { return false; @@ -586,7 +586,7 @@ public class AbilityFactoryPreventDamage { @Override public boolean canPlayAI() { - return AbilityFactoryPreventDamage.preventDamageAllCanPlayAI(af, this); + return AbilityFactoryPreventDamage.preventDamageAllCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -624,7 +624,7 @@ public class AbilityFactoryPreventDamage { @Override public boolean canPlayAI() { - return AbilityFactoryPreventDamage.preventDamageAllCanPlayAI(af, this); + return AbilityFactoryPreventDamage.preventDamageAllCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -718,7 +718,7 @@ public class AbilityFactoryPreventDamage { return sb.toString(); } - private static boolean preventDamageAllCanPlayAI(final AbilityFactory af, final SpellAbility sa) { + private static boolean preventDamageAllCanPlayAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { final Card hostCard = af.getHostCard(); boolean chance = false; @@ -729,11 +729,11 @@ public class AbilityFactoryPreventDamage { return false; } - if (!CostUtil.checkDiscardCost(cost, hostCard)) { + if (!CostUtil.checkDiscardCost(ai, cost, hostCard)) { return false; } - if (!CostUtil.checkSacrificeCost(cost, hostCard)) { + if (!CostUtil.checkSacrificeCost(ai, cost, hostCard)) { return false; } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryProtection.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryProtection.java index 0e03badee2f..5a507f0272c 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryProtection.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryProtection.java @@ -81,7 +81,7 @@ public final class AbilityFactoryProtection { @Override public boolean canPlayAI() { - return AbilityFactoryProtection.protectCanPlayAI(af, this); + return AbilityFactoryProtection.protectCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -125,7 +125,7 @@ public final class AbilityFactoryProtection { @Override public boolean canPlayAI() { - return AbilityFactoryProtection.protectCanPlayAI(af, this); + return AbilityFactoryProtection.protectCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -175,7 +175,7 @@ public final class AbilityFactoryProtection { @Override public boolean canPlayAI() { - return AbilityFactoryProtection.protectCanPlayAI(af, this); + return AbilityFactoryProtection.protectCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -190,7 +190,7 @@ public final class AbilityFactoryProtection { @Override public boolean chkAIDrawback() { - return AbilityFactoryProtection.protectDrawbackAI(af, this); + return AbilityFactoryProtection.protectDrawbackAI(getActivatingPlayer(), af, this); } @Override @@ -245,11 +245,11 @@ public final class AbilityFactoryProtection { * a {@link forge.card.abilityfactory.AbilityFactory} object. * @return a {@link forge.CardList} object. */ - private static List getProtectCreatures(final AbilityFactory af, final SpellAbility sa) { + private static List getProtectCreatures(final Player ai, final AbilityFactory af, final SpellAbility sa) { final Card hostCard = af.getHostCard(); final ArrayList gains = AbilityFactoryProtection.getProtectionList(hostCard, af.getMapParams()); - List list = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer()); + List list = AllZoneUtil.getCreaturesInPlay(ai); list = CardLists.filter(list, new Predicate() { @Override public boolean apply(final Card c) { @@ -264,7 +264,7 @@ public final class AbilityFactoryProtection { // will the creature attack (only relevant for sorcery speed)? if (Singletons.getModel().getGameState().getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) - && Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(AllZone.getComputerPlayer()) + && Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(ai) && CardFactoryUtil.doesCreatureAttackAI(c)) { return true; } @@ -300,7 +300,7 @@ public final class AbilityFactoryProtection { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private static boolean protectCanPlayAI(final AbilityFactory af, final SpellAbility sa) { + private static boolean protectCanPlayAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); final Card hostCard = af.getHostCard(); // if there is no target and host card isn't in play, don't activate @@ -315,11 +315,11 @@ public final class AbilityFactoryProtection { return false; } - if (!CostUtil.checkDiscardCost(cost, hostCard)) { + if (!CostUtil.checkDiscardCost(ai, cost, hostCard)) { return false; } - if (!CostUtil.checkCreatureSacrificeCost(cost, hostCard)) { + if (!CostUtil.checkCreatureSacrificeCost(ai, cost, hostCard)) { return false; } @@ -355,7 +355,7 @@ public final class AbilityFactoryProtection { * } */ } else { - return AbilityFactoryProtection.protectTgtAI(af, sa, false); + return AbilityFactoryProtection.protectTgtAI(ai, af, sa, false); } return false; @@ -374,7 +374,7 @@ public final class AbilityFactoryProtection { * a boolean. * @return a boolean. */ - private static boolean protectTgtAI(final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { + private static boolean protectTgtAI(final Player ai, final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { if (!mandatory && Singletons.getModel().getGameState().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { return false; } @@ -383,7 +383,7 @@ public final class AbilityFactoryProtection { final Target tgt = sa.getTarget(); tgt.resetTargets(); - List list = AbilityFactoryProtection.getProtectCreatures(af, sa); + List list = AbilityFactoryProtection.getProtectCreatures(ai, af, sa); list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard()); @@ -403,18 +403,18 @@ public final class AbilityFactoryProtection { // attack/block if ((sa.getPayCosts() != null) && sa.getPayCosts().getTap()) { if (Singletons.getModel().getGameState().getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) - && Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(AllZone.getComputerPlayer())) { + && Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(ai)) { list.remove(sa.getSourceCard()); } if (Singletons.getModel().getGameState().getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS) - && Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(AllZone.getHumanPlayer())) { + && Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(ai)) { list.remove(sa.getSourceCard()); } } } if (list.isEmpty()) { - return mandatory && AbilityFactoryProtection.protectMandatoryTarget(af, sa, mandatory); + return mandatory && AbilityFactoryProtection.protectMandatoryTarget(ai, af, sa, mandatory); } // Don't target cards that will die. @@ -433,7 +433,7 @@ public final class AbilityFactoryProtection { if (list.isEmpty()) { if ((tgt.getNumTargeted() < tgt.getMinTargets(source, sa)) || (tgt.getNumTargeted() == 0)) { if (mandatory) { - return AbilityFactoryProtection.protectMandatoryTarget(af, sa, mandatory); + return AbilityFactoryProtection.protectMandatoryTarget(ai, af, sa, mandatory); } tgt.resetTargets(); @@ -465,7 +465,7 @@ public final class AbilityFactoryProtection { * a boolean. * @return a boolean. */ - private static boolean protectMandatoryTarget(final AbilityFactory af, final SpellAbility sa, + private static boolean protectMandatoryTarget(final Player ai, final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { final HashMap params = af.getMapParams(); final Card host = af.getHostCard(); @@ -484,7 +484,7 @@ public final class AbilityFactoryProtection { list.remove(c); } - List pref = CardLists.filterControlledBy(list, AllZone.getComputerPlayer()); + List pref = CardLists.filterControlledBy(list, ai); pref = CardLists.filter(pref, new Predicate() { @Override public boolean apply(final Card c) { @@ -492,7 +492,7 @@ public final class AbilityFactoryProtection { AbilityFactoryProtection.getProtectionList(host, params)); } }); - final List pref2 = CardLists.filterControlledBy(list, AllZone.getComputerPlayer()); + final List pref2 = CardLists.filterControlledBy(list, ai); pref = CardLists.filter(pref, new Predicate() { @Override public boolean apply(final Card c) { @@ -500,7 +500,7 @@ public final class AbilityFactoryProtection { AbilityFactoryProtection.getProtectionList(host, params)); } }); - final List forced = CardLists.filterControlledBy(list, AllZone.getHumanPlayer()); + final List forced = CardLists.filterControlledBy(list, ai); final Card source = sa.getSourceCard(); while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { @@ -585,7 +585,7 @@ public final class AbilityFactoryProtection { return true; } } else { - return AbilityFactoryProtection.protectTgtAI(af, sa, mandatory); + return AbilityFactoryProtection.protectTgtAI(ai, af, sa, mandatory); } return true; @@ -602,7 +602,7 @@ public final class AbilityFactoryProtection { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private static boolean protectDrawbackAI(final AbilityFactory af, final SpellAbility sa) { + private static boolean protectDrawbackAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { final Card host = af.getHostCard(); if ((sa.getTarget() == null) || !sa.getTarget().doesTarget()) { @@ -610,7 +610,7 @@ public final class AbilityFactoryProtection { // TODO } } else { - return AbilityFactoryProtection.protectTgtAI(af, sa, false); + return AbilityFactoryProtection.protectTgtAI(ai, af, sa, false); } return true; @@ -732,6 +732,7 @@ public final class AbilityFactoryProtection { final ArrayList choices = AbilityFactoryProtection.getProtectionList(host, params); final ArrayList gains = new ArrayList(); if (isChoice) { + if (sa.getActivatingPlayer().isHuman()) { final String choice = GuiChoose.one("Choose a protection", choices); if (null == choice) { @@ -739,13 +740,14 @@ public final class AbilityFactoryProtection { } gains.add(choice); } else { + Player ai = sa.getActivatingPlayer(); String choice = choices.get(0); if (params.containsKey("AILogic")) { final String logic = params.get("AILogic"); if (logic.equals("MostProminentHumanCreatures")) { - List list = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer()); + List list = AllZoneUtil.getCreaturesInPlay(ai.getOpponent()); if (list.isEmpty()) { - list = CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), AllZone.getHumanPlayer()); + list = CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), ai.getOpponent()); } if (!list.isEmpty()) { choice = CardFactoryUtil.getMostProminentColor(list); @@ -894,7 +896,7 @@ public final class AbilityFactoryProtection { @Override public boolean canPlayAI() { - return AbilityFactoryProtection.protectAllCanPlayAI(af, this); + return AbilityFactoryProtection.protectAllCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -938,7 +940,7 @@ public final class AbilityFactoryProtection { @Override public boolean canPlayAI() { - return AbilityFactoryProtection.protectAllCanPlayAI(af, this); + return AbilityFactoryProtection.protectAllCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -988,7 +990,7 @@ public final class AbilityFactoryProtection { @Override public boolean canPlayAI() { - return AbilityFactoryProtection.protectAllCanPlayAI(af, this); + return AbilityFactoryProtection.protectAllCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -1027,7 +1029,7 @@ public final class AbilityFactoryProtection { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private static boolean protectAllCanPlayAI(final AbilityFactory af, final SpellAbility sa) { + private static boolean protectAllCanPlayAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { final Card hostCard = af.getHostCard(); // if there is no target and host card isn't in play, don't activate if ((sa.getTarget() == null) && !AllZoneUtil.isCardInPlay(hostCard)) { @@ -1041,11 +1043,11 @@ public final class AbilityFactoryProtection { return false; } - if (!CostUtil.checkDiscardCost(cost, hostCard)) { + if (!CostUtil.checkDiscardCost(ai, cost, hostCard)) { return false; } - if (!CostUtil.checkSacrificeCost(cost, hostCard)) { + if (!CostUtil.checkSacrificeCost(ai, cost, hostCard)) { return false; } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryPump.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryPump.java index a15fbe8f2e8..58a9ef986ac 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryPump.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryPump.java @@ -243,7 +243,7 @@ public class AbilityFactoryPump { @Override public boolean chkAIDrawback() { - return AbilityFactoryPump.this.pumpDrawbackAI(this); + return AbilityFactoryPump.this.pumpDrawbackAI(getActivatingPlayer(), this); } @Override @@ -292,12 +292,12 @@ public class AbilityFactoryPump { * @param sa SpellAbility * @return true, if successful */ - public boolean containsUsefulKeyword(final ArrayList keywords, final Card card, final SpellAbility sa) { + public boolean containsUsefulKeyword(final Player ai, final ArrayList keywords, final Card card, final SpellAbility sa) { for (final String keyword : keywords) { - if (!sa.getAbilityFactory().isCurse() && isUsefulPumpKeyword(keyword, card, sa)) { + if (!sa.getAbilityFactory().isCurse() && isUsefulPumpKeyword(ai, keyword, card, sa)) { return true; } - if (sa.getAbilityFactory().isCurse() && isUsefulCurseKeyword(keyword, card, sa)) { + if (sa.getAbilityFactory().isCurse() && isUsefulCurseKeyword(ai, keyword, card, sa)) { return true; } } @@ -314,16 +314,15 @@ public class AbilityFactoryPump { * @param sa SpellAbility * @return true, if is useful keyword */ - public boolean isUsefulCurseKeyword(final String keyword, final Card card, final SpellAbility sa) { + public boolean isUsefulCurseKeyword(final Player ai, final String keyword, final Card card, final SpellAbility sa) { final PhaseHandler ph = Singletons.getModel().getGameState().getPhaseHandler(); - final Player computer = AllZone.getComputerPlayer(); - final Player human = AllZone.getHumanPlayer(); + final Player human = ai.getOpponent(); //int attack = getNumAttack(sa); //int defense = getNumDefense(sa); if (!CardUtil.isStackingKeyword(keyword) && card.hasKeyword(keyword)) { return false; } else if (keyword.equals("Defender") || keyword.endsWith("CARDNAME can't attack.")) { - if (ph.isPlayerTurn(computer) || !CombatUtil.canAttack(card) + if (ph.isPlayerTurn(ai) || !CombatUtil.canAttack(card) || (card.getNetCombatDamage() <= 0) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) { return false; @@ -341,7 +340,7 @@ public class AbilityFactoryPump { return false; } - List attackers = CardLists.filter(AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.possibleAttackers); + List attackers = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.possibleAttackers); if (!CombatUtil.canBlockAtLeastOne(card, attackers)) { return false; } @@ -352,7 +351,7 @@ public class AbilityFactoryPump { return false; } - List attackers = CardLists.filter(AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.possibleAttackers); + List attackers = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.possibleAttackers); if (!CombatUtil.canBlockAtLeastOne(card, attackers)) { return false; } @@ -363,11 +362,11 @@ public class AbilityFactoryPump { } } else if (keyword.endsWith("Prevent all combat damage that would be dealt by CARDNAME.") || keyword.endsWith("Prevent all damage that would be dealt by CARDNAME.")) { - if (ph.isPlayerTurn(computer) && (!(CombatUtil.canBlock(card) || card.isBlocking()) + if (ph.isPlayerTurn(ai) && (!(CombatUtil.canBlock(card) || card.isBlocking()) || card.getNetCombatDamage() <= 0 || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) || ph.getPhase().isBefore(PhaseType.MAIN1) - || CardLists.getNotKeyword(AllZoneUtil.getCreaturesInPlay(computer), "Defender").isEmpty())) { + || CardLists.getNotKeyword(AllZoneUtil.getCreaturesInPlay(ai), "Defender").isEmpty())) { return false; } if (ph.isPlayerTurn(human) && (!card.isAttacking() @@ -375,7 +374,7 @@ public class AbilityFactoryPump { return false; } } else if (keyword.endsWith("CARDNAME attacks each turn if able.")) { - if (ph.isPlayerTurn(computer) || !CombatUtil.canAttack(card) || !CombatUtil.canBeBlocked(card) + if (ph.isPlayerTurn(ai) || !CombatUtil.canAttack(card) || !CombatUtil.canBeBlocked(card) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) { return false; } @@ -399,10 +398,9 @@ public class AbilityFactoryPump { * @param sa SpellAbility * @return true, if is useful keyword */ - public boolean isUsefulPumpKeyword(final String keyword, final Card card, final SpellAbility sa) { + public boolean isUsefulPumpKeyword(final Player ai, final String keyword, final Card card, final SpellAbility sa) { final PhaseHandler ph = Singletons.getModel().getGameState().getPhaseHandler(); - final Player computer = AllZone.getComputerPlayer(); - final Player human = AllZone.getHumanPlayer(); + final Player opp = ai.getOpponent(); int attack = getNumAttack(sa); //int defense = getNumDefense(sa); if (!CardUtil.isStackingKeyword(keyword) && card.hasKeyword(keyword)) { @@ -410,7 +408,7 @@ public class AbilityFactoryPump { } Predicate opBlockers = CardPredicates.possibleBlockers(card); - List cardsCanBlock = CardLists.filter(AllZoneUtil.getCreaturesInPlay(human), opBlockers); + List cardsCanBlock = CardLists.filter(AllZoneUtil.getCreaturesInPlay(opp), opBlockers); final boolean evasive = (keyword.endsWith("Unblockable") || keyword.endsWith("Fear") || keyword.endsWith("Intimidate") || keyword.endsWith("Shadow")); @@ -418,14 +416,14 @@ public class AbilityFactoryPump { || keyword.contains("Bushido")); // give evasive keywords to creatures that can or do attack if (evasive) { - if (ph.isPlayerTurn(human) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || card.getNetCombatDamage() <= 0 || cardsCanBlock.isEmpty()) { return false; } } else if (keyword.endsWith("Flying")) { - if (ph.isPlayerTurn(human) + if (ph.isPlayerTurn(opp) && ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) && !CardLists.getKeyword(AllZone.getCombat().getAttackerList(), "Flying").isEmpty() && !card.hasKeyword("Reach") @@ -434,27 +432,27 @@ public class AbilityFactoryPump { return true; } Predicate flyingOrReach = Predicates.or(CardPredicates.hasKeyword("Flying"), CardPredicates.hasKeyword("Reach")); - if (ph.isPlayerTurn(human) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || card.getNetCombatDamage() <= 0 || !Iterables.any(cardsCanBlock, Predicates.not(flyingOrReach))) { return false; } } else if (keyword.endsWith("Horsemanship")) { - if (ph.isPlayerTurn(human) + if (ph.isPlayerTurn(opp) && ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) && !CardLists.getKeyword(AllZone.getCombat().getAttackerList(), "Horsemanship").isEmpty() && CombatUtil.canBlock(card) && CombatUtil.lifeInDanger(AllZone.getCombat())) { return true; } - if (ph.isPlayerTurn(human) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || card.getNetCombatDamage() <= 0 || CardLists.getNotKeyword(cardsCanBlock, "Horsemanship").isEmpty()) { return false; } } else if (keyword.endsWith("Haste")) { - if (!card.hasSickness() || ph.isPlayerTurn(human) || card.isTapped() + if (!card.hasSickness() || ph.isPlayerTurn(opp) || card.isTapped() || card.getNetCombatDamage() <= 0 || card.hasKeyword("CARDNAME can attack as though it had haste.") || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) @@ -465,7 +463,7 @@ public class AbilityFactoryPump { return true; } else if (keyword.endsWith("Deathtouch")) { Combat combat = AllZone.getCombat(); - if (ph.isPlayerTurn(human) && ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)) { + if (ph.isPlayerTurn(opp) && ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)) { List attackers = combat.getAttackers(); for (Card attacker : attackers) { if (CombatUtil.canBlock(attacker, card, combat) @@ -473,9 +471,9 @@ public class AbilityFactoryPump { return true; } } - } else if (ph.isPlayerTurn(computer) && ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) + } else if (ph.isPlayerTurn(ai) && ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) && CombatUtil.canAttack(card)) { - List blockers = AllZoneUtil.getCreaturesInPlay(human); + List blockers = AllZoneUtil.getCreaturesInPlay(opp); for (Card blocker : blockers) { if (CombatUtil.canBlock(card, blocker, combat) && !CombatUtil.canDestroyBlocker(blocker, card, combat, false)) { @@ -485,32 +483,32 @@ public class AbilityFactoryPump { } return false; } else if (combatRelevant) { - if (ph.isPlayerTurn(human) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) - || (AllZoneUtil.getCreaturesInPlay(human).size() < 1) + || (AllZoneUtil.getCreaturesInPlay(opp).size() < 1) || cardsCanBlock.isEmpty()) { return false; } } else if (keyword.equals("Double Strike")) { - if (ph.isPlayerTurn(human) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) || card.getNetCombatDamage() <= 0 || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { return false; } } else if (keyword.startsWith("Rampage")) { - if (ph.isPlayerTurn(human) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || cardsCanBlock.size() < 2) { return false; } } else if (keyword.startsWith("Flanking")) { - if (ph.isPlayerTurn(human) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || CardLists.getNotKeyword(cardsCanBlock, "Flanking").isEmpty()) { return false; } } else if (keyword.startsWith("Trample")) { - if (ph.isPlayerTurn(human) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) || !CombatUtil.canBeBlocked(card) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || cardsCanBlock.isEmpty() @@ -524,7 +522,7 @@ public class AbilityFactoryPump { if (card.isBlocking()) { return true; } - if ((ph.isPlayerTurn(human)) + if ((ph.isPlayerTurn(opp)) || !(CombatUtil.canAttack(card) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) { return false; @@ -548,13 +546,13 @@ public class AbilityFactoryPump { return false; } } else if (keyword.equals("Vigilance")) { - if (ph.isPlayerTurn(human) || !CombatUtil.canAttack(card) + if (ph.isPlayerTurn(opp) || !CombatUtil.canAttack(card) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) - || CardLists.getNotKeyword(AllZoneUtil.getCreaturesInPlay(human), "Defender").size() < 1) { + || CardLists.getNotKeyword(AllZoneUtil.getCreaturesInPlay(opp), "Defender").size() < 1) { return false; } } else if (keyword.equals("Reach")) { - if (ph.isPlayerTurn(computer) + if (ph.isPlayerTurn(ai) || !ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || CardLists.getKeyword(AllZone.getCombat().getAttackerList(), "Flying").isEmpty() || card.hasKeyword("Flying") @@ -562,7 +560,7 @@ public class AbilityFactoryPump { return false; } } else if (keyword.endsWith("CARDNAME can block an additional creature.")) { - if (ph.isPlayerTurn(computer) + if (ph.isPlayerTurn(ai) || !ph.getPhase().equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)) { return false; } @@ -584,34 +582,34 @@ public class AbilityFactoryPump { return false; } } else if (keyword.equals("Islandwalk")) { - if (ph.isPlayerTurn(human) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || card.getNetCombatDamage() <= 0 - || CardLists.getType(AllZoneUtil.getPlayerLandsInPlay(human), "Island").isEmpty() + || CardLists.getType(AllZoneUtil.getPlayerLandsInPlay(opp), "Island").isEmpty() || cardsCanBlock.isEmpty()) { return false; } } else if (keyword.equals("Swampwalk")) { - if (ph.isPlayerTurn(human) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || card.getNetCombatDamage() <= 0 - || CardLists.getType(AllZoneUtil.getPlayerLandsInPlay(human), "Swamp").isEmpty() + || CardLists.getType(AllZoneUtil.getPlayerLandsInPlay(opp), "Swamp").isEmpty() || cardsCanBlock.isEmpty()) { return false; } } else if (keyword.equals("Mountainwalk")) { - if (ph.isPlayerTurn(human) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || card.getNetCombatDamage() <= 0 - || CardLists.getType(AllZoneUtil.getPlayerLandsInPlay(human), "Mountain").isEmpty() + || CardLists.getType(AllZoneUtil.getPlayerLandsInPlay(opp), "Mountain").isEmpty() || cardsCanBlock.isEmpty()) { return false; } } else if (keyword.equals("Forestwalk")) { - if (ph.isPlayerTurn(human) || !(CombatUtil.canAttack(card) || card.isAttacking()) + if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking()) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || card.getNetCombatDamage() <= 0 - || CardLists.getType(AllZoneUtil.getPlayerLandsInPlay(human), "Forest").isEmpty() + || CardLists.getType(AllZoneUtil.getPlayerLandsInPlay(opp), "Forest").isEmpty() || cardsCanBlock.isEmpty()) { return false; } @@ -619,7 +617,7 @@ public class AbilityFactoryPump { return true; } - private boolean shouldPumpCard(final SpellAbility sa, final Card c) { + private boolean shouldPumpCard(final Player ai, final SpellAbility sa, final Card c) { int attack = getNumAttack(sa); int defense = getNumDefense(sa); PhaseHandler phase = Singletons.getModel().getGameState().getPhaseHandler(); @@ -632,13 +630,13 @@ public class AbilityFactoryPump { return false; } - if (containsUsefulKeyword(keywords, c, sa)) { + if (containsUsefulKeyword(ai, keywords, c, sa)) { return true; } // will the creature attack (only relevant for sorcery speed)? if (phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) - && phase.isPlayerTurn(AllZone.getComputerPlayer()) + && phase.isPlayerTurn(ai) && attack > 0 && CardFactoryUtil.doesCreatureAttackAI(c)) { return true; @@ -681,7 +679,7 @@ public class AbilityFactoryPump { } if (phase.getPhase().equals(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) - && phase.isPlayerTurn(AllZone.getHumanPlayer()) + && phase.isPlayerTurn(ai.getOpponent()) && c.isBlocking() && defense > 0 && attackerHasTrample @@ -699,13 +697,13 @@ public class AbilityFactoryPump { * * @return a {@link forge.CardList} object. */ - private List getPumpCreatures(final SpellAbility sa) { + private List getPumpCreatures(final Player ai, final SpellAbility sa) { - List list = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer()); + List list = AllZoneUtil.getCreaturesInPlay(ai); list = CardLists.filter(list, new Predicate() { @Override public boolean apply(final Card c) { - return shouldPumpCard(sa, c); + return shouldPumpCard(ai, sa, c); } }); return list; @@ -724,8 +722,8 @@ public class AbilityFactoryPump { * a int. * @return a {@link forge.CardList} object. */ - private List getCurseCreatures(final SpellAbility sa, final int defense, final int attack) { - List list = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer()); + private List getCurseCreatures(final Player ai, final SpellAbility sa, final int defense, final int attack) { + List list = AllZoneUtil.getCreaturesInPlay(ai.getOpponent()); list = CardLists.getTargetableCards(list, sa); if ((defense < 0) && !list.isEmpty()) { // with spells that give -X/-X, // compi will try to destroy a @@ -760,7 +758,7 @@ public class AbilityFactoryPump { if (!c.isAttacking()) { return false; } - if (c.getNetAttack() > 0 && AllZone.getComputerPlayer().getLife() < 5) { + if (c.getNetAttack() > 0 && ai.getLife() < 5) { return true; } //Don't waste a -7/-0 spell on a 1/1 creature @@ -784,7 +782,7 @@ public class AbilityFactoryPump { list = CardLists.filter(list, new Predicate() { @Override public boolean apply(final Card c) { - return containsUsefulKeyword(keywords, c, sa); + return containsUsefulKeyword(ai, keywords, c, sa); } }); } else { @@ -824,11 +822,11 @@ public class AbilityFactoryPump { return false; } - if (!CostUtil.checkDiscardCost(cost, sa.getSourceCard())) { + if (!CostUtil.checkDiscardCost(ai, cost, sa.getSourceCard())) { return false; } - if (!CostUtil.checkCreatureSacrificeCost(cost, sa.getSourceCard())) { + if (!CostUtil.checkCreatureSacrificeCost(ai, cost, sa.getSourceCard())) { return false; } @@ -837,10 +835,10 @@ public class AbilityFactoryPump { } if (AllZone.getStack().isEmpty() && CostUtil.hasTapCost(cost, sa.getSourceCard())) { - if (ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) && ph.isPlayerTurn(AllZone.getComputerPlayer())) { + if (ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) && ph.isPlayerTurn(ai)) { return false; } - if (ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS) && ph.isPlayerTurn(AllZone.getHumanPlayer())) { + if (ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS) && ph.isPlayerTurn(ai.getOpponent())) { return false; } } @@ -924,20 +922,20 @@ public class AbilityFactoryPump { return false; } - if (!containsUsefulKeyword(this.keywords, card, sa)) { + if (!containsUsefulKeyword(ai, this.keywords, card, sa)) { continue; } return r.nextFloat() <= Math.pow(.9, activations); } - if (shouldPumpCard(sa, card)) { + if (shouldPumpCard(ai, sa, card)) { return r.nextFloat() <= Math.pow(.9, activations); } } return false; } //Targeted - if (!this.pumpTgtAI(sa, defense, attack, false)) { + if (!this.pumpTgtAI(ai, sa, defense, attack, false)) { return false; } @@ -964,7 +962,7 @@ public class AbilityFactoryPump { * a boolean. * @return a boolean. */ - private boolean pumpTgtAI(final SpellAbility sa, final int defense, final int attack, final boolean mandatory) { + private boolean pumpTgtAI(final Player ai, final SpellAbility sa, final int defense, final int attack, final boolean mandatory) { if (!mandatory && !sa.isTrigger() && Singletons.getModel().getGameState().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY) @@ -973,6 +971,7 @@ public class AbilityFactoryPump { return false; } + final Player opp = ai.getOpponent(); final Target tgt = sa.getTarget(); tgt.resetTargets(); List list = new ArrayList(); @@ -989,20 +988,20 @@ public class AbilityFactoryPump { } } } else if (this.abilityFactory.isCurse()) { - if (sa.canTarget(AllZone.getHumanPlayer())) { - tgt.addTarget(AllZone.getHumanPlayer()); + if (sa.canTarget(opp)) { + tgt.addTarget(opp); return true; } - list = this.getCurseCreatures(sa, defense, attack); + list = this.getCurseCreatures(ai, sa, defense, attack); } else { if (!tgt.canTgtCreature()) { ZoneType zone = tgt.getZone().get(0); list = AllZoneUtil.getCardsIn(zone); } else { - list = this.getPumpCreatures(sa); + list = this.getPumpCreatures(ai, sa); } - if (sa.canTarget(AllZone.getComputerPlayer())) { - tgt.addTarget(AllZone.getComputerPlayer()); + if (sa.canTarget(ai)) { + tgt.addTarget(ai); return true; } } @@ -1013,18 +1012,18 @@ public class AbilityFactoryPump { // attack/block if ((sa.getPayCosts() != null) && sa.getPayCosts().getTap()) { if (Singletons.getModel().getGameState().getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) - && Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(AllZone.getComputerPlayer())) { + && Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(ai)) { list.remove(sa.getSourceCard()); } if (Singletons.getModel().getGameState().getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS) - && Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(AllZone.getHumanPlayer())) { + && Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(opp)) { list.remove(sa.getSourceCard()); } } } if (list.isEmpty()) { - return mandatory && this.pumpMandatoryTarget(this.abilityFactory, sa, mandatory); + return mandatory && this.pumpMandatoryTarget(ai, this.abilityFactory, sa, mandatory); } if (!this.abilityFactory.isCurse()) { @@ -1044,7 +1043,7 @@ public class AbilityFactoryPump { if (list.isEmpty()) { if ((tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) || (tgt.getNumTargeted() == 0)) { if (mandatory) { - return this.pumpMandatoryTarget(this.abilityFactory, sa, mandatory); + return this.pumpMandatoryTarget(ai, this.abilityFactory, sa, mandatory); } tgt.resetTargets(); @@ -1076,9 +1075,10 @@ public class AbilityFactoryPump { * a boolean. * @return a boolean. */ - private boolean pumpMandatoryTarget(final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { + private boolean pumpMandatoryTarget(final Player ai, final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { List list = AllZoneUtil.getCardsIn(ZoneType.Battlefield); final Target tgt = sa.getTarget(); + final Player opp = ai.getOpponent(); list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard()); list = CardLists.getTargetableCards(list, sa); @@ -1097,11 +1097,11 @@ public class AbilityFactoryPump { final Card source = sa.getSourceCard(); if (af.isCurse()) { - pref = CardLists.filterControlledBy(list, AllZone.getHumanPlayer()); - forced = CardLists.filterControlledBy(list, AllZone.getComputerPlayer()); + pref = CardLists.filterControlledBy(list, opp); + forced = CardLists.filterControlledBy(list, ai); } else { - pref = CardLists.filterControlledBy(list, AllZone.getComputerPlayer()); - forced = CardLists.filterControlledBy(list, AllZone.getHumanPlayer()); + pref = CardLists.filterControlledBy(list, ai); + forced = CardLists.filterControlledBy(list, opp); } while (tgt.getNumTargeted() < tgt.getMaxTargets(source, sa)) { @@ -1213,7 +1213,7 @@ public class AbilityFactoryPump { return true; } } else { - return this.pumpTgtAI(sa, defense, attack, mandatory); + return this.pumpTgtAI(ai, sa, defense, attack, mandatory); } return true; @@ -1228,7 +1228,7 @@ public class AbilityFactoryPump { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private boolean pumpDrawbackAI(final SpellAbility sa) { + private boolean pumpDrawbackAI(final Player ai, final SpellAbility sa) { final Card source = sa.getSourceCard(); int defense; if (this.numDefense.contains("X") && source.getSVar("X").equals("Count$xPaid")) { @@ -1256,7 +1256,7 @@ public class AbilityFactoryPump { } } else { //Targeted - if (!this.pumpTgtAI(sa, defense, attack, false)) { + if (!this.pumpTgtAI(ai, sa, defense, attack, false)) { return false; } @@ -1589,7 +1589,7 @@ public class AbilityFactoryPump { @Override public boolean canPlayAI() { - return AbilityFactoryPump.this.pumpAllCanPlayAI(this); + return AbilityFactoryPump.this.pumpAllCanPlayAI(getActivatingPlayer(), this); } @Override @@ -1628,7 +1628,7 @@ public class AbilityFactoryPump { @Override public boolean canPlayAI() { - return AbilityFactoryPump.this.pumpAllCanPlayAI(this); + return AbilityFactoryPump.this.pumpAllCanPlayAI(getActivatingPlayer(), this); } @Override @@ -1680,7 +1680,7 @@ public class AbilityFactoryPump { @Override public boolean canPlayAI() { - return AbilityFactoryPump.this.pumpAllCanPlayAI(this); + return AbilityFactoryPump.this.pumpAllCanPlayAI(getActivatingPlayer(), this); } @Override @@ -1708,7 +1708,7 @@ public class AbilityFactoryPump { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private boolean pumpAllCanPlayAI(final SpellAbility sa) { + private boolean pumpAllCanPlayAI(final Player ai, final SpellAbility sa) { String valid = ""; final Random r = MyRandom.getRandom(); final Card source = sa.getSourceCard(); @@ -1724,15 +1724,16 @@ public class AbilityFactoryPump { valid = this.params.get("ValidCards"); } - List comp = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); + final Player opp = ai.getOpponent(); + List comp = ai.getCardsIn(ZoneType.Battlefield); comp = CardLists.getValidCards(comp, valid, source.getController(), source); - List human = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield); + List human = opp.getCardsIn(ZoneType.Battlefield); human = CardLists.getValidCards(human, valid, source.getController(), source); final Target tgt = sa.getTarget(); - if (tgt != null && sa.canTarget(AllZone.getHumanPlayer()) && params.containsKey("IsCurse")) { + if (tgt != null && sa.canTarget(opp) && params.containsKey("IsCurse")) { tgt.resetTargets(); - sa.getTarget().addTarget(AllZone.getHumanPlayer()); + sa.getTarget().addTarget(opp); comp = new ArrayList(); } @@ -1775,7 +1776,7 @@ public class AbilityFactoryPump { comp = CardLists.filter(comp, new Predicate() { @Override public boolean apply(final Card c) { - if (power <= 0 && !containsUsefulKeyword(keywords, c, sa)) { + if (power <= 0 && !containsUsefulKeyword(ai, keywords, c, sa)) { return false; } if (phase.equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) && c.isAttacking()) { diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryRegenerate.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryRegenerate.java index b21af19d9e8..431b60810c6 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryRegenerate.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryRegenerate.java @@ -89,7 +89,7 @@ public class AbilityFactoryRegenerate { @Override public boolean canPlayAI() { - return AbilityFactoryRegenerate.regenerateCanPlayAI(af, this); + return AbilityFactoryRegenerate.regenerateCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -128,7 +128,7 @@ public class AbilityFactoryRegenerate { @Override public boolean canPlayAI() { - return AbilityFactoryRegenerate.regenerateCanPlayAI(af, this); + return AbilityFactoryRegenerate.regenerateCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -263,7 +263,7 @@ public class AbilityFactoryRegenerate { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private static boolean regenerateCanPlayAI(final AbilityFactory af, final SpellAbility sa) { + private static boolean regenerateCanPlayAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); final Card hostCard = af.getHostCard(); boolean chance = false; @@ -274,11 +274,11 @@ public class AbilityFactoryRegenerate { return false; } - if (!CostUtil.checkSacrificeCost(abCost, hostCard)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, hostCard)) { return false; } - if (!CostUtil.checkCreatureSacrificeCost(abCost, hostCard)) { + if (!CostUtil.checkCreatureSacrificeCost(ai, abCost, hostCard)) { return false; } } @@ -316,8 +316,8 @@ public class AbilityFactoryRegenerate { } else { tgt.resetTargets(); // filter AIs battlefield by what I can target - List targetables = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); - targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), AllZone.getComputerPlayer(), hostCard); + List targetables = ai.getCardsIn(ZoneType.Battlefield); + targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, hostCard); if (targetables.size() == 0) { return false; @@ -390,7 +390,7 @@ public class AbilityFactoryRegenerate { // If there's no target on the trigger, just say yes. chance = true; } else { - chance = AbilityFactoryRegenerate.regenMandatoryTarget(af, sa, mandatory); + chance = AbilityFactoryRegenerate.regenMandatoryTarget(ai, af, sa, mandatory); } final AbilitySub subAb = sa.getSubAbility(); @@ -414,14 +414,14 @@ public class AbilityFactoryRegenerate { * a boolean. * @return a boolean. */ - private static boolean regenMandatoryTarget(final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { + private static boolean regenMandatoryTarget(final Player ai, final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { final Card hostCard = af.getHostCard(); final Target tgt = sa.getTarget(); tgt.resetTargets(); // filter AIs battlefield by what I can target List targetables = AllZoneUtil.getCardsIn(ZoneType.Battlefield); - targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), AllZone.getComputerPlayer(), hostCard); - final List compTargetables = CardLists.filterControlledBy(targetables, AllZone.getComputerPlayer()); + targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, hostCard); + final List compTargetables = CardLists.filterControlledBy(targetables, ai); if (targetables.size() == 0) { return false; @@ -543,7 +543,7 @@ public class AbilityFactoryRegenerate { @Override public boolean canPlayAI() { - return AbilityFactoryRegenerate.regenerateAllCanPlayAI(af, this); + return AbilityFactoryRegenerate.regenerateAllCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -582,7 +582,7 @@ public class AbilityFactoryRegenerate { @Override public boolean canPlayAI() { - return AbilityFactoryRegenerate.regenerateAllCanPlayAI(af, this); + return AbilityFactoryRegenerate.regenerateAllCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -701,18 +701,18 @@ public class AbilityFactoryRegenerate { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private static boolean regenerateAllCanPlayAI(final AbilityFactory af, final SpellAbility sa) { + private static boolean regenerateAllCanPlayAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); final Card hostCard = af.getHostCard(); boolean chance = false; final Cost abCost = af.getAbCost(); if (abCost != null) { // AI currently disabled for these costs - if (!CostUtil.checkSacrificeCost(abCost, hostCard)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, hostCard)) { return false; } - if (!CostUtil.checkCreatureSacrificeCost(abCost, hostCard)) { + if (!CostUtil.checkCreatureSacrificeCost(ai, abCost, hostCard)) { return false; } @@ -730,7 +730,7 @@ public class AbilityFactoryRegenerate { List list = AllZoneUtil.getCardsIn(ZoneType.Battlefield); list = CardLists.getValidCards(list, valid.split(","), hostCard.getController(), hostCard); - list = CardLists.filter(list, CardPredicates.isController(AllZone.getComputerPlayer())); + list = CardLists.filter(list, CardPredicates.isController(ai)); if (list.size() == 0) { return false; diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryReveal.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryReveal.java index 1f2d0848219..af74b0bf091 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryReveal.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryReveal.java @@ -1293,11 +1293,11 @@ public final class AbilityFactoryReveal { return false; } - if (!CostUtil.checkDiscardCost(abCost, source)) { + if (!CostUtil.checkDiscardCost(ai, abCost, source)) { return false; } - if (!CostUtil.checkSacrificeCost(abCost, source)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, source)) { return false; } @@ -2279,11 +2279,11 @@ public final class AbilityFactoryReveal { return false; } - if (!CostUtil.checkDiscardCost(abCost, source)) { + if (!CostUtil.checkDiscardCost(ai, abCost, source)) { return false; } - if (!CostUtil.checkSacrificeCost(abCost, source)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, source)) { return false; } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryToken.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryToken.java index a2e9a3aa415..0df25b92f45 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryToken.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryToken.java @@ -359,11 +359,11 @@ public class AbilityFactoryToken extends AbilityFactory { return false; } - if (!CostUtil.checkDiscardCost(cost, source)) { + if (!CostUtil.checkDiscardCost(ai, cost, source)) { return false; } - if (!CostUtil.checkSacrificeCost(cost, source)) { + if (!CostUtil.checkSacrificeCost(ai, cost, source)) { return false; } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java index be46504e937..2cba9ec8aab 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java @@ -81,7 +81,7 @@ public class AbilityFactoryTurns { @Override public boolean canPlayAI() { - return AbilityFactoryTurns.addTurnCanPlayAI(af, this); + return AbilityFactoryTurns.addTurnCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -119,7 +119,7 @@ public class AbilityFactoryTurns { @Override public boolean canPlayAI() { - return AbilityFactoryTurns.addTurnCanPlayAI(af, this); + return AbilityFactoryTurns.addTurnCanPlayAI(getActivatingPlayer(), af, this); } @Override @@ -130,7 +130,7 @@ public class AbilityFactoryTurns { @Override public boolean canPlayFromEffectAI(final boolean mandatory, final boolean withOutManaCost) { if (withOutManaCost) { - return AbilityFactoryTurns.addTurnTriggerAINoCost(af, this, mandatory); + return AbilityFactoryTurns.addTurnTriggerAINoCost(getActivatingPlayer(), af, this, mandatory); } return AbilityFactoryTurns.addTurnTriggerAI(getActivatingPlayer(), af, this, mandatory); } @@ -255,8 +255,8 @@ public class AbilityFactoryTurns { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - private static boolean addTurnCanPlayAI(final AbilityFactory af, final SpellAbility sa) { - return AbilityFactoryTurns.addTurnTriggerAINoCost(af, sa, false); + private static boolean addTurnCanPlayAI(final Player ai, final AbilityFactory af, final SpellAbility sa) { + return AbilityFactoryTurns.addTurnTriggerAINoCost(ai, af, sa, false); } /** @@ -276,7 +276,7 @@ public class AbilityFactoryTurns { if (!ComputerUtil.canPayCost(sa, ai) && !mandatory) { return false; } - return addTurnTriggerAINoCost(af, sa, mandatory); + return addTurnTriggerAINoCost(ai, af, sa, mandatory); } /** @@ -292,18 +292,19 @@ public class AbilityFactoryTurns { * a boolean. * @return a boolean. */ - private static boolean addTurnTriggerAINoCost(final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { + private static boolean addTurnTriggerAINoCost(final Player ai, final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { final HashMap params = af.getMapParams(); + final Player opp = ai.getOpponent(); final Target tgt = sa.getTarget(); if (sa.getTarget() != null) { tgt.resetTargets(); - if (sa.canTarget(AllZone.getComputerPlayer())) { - sa.getTarget().addTarget(AllZone.getComputerPlayer()); - } else if (mandatory && sa.canTarget(AllZone.getHumanPlayer())) { - sa.getTarget().addTarget(AllZone.getHumanPlayer()); + if (sa.canTarget(ai)) { + sa.getTarget().addTarget(ai); + } else if (mandatory && sa.canTarget(opp)) { + sa.getTarget().addTarget(opp); } else { return false; } @@ -520,10 +521,10 @@ public class AbilityFactoryTurns { // Update observers AllZone.getStack().updateObservers(); - AllZone.getComputerPlayer().updateObservers(); - AllZone.getHumanPlayer().updateObservers(); - AllZone.getComputerPlayer().updateLabelObservers(); - AllZone.getHumanPlayer().updateLabelObservers(); + for (Player p : AllZone.getPlayersInGame()) { + p.updateObservers(); + p.updateLabelObservers(); + } } } // end class AbilityFactory_Turns diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryZoneAffecting.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryZoneAffecting.java index 539b87ca908..7764577b616 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryZoneAffecting.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryZoneAffecting.java @@ -25,7 +25,6 @@ import java.util.Iterator; import java.util.List; import java.util.Random; -import forge.AllZone; import forge.Card; import forge.CardLists; @@ -301,7 +300,7 @@ public class AbilityFactoryZoneAffecting { if (abCost != null) { // AI currently disabled for these costs - if (!CostUtil.checkCreatureSacrificeCost(abCost, source)) { + if (!CostUtil.checkCreatureSacrificeCost(ai, abCost, source)) { return false; } @@ -309,14 +308,14 @@ public class AbilityFactoryZoneAffecting { return false; } - if (!CostUtil.checkDiscardCost(abCost, source)) { + if (!CostUtil.checkDiscardCost(ai, abCost, source)) { for (final CostPart part : abCost.getCostParts()) { if (part instanceof CostDiscard) { CostDiscard cd = (CostDiscard) part; - cd.decideAIPayment(sa, sa.getSourceCard(), null); + cd.decideAIPayment(ai, sa, sa.getSourceCard(), null); List discards = cd.getList(); for (Card discard : discards) { - if (!ComputerUtil.isWorseThanDraw(discard)) { + if (!ComputerUtil.isWorseThanDraw(ai, discard)) { return false; } } @@ -879,11 +878,11 @@ public class AbilityFactoryZoneAffecting { return false; } - if (!CostUtil.checkDiscardCost(abCost, source)) { + if (!CostUtil.checkDiscardCost(ai, abCost, source)) { return false; } - if (!CostUtil.checkSacrificeCost(abCost, source)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, source)) { return false; } @@ -924,8 +923,7 @@ public class AbilityFactoryZoneAffecting { if (params.get("NumCards").equals("X") && source.getSVar("X").startsWith("Count$xPaid")) { // Set PayX here to maximum value. - final int cardsToDiscard = Math.min(ComputerUtil.determineLeftoverMana(sa, ai), AllZone.getHumanPlayer() - .getCardsIn(ZoneType.Library).size()); + final int cardsToDiscard = Math.min(ComputerUtil.determineLeftoverMana(sa, ai), ai.getOpponent().getCardsIn(ZoneType.Library).size()); source.setSVar("PayX", Integer.toString(cardsToDiscard)); if (cardsToDiscard <= 0) { return false; @@ -1413,7 +1411,7 @@ public class AbilityFactoryZoneAffecting { if (p.isComputer()) { // discard AI cards int max = chooser.getCardsIn(ZoneType.Hand).size(); max = Math.min(max, numCards); - List list = ComputerUtil.discardNumTypeAI(max, dValid, sa); + List list = ComputerUtil.discardNumTypeAI(p, max, dValid, sa); if (mode.startsWith("Reveal")) { GuiChoose.oneOrNone("Computer has chosen", list); } @@ -1602,7 +1600,7 @@ public class AbilityFactoryZoneAffecting { if (abCost != null) { // AI currently disabled for these costs - if (!CostUtil.checkSacrificeCost(abCost, source)) { + if (!CostUtil.checkSacrificeCost(ai, abCost, source)) { return false; } @@ -1610,7 +1608,7 @@ public class AbilityFactoryZoneAffecting { return false; } - if (!CostUtil.checkDiscardCost(abCost, source)) { + if (!CostUtil.checkDiscardCost(ai, abCost, source)) { return false; } diff --git a/src/main/java/forge/card/cardfactory/CardFactory.java b/src/main/java/forge/card/cardfactory/CardFactory.java index 4955b1b3a4b..11c34278cf4 100644 --- a/src/main/java/forge/card/cardfactory/CardFactory.java +++ b/src/main/java/forge/card/cardfactory/CardFactory.java @@ -217,10 +217,10 @@ public class CardFactory implements CardFactoryInterface { } else if (copySA instanceof Spell) { Spell spell = (Spell) copySA; if (spell.canPlayFromEffectAI(false, true)) { - ComputerUtil.playStackFree(copySA); + ComputerUtil.playStackFree(controller, copySA); } } else if (copySA.canPlayAI()) { - ComputerUtil.playStackFree(copySA); + ComputerUtil.playStackFree(controller, copySA); } c.addController(originalController); diff --git a/src/main/java/forge/card/cardfactory/CardFactorySorceries.java b/src/main/java/forge/card/cardfactory/CardFactorySorceries.java index 517adc6e822..3d04f2156d2 100644 --- a/src/main/java/forge/card/cardfactory/CardFactorySorceries.java +++ b/src/main/java/forge/card/cardfactory/CardFactorySorceries.java @@ -148,7 +148,7 @@ public class CardFactorySorceries { for (final SpellAbility sa : choices) { if (sa.canPlayAI()) { - ComputerUtil.playStackFree(sa); + ComputerUtil.playStackFree(sa.getActivatingPlayer(), sa); if (pile1.get(i).isPermanent()) { exiled.remove(pile1.get(i)); } @@ -164,7 +164,7 @@ public class CardFactorySorceries { for (final SpellAbility sa : choices) { if (sa.canPlayAI()) { - ComputerUtil.playStackFree(sa); + ComputerUtil.playStackFree(sa.getActivatingPlayer(), sa); if (pile2.get(i).isPermanent()) { exiled.remove(pile2.get(i)); } diff --git a/src/main/java/forge/card/cost/CostDamage.java b/src/main/java/forge/card/cost/CostDamage.java index b7e2bba869b..cca5eefddd1 100644 --- a/src/main/java/forge/card/cost/CostDamage.java +++ b/src/main/java/forge/card/cost/CostDamage.java @@ -151,7 +151,7 @@ public class CostDamage extends CostPart { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { Integer c = this.convertAmount(); if (c == null) { diff --git a/src/main/java/forge/card/cost/CostDiscard.java b/src/main/java/forge/card/cost/CostDiscard.java index e51b2d8426f..5416765285c 100644 --- a/src/main/java/forge/card/cost/CostDiscard.java +++ b/src/main/java/forge/card/cost/CostDiscard.java @@ -270,16 +270,16 @@ public class CostDiscard extends CostPartWithList { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { final String type = this.getType(); - final Player activator = ability.getActivatingPlayer(); - final List hand = activator.getCardsIn(ZoneType.Hand); + + final List hand = ai.getCardsIn(ZoneType.Hand); this.resetList(); if (type.equals("LastDrawn")) { - if (!hand.contains(activator.getLastDrawnCard())) { + if (!hand.contains(ai.getLastDrawnCard())) { return false; } - this.addToList(activator.getLastDrawnCard()); + this.addToList(ai.getLastDrawnCard()); } else if (this.getThis()) { @@ -310,7 +310,7 @@ public class CostDiscard extends CostPartWithList { if (type.equals("Random")) { this.setList(CardLists.getRandomSubList(hand, c)); } else { - this.setList(ComputerUtil.discardNumTypeAI(c, type.split(";"), ability)); + this.setList(ComputerUtil.discardNumTypeAI(ai, c, type.split(";"), ability)); } } return this.getList() != null; diff --git a/src/main/java/forge/card/cost/CostExile.java b/src/main/java/forge/card/cost/CostExile.java index b16fd55857b..7f21219473e 100644 --- a/src/main/java/forge/card/cost/CostExile.java +++ b/src/main/java/forge/card/cost/CostExile.java @@ -237,7 +237,7 @@ public class CostExile extends CostPartWithList { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { this.resetList(); if (this.getThis()) { this.getList().add(source); @@ -258,7 +258,7 @@ public class CostExile extends CostPartWithList { } if (this.from.equals(ZoneType.Library)) { - this.setList(AllZone.getComputerPlayer().getCardsIn(ZoneType.Library, c)); + this.setList(ai.getCardsIn(ZoneType.Library, c)); } else { this.setList(ComputerUtil.chooseExileFrom(this.getFrom(), this.getType(), source, ability.getTargetCard(), c)); diff --git a/src/main/java/forge/card/cost/CostGainLife.java b/src/main/java/forge/card/cost/CostGainLife.java index 673b34f4d23..3f0e21b8db4 100644 --- a/src/main/java/forge/card/cost/CostGainLife.java +++ b/src/main/java/forge/card/cost/CostGainLife.java @@ -156,8 +156,8 @@ public class CostGainLife extends CostPart { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { - final Player activator = ability.getActivatingPlayer(); + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { + Integer c = this.convertAmount(); if (c == null) { @@ -169,7 +169,7 @@ public class CostGainLife extends CostPart { c = AbilityFactory.calculateAmount(source, this.getAmount(), ability); } } - if (!activator.getOpponent().canGainLife()) { + if (!ai.getOpponent().canGainLife()) { return false; } this.setLastPaidAmount(c); diff --git a/src/main/java/forge/card/cost/CostMana.java b/src/main/java/forge/card/cost/CostMana.java index ddaa09206ac..62486bf9659 100644 --- a/src/main/java/forge/card/cost/CostMana.java +++ b/src/main/java/forge/card/cost/CostMana.java @@ -239,7 +239,7 @@ public class CostMana extends CostPart { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { return true; } diff --git a/src/main/java/forge/card/cost/CostMill.java b/src/main/java/forge/card/cost/CostMill.java index ad292ed1937..e8f0062c131 100644 --- a/src/main/java/forge/card/cost/CostMill.java +++ b/src/main/java/forge/card/cost/CostMill.java @@ -20,7 +20,6 @@ package forge.card.cost; import java.util.Iterator; import java.util.List; -import forge.AllZone; import forge.Card; import forge.GameActionUtil; @@ -81,7 +80,7 @@ public class CostMill extends CostPartWithList { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { this.resetList(); Integer c = this.convertAmount(); @@ -95,7 +94,7 @@ public class CostMill extends CostPartWithList { c = AbilityFactory.calculateAmount(source, this.getAmount(), ability); } - this.setList(AllZone.getComputerPlayer().getCardsIn(ZoneType.Library, c)); + this.setList(ai.getCardsIn(ZoneType.Library, c)); if ((this.getList() == null) || (this.getList().size() < c)) { return false; diff --git a/src/main/java/forge/card/cost/CostPart.java b/src/main/java/forge/card/cost/CostPart.java index b47ef612e3f..de6e2c5f4e0 100644 --- a/src/main/java/forge/card/cost/CostPart.java +++ b/src/main/java/forge/card/cost/CostPart.java @@ -191,7 +191,7 @@ public abstract class CostPart { * the payment * @return true, if successful */ - public abstract boolean decideAIPayment(SpellAbility ability, Card source, CostPayment payment); + public abstract boolean decideAIPayment(final Player ai, SpellAbility ability, Card source, CostPayment payment); /** * Pay ai. diff --git a/src/main/java/forge/card/cost/CostPayLife.java b/src/main/java/forge/card/cost/CostPayLife.java index 305d50bbaa1..194d435e7c7 100644 --- a/src/main/java/forge/card/cost/CostPayLife.java +++ b/src/main/java/forge/card/cost/CostPayLife.java @@ -161,8 +161,7 @@ public class CostPayLife extends CostPart { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { - final Player activator = ability.getActivatingPlayer(); + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { Integer c = this.convertAmount(); if (c == null) { @@ -174,7 +173,7 @@ public class CostPayLife extends CostPart { c = AbilityFactory.calculateAmount(source, this.getAmount(), ability); } } - if (!activator.canPayLife(c)) { + if (!ai.canPayLife(c)) { return false; } // activator.payLife(c, null); diff --git a/src/main/java/forge/card/cost/CostPayment.java b/src/main/java/forge/card/cost/CostPayment.java index afde7583b1f..51a8525e81c 100644 --- a/src/main/java/forge/card/cost/CostPayment.java +++ b/src/main/java/forge/card/cost/CostPayment.java @@ -281,13 +281,12 @@ public class CostPayment { * * @return a boolean. */ - public final boolean payComputerCosts() { + public final boolean payComputerCosts(final Player ai) { // canPayAdditionalCosts now Player Agnostic // Just in case it wasn't set, but honestly it shouldn't have gotten // here without being set - final Player activator = AllZone.getComputerPlayer(); - this.ability.setActivatingPlayer(activator); + this.ability.setActivatingPlayer(ai); final Card source = this.ability.getSourceCard(); final ArrayList parts = this.cost.getCostParts(); @@ -298,7 +297,7 @@ public class CostPayment { // Set all of the decisions before attempting to pay anything for (final CostPart part : parts) { - if (!part.decideAIPayment(this.ability, source, this)) { + if (!part.decideAIPayment(ai, this.ability, source, this)) { return false; } } diff --git a/src/main/java/forge/card/cost/CostPutCounter.java b/src/main/java/forge/card/cost/CostPutCounter.java index 23c0ead6c47..444adee3ea8 100644 --- a/src/main/java/forge/card/cost/CostPutCounter.java +++ b/src/main/java/forge/card/cost/CostPutCounter.java @@ -204,19 +204,18 @@ public class CostPutCounter extends CostPartWithList { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { this.resetList(); if (this.getThis()) { this.addToList(source); return true; } else { - final Player activator = ability.getActivatingPlayer(); Integer c = this.convertAmount(); if (c == null) { c = AbilityFactory.calculateAmount(source, this.getAmount(), ability); } - final List typeList = CardLists.getValidCards(activator.getCardsIn(ZoneType.Battlefield), this.getType().split(";"), activator, source); + final List typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), this.getType().split(";"), ai, source); Card card = null; if (this.getType().equals("Creature.YouCtrl")) { diff --git a/src/main/java/forge/card/cost/CostRemoveCounter.java b/src/main/java/forge/card/cost/CostRemoveCounter.java index 7e03788a3a4..ae83e7e95be 100644 --- a/src/main/java/forge/card/cost/CostRemoveCounter.java +++ b/src/main/java/forge/card/cost/CostRemoveCounter.java @@ -21,7 +21,6 @@ import java.util.List; import forge.Card; -import forge.AllZone; import forge.CardLists; import forge.Counters; import forge.card.abilityfactory.AbilityFactory; @@ -268,10 +267,10 @@ public class CostRemoveCounter extends CostPartWithList { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { final String amount = this.getAmount(); Integer c = this.convertAmount(); - Player computer = AllZone.getComputerPlayer(); + if (c == null) { final String sVar = ability.getSVar(amount); @@ -287,8 +286,7 @@ public class CostRemoveCounter extends CostPartWithList { if (!this.getThis()) { this.getList().clear(); - final List typeList = CardLists - .getValidCards(computer.getCardsIn(this.getZone()), this.getType().split(";"), computer, source); + final List typeList = CardLists.getValidCards(ai.getCardsIn(this.getZone()), this.getType().split(";"), ai, source); for (Card card : typeList) { if (card.getCounters(this.getCounter()) >= c) { this.addToList(card); diff --git a/src/main/java/forge/card/cost/CostReturn.java b/src/main/java/forge/card/cost/CostReturn.java index 5a1bcf481aa..916dcd9262e 100644 --- a/src/main/java/forge/card/cost/CostReturn.java +++ b/src/main/java/forge/card/cost/CostReturn.java @@ -174,7 +174,7 @@ public class CostReturn extends CostPartWithList { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { this.resetList(); if (this.getThis()) { this.getList().add(source); diff --git a/src/main/java/forge/card/cost/CostReveal.java b/src/main/java/forge/card/cost/CostReveal.java index 581274f8444..ae29693814b 100644 --- a/src/main/java/forge/card/cost/CostReveal.java +++ b/src/main/java/forge/card/cost/CostReveal.java @@ -96,10 +96,9 @@ public class CostReveal extends CostPartWithList { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { final String type = this.getType(); - final Player activator = ability.getActivatingPlayer(); - List hand = activator.getCardsIn(ZoneType.Hand); + List hand = ai.getCardsIn(ZoneType.Hand); this.resetList(); if (this.getThis()) { @@ -109,10 +108,10 @@ public class CostReveal extends CostPartWithList { this.getList().add(source); } else if (this.getType().equals("Hand")) { - this.setList(activator.getCardsIn(ZoneType.Hand)); + this.setList(ai.getCardsIn(ZoneType.Hand)); return true; } else { - hand = CardLists.getValidCards(hand, type.split(";"), activator, source); + hand = CardLists.getValidCards(hand, type.split(";"), ai, source); Integer c = this.convertAmount(); if (c == null) { final String sVar = ability.getSVar(this.getAmount()); @@ -123,7 +122,7 @@ public class CostReveal extends CostPartWithList { } } - this.setList(ComputerUtil.discardNumTypeAI(c, type.split(";"), ability)); + this.setList(ComputerUtil.discardNumTypeAI(ai, c, type.split(";"), ability)); } return this.getList() != null; } diff --git a/src/main/java/forge/card/cost/CostSacrifice.java b/src/main/java/forge/card/cost/CostSacrifice.java index 5b310017247..5060ab2c564 100644 --- a/src/main/java/forge/card/cost/CostSacrifice.java +++ b/src/main/java/forge/card/cost/CostSacrifice.java @@ -199,7 +199,7 @@ public class CostSacrifice extends CostPartWithList { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { this.resetList(); final Player activator = ability.getActivatingPlayer(); if (this.getThis()) { @@ -221,7 +221,7 @@ public class CostSacrifice extends CostPartWithList { c = AbilityFactory.calculateAmount(source, this.getAmount(), ability); } - this.setList(ComputerUtil.chooseSacrificeType(this.getType(), source, ability.getTargetCard(), c)); + this.setList(ComputerUtil.chooseSacrificeType(activator, this.getType(), source, ability.getTargetCard(), c)); if (this.getList() == null) { return false; } diff --git a/src/main/java/forge/card/cost/CostTap.java b/src/main/java/forge/card/cost/CostTap.java index b3e5abec0b5..cd643202937 100644 --- a/src/main/java/forge/card/cost/CostTap.java +++ b/src/main/java/forge/card/cost/CostTap.java @@ -103,7 +103,7 @@ public class CostTap extends CostPart { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { return true; } } diff --git a/src/main/java/forge/card/cost/CostTapType.java b/src/main/java/forge/card/cost/CostTapType.java index 9db9200f700..8ed08edb111 100644 --- a/src/main/java/forge/card/cost/CostTapType.java +++ b/src/main/java/forge/card/cost/CostTapType.java @@ -181,14 +181,14 @@ public class CostTapType extends CostPartWithList { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { final boolean tap = payment.getCost().getTap(); final String amount = this.getAmount(); Integer c = this.convertAmount(); if (c == null) { final String sVar = ability.getSVar(amount); if (sVar.equals("XChoice")) { - List typeList = ability.getActivatingPlayer().getCardsIn(ZoneType.Battlefield); + List typeList = ai.getCardsIn(ZoneType.Battlefield); typeList = CardLists.getValidCards(typeList, this.getType().split(";"), ability.getActivatingPlayer(), ability.getSourceCard()); typeList = CardLists.filter(typeList, Presets.UNTAPPED); c = typeList.size(); diff --git a/src/main/java/forge/card/cost/CostUntap.java b/src/main/java/forge/card/cost/CostUntap.java index ce5cbce9a95..87be288c1bd 100644 --- a/src/main/java/forge/card/cost/CostUntap.java +++ b/src/main/java/forge/card/cost/CostUntap.java @@ -103,7 +103,7 @@ public class CostUntap extends CostPart { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { return true; } } diff --git a/src/main/java/forge/card/cost/CostUntapType.java b/src/main/java/forge/card/cost/CostUntapType.java index 383be4201da..d4121339ea4 100644 --- a/src/main/java/forge/card/cost/CostUntapType.java +++ b/src/main/java/forge/card/cost/CostUntapType.java @@ -190,7 +190,7 @@ public class CostUntapType extends CostPartWithList { * , forge.Card, forge.card.cost.Cost_Payment) */ @Override - public final boolean decideAIPayment(final SpellAbility ability, final Card source, final CostPayment payment) { + public final boolean decideAIPayment(final Player ai, final SpellAbility ability, final Card source, final CostPayment payment) { final boolean untap = payment.getCost().getUntap(); final String amount = this.getAmount(); Integer c = this.convertAmount(); @@ -198,7 +198,7 @@ public class CostUntapType extends CostPartWithList { final String sVar = ability.getSVar(amount); if (sVar.equals("XChoice")) { List typeList = AllZoneUtil.getCardsIn(ZoneType.Battlefield); - typeList = CardLists.getValidCards(typeList, this.getType().split(";"), ability.getActivatingPlayer(), ability.getSourceCard()); + typeList = CardLists.getValidCards(typeList, this.getType().split(";"), ai, ability.getSourceCard()); if (untap) { typeList.remove(source); } diff --git a/src/main/java/forge/card/cost/CostUtil.java b/src/main/java/forge/card/cost/CostUtil.java index c2f9653a0d5..f36506518b5 100644 --- a/src/main/java/forge/card/cost/CostUtil.java +++ b/src/main/java/forge/card/cost/CostUtil.java @@ -50,8 +50,8 @@ public class CostUtil { * the source * @return true, if successful */ - public static boolean checkSacrificeCost(final Cost cost, final Card source) { - return checkSacrificeCost(cost, source, true); + public static boolean checkSacrificeCost(final Player ai, final Cost cost, final Card source) { + return checkSacrificeCost(ai, cost, source, true); } /** @@ -65,7 +65,7 @@ public class CostUtil { * is the gain important enough? * @return true, if successful */ - public static boolean checkSacrificeCost(final Cost cost, final Card source, final boolean important) { + public static boolean checkSacrificeCost(final Player ai, final Cost cost, final Card source, final boolean important) { if (cost == null) { return true; } @@ -86,9 +86,9 @@ public class CostUtil { continue; } - List typeList = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); + List typeList = ai.getCardsIn(ZoneType.Battlefield); typeList = CardLists.getValidCards(typeList, type.split(","), source.getController(), source); - if (ComputerUtil.getCardPreference(source, "SacCost", typeList) == null) { + if (ComputerUtil.getCardPreference(ai, source, "SacCost", typeList) == null) { return false; } } @@ -105,7 +105,7 @@ public class CostUtil { * the source * @return true, if successful */ - public static boolean checkCreatureSacrificeCost(final Cost cost, final Card source) { + public static boolean checkCreatureSacrificeCost(final Player ai, final Cost cost, final Card source) { if (cost == null) { return true; } @@ -121,9 +121,9 @@ public class CostUtil { continue; } - List typeList = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); + List typeList = ai.getCardsIn(ZoneType.Battlefield); typeList = CardLists.getValidCards(typeList, type.split(","), source.getController(), source); - if (ComputerUtil.getCardPreference(source, "SacCost", typeList) == null) { + if (ComputerUtil.getCardPreference(ai, source, "SacCost", typeList) == null) { return false; } } @@ -207,7 +207,7 @@ public class CostUtil { * the source * @return true, if successful */ - public static boolean checkDiscardCost(final Cost cost, final Card source) { + public static boolean checkDiscardCost(final Player ai, final Cost cost, final Card source) { if (cost == null) { return true; } @@ -216,12 +216,12 @@ public class CostUtil { final CostDiscard disc = (CostDiscard) part; final String type = disc.getType(); - List typeList = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand); - if (typeList.size() > AllZone.getComputerPlayer().getMaxHandSize()) { + List typeList = ai.getCardsIn(ZoneType.Hand); + if (typeList.size() > ai.getMaxHandSize()) { continue; } typeList = CardLists.getValidCards(typeList, type.split(","), source.getController(), source); - if (ComputerUtil.getCardPreference(source, "DiscardCost", typeList) == null) { + if (ComputerUtil.getCardPreference(ai, source, "DiscardCost", typeList) == null) { return false; } } diff --git a/src/main/java/forge/card/spellability/SpellPermanent.java b/src/main/java/forge/card/spellability/SpellPermanent.java index 596e2933153..0475e81f60d 100644 --- a/src/main/java/forge/card/spellability/SpellPermanent.java +++ b/src/main/java/forge/card/spellability/SpellPermanent.java @@ -295,7 +295,7 @@ public class SpellPermanent extends Spell { } // Wait for Main2 if possible if (Singletons.getModel().getGameState().getPhaseHandler().is(PhaseType.MAIN1) - && !ComputerUtil.castPermanentInMain1(this)) { + && !ComputerUtil.castPermanentInMain1(this, ai)) { return false; } // save cards with flash for surprise blocking @@ -327,6 +327,7 @@ public class SpellPermanent extends Spell { if (mandatory) { return true; } + final Player ai = getActivatingPlayer(); final Card card = this.getSourceCard(); String mana = this.getPayCosts().getTotalMana(); final Cost cost = this.getPayCosts(); @@ -337,11 +338,11 @@ public class SpellPermanent extends Spell { return false; } - if (!CostUtil.checkDiscardCost(cost, card)) { + if (!CostUtil.checkDiscardCost(ai, cost, card)) { return false; } - if (!CostUtil.checkSacrificeCost(cost, card)) { + if (!CostUtil.checkSacrificeCost(ai, cost, card)) { return false; } @@ -352,13 +353,13 @@ public class SpellPermanent extends Spell { // check on legendary if (card.isType("Legendary") && !AllZoneUtil.isCardInPlay("Mirror Gallery")) { - final List list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); + final List list = ai.getCardsIn(ZoneType.Battlefield); if (Iterables.any(list, CardPredicates.nameEquals(card.getName()))) { return false; } } if (card.isPlaneswalker()) { - List list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); + List list = ai.getCardsIn(ZoneType.Battlefield); list = CardLists.filter(list, CardPredicates.Presets.PLANEWALKERS); for (int i = 0; i < list.size(); i++) { @@ -372,7 +373,7 @@ public class SpellPermanent extends Spell { } } if (card.isType("World")) { - List list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); + List list = ai.getCardsIn(ZoneType.Battlefield); list = CardLists.getType(list, "World"); if (list.size() > 0) { return false; diff --git a/src/main/java/forge/game/phase/CombatUtil.java b/src/main/java/forge/game/phase/CombatUtil.java index 28e4b770ce7..bcb4bb10a02 100644 --- a/src/main/java/forge/game/phase/CombatUtil.java +++ b/src/main/java/forge/game/phase/CombatUtil.java @@ -305,7 +305,7 @@ public class CombatUtil { * the attackers * @return true, if one can be blocked */ - public static boolean canBlockAtLeastOne(final Card blocker, final List attackers) { + public static boolean canBlockAtLeastOne(final Card blocker, final Iterable attackers) { for (Card attacker : attackers) { if (CombatUtil.canBlock(attacker, blocker)) { return true; diff --git a/src/main/java/forge/game/phase/PhaseHandler.java b/src/main/java/forge/game/phase/PhaseHandler.java index c8fd97cff48..c0a7d6f0f3c 100644 --- a/src/main/java/forge/game/phase/PhaseHandler.java +++ b/src/main/java/forge/game/phase/PhaseHandler.java @@ -433,10 +433,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { c.resetReceivedDamageFromThisTurn(); c.resetDealtDamageToThisTurn(); c.resetDealtDamageToPlayerThisTurn(); - c.getDamageHistory().setDealtDmgToHumanThisTurn(false); - c.getDamageHistory().setDealtDmgToComputerThisTurn(false); - c.getDamageHistory().setDealtCombatDmgToHumanThisTurn(false); - c.getDamageHistory().setDealtCombatDmgToComputerThisTurn(false); + c.getDamageHistory().newTurn(); c.setRegeneratedThisTurn(0); c.clearMustBlockCards(); if (this.isPlayerTurn(AllZone.getComputerPlayer())) { diff --git a/src/main/java/forge/game/phase/Upkeep.java b/src/main/java/forge/game/phase/Upkeep.java index f8f465fa9df..7b34bb0e49e 100644 --- a/src/main/java/forge/game/phase/Upkeep.java +++ b/src/main/java/forge/game/phase/Upkeep.java @@ -378,7 +378,7 @@ public class Upkeep extends Phase implements java.io.Serializable { GameActionUtil.payCostDuringAbilityResolve(blankAbility, blankAbility.getPayCosts(), paidCommand, unpaidCommand, null); } else { // computer - if (ComputerUtil.shouldPayCost(c, upkeepCost) && ComputerUtil.canPayCost(blankAbility, controller)) { + if (ComputerUtil.shouldPayCost(controller, c, upkeepCost) && ComputerUtil.canPayCost(blankAbility, controller)) { ComputerUtil.playNoStack(controller, blankAbility); } else { Singletons.getModel().getGameAction().sacrifice(c, null); @@ -972,7 +972,7 @@ public class Upkeep extends Phase implements java.io.Serializable { for (final SpellAbility sa : choices) { if (sa.canPlayAI()) { - ComputerUtil.playStackFree(sa); + ComputerUtil.playStackFree(player, sa); break; } } diff --git a/src/main/java/forge/game/player/AIPlayer.java b/src/main/java/forge/game/player/AIPlayer.java index f2eaf0c3602..e7aa5591797 100644 --- a/src/main/java/forge/game/player/AIPlayer.java +++ b/src/main/java/forge/game/player/AIPlayer.java @@ -155,7 +155,7 @@ public class AIPlayer extends Player { public final List discard(final int num, final SpellAbility sa, final boolean duringResolution) { int max = this.getCardsIn(ZoneType.Hand).size(); max = Math.min(max, num); - final List discarded = ComputerUtil.discardNumTypeAI(max, null, sa); + final List discarded = ComputerUtil.discardNumTypeAI(this, max, null, sa); for (int i = 0; i < discarded.size(); i++) { this.doDiscard(discarded.get(i), sa); } diff --git a/src/main/java/forge/game/player/ComputerAIGeneral.java b/src/main/java/forge/game/player/ComputerAIGeneral.java index 0bb72c0f787..88a30b63604 100644 --- a/src/main/java/forge/game/player/ComputerAIGeneral.java +++ b/src/main/java/forge/game/player/ComputerAIGeneral.java @@ -49,13 +49,14 @@ import forge.game.zone.ZoneType; */ public class ComputerAIGeneral implements Computer { + final private Player player; /** *

* Constructor for ComputerAI_General. *

*/ - public ComputerAIGeneral() { - + public ComputerAIGeneral(Player computerPlayer) { + player = computerPlayer; } /** @@ -65,7 +66,7 @@ public class ComputerAIGeneral implements Computer { */ @Override public final void main() { - ComputerUtil.chooseLandsToPlay(); + ComputerUtil.chooseLandsToPlay(player); this.playSpellAbilitiesStackEmpty(); } // main() @@ -81,7 +82,7 @@ public class ComputerAIGeneral implements Computer { private void playSpellAbilitiesStackEmpty() { final List list = getAvailableCards(); - final boolean nextPhase = ComputerUtil.playSpellAbilities(getSpellAbilities(list)); + final boolean nextPhase = ComputerUtil.playSpellAbilities(player, getSpellAbilities(list)); if (nextPhase) { Singletons.getModel().getGameState().getPhaseHandler().passPriority(); @@ -95,10 +96,10 @@ public class ComputerAIGeneral implements Computer { * * @return a boolean. */ - public static boolean hasACardGivingHaste() { - final List all = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); - all.addAll(CardFactoryUtil.getExternalZoneActivationCards(AllZone.getComputerPlayer())); - all.addAll(AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand)); + public static boolean hasACardGivingHaste(final Player ai) { + final List all = ai.getCardsIn(ZoneType.Battlefield); + all.addAll(CardFactoryUtil.getExternalZoneActivationCards(ai)); + all.addAll(ai.getCardsIn(ZoneType.Hand)); for (final Card c : all) { for (final SpellAbility sa : c.getSpellAbility()) { @@ -130,17 +131,17 @@ public class ComputerAIGeneral implements Computer { * @return a {@link forge.CardList} object. */ private List getAvailableCards() { - final Player computer = AllZone.getComputerPlayer(); - final Player human = AllZone.getHumanPlayer(); - List all = computer.getCardsIn(ZoneType.Hand); - all.addAll(computer.getCardsIn(ZoneType.Battlefield)); - all.addAll(computer.getCardsIn(ZoneType.Exile)); - all.addAll(computer.getCardsIn(ZoneType.Graveyard)); - if (!computer.getCardsIn(ZoneType.Library).isEmpty()) { - all.add(computer.getCardsIn(ZoneType.Library).get(0)); + + final Player opp = player.getOpponent(); + List all = player.getCardsIn(ZoneType.Hand); + all.addAll(player.getCardsIn(ZoneType.Battlefield)); + all.addAll(player.getCardsIn(ZoneType.Exile)); + all.addAll(player.getCardsIn(ZoneType.Graveyard)); + if (!player.getCardsIn(ZoneType.Library).isEmpty()) { + all.add(player.getCardsIn(ZoneType.Library).get(0)); } - all.addAll(human.getCardsIn(ZoneType.Exile)); - all.addAll(human.getCardsIn(ZoneType.Battlefield)); + all.addAll(opp.getCardsIn(ZoneType.Exile)); + all.addAll(opp.getCardsIn(ZoneType.Battlefield)); return all; } @@ -208,15 +209,15 @@ public class ComputerAIGeneral implements Computer { * @return a {@link java.util.ArrayList} object. */ private ArrayList getPossibleETBCounters() { - final Player computer = AllZone.getComputerPlayer(); - final Player human = AllZone.getHumanPlayer(); - List all = computer.getCardsIn(ZoneType.Hand); - all.addAll(computer.getCardsIn(ZoneType.Exile)); - all.addAll(computer.getCardsIn(ZoneType.Graveyard)); - if (!computer.getCardsIn(ZoneType.Library).isEmpty()) { - all.add(computer.getCardsIn(ZoneType.Library).get(0)); + + final Player opp = player.getOpponent(); + List all = player.getCardsIn(ZoneType.Hand); + all.addAll(player.getCardsIn(ZoneType.Exile)); + all.addAll(player.getCardsIn(ZoneType.Graveyard)); + if (!player.getCardsIn(ZoneType.Library).isEmpty()) { + all.add(player.getCardsIn(ZoneType.Library).get(0)); } - all.addAll(human.getCardsIn(ZoneType.Exile)); + all.addAll(opp.getCardsIn(ZoneType.Exile)); final ArrayList spellAbilities = new ArrayList(); for (final Card c : all) { @@ -295,7 +296,7 @@ public class ComputerAIGeneral implements Computer { Log.debug(sb.toString()); } - AllZone.getComputerPlayer().getZone(ZoneType.Battlefield).updateObservers(); + player.getZone(ZoneType.Battlefield).updateObservers(); Singletons.getModel().getGameState().getPhaseHandler().setNeedToNextPhase(true); } @@ -307,7 +308,7 @@ public class ComputerAIGeneral implements Computer { */ @Override public final void declareBlockers() { - final List blockers = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer()); + final List blockers = AllZoneUtil.getCreaturesInPlay(player); AllZone.setCombat(ComputerUtilBlock.getBlockers(AllZone.getCombat(), blockers)); @@ -351,7 +352,7 @@ public class ComputerAIGeneral implements Computer { // top of stack is owned by human, ArrayList possibleCounters = getPlayableCounters(cards); - if ((possibleCounters.size() > 0) && ComputerUtil.playCounterSpell(possibleCounters)) { + if ((possibleCounters.size() > 0) && ComputerUtil.playCounterSpell(player, possibleCounters)) { // Responding CounterSpell is on the Stack trying to Counter the Spell // If playCounterSpell returns true, a Spell is hitting the Stack return; @@ -359,7 +360,7 @@ public class ComputerAIGeneral implements Computer { possibleCounters.clear(); possibleCounters = this.getPossibleETBCounters(); - if ((possibleCounters.size() > 0) && !ComputerUtil.playSpellAbilities(possibleCounters)) { + if ((possibleCounters.size() > 0) && !ComputerUtil.playSpellAbilities(player, possibleCounters)) { // Responding Permanent w/ ETB Counter is on the Stack // If playSpellAbilities returns false, a Spell is hitting the Stack return; @@ -367,7 +368,7 @@ public class ComputerAIGeneral implements Computer { final ArrayList sas = this.getSpellAbilities(cards); if (sas.size() > 0) { // Spell not Countered - if (!ComputerUtil.playSpellAbilities(sas)) { + if (!ComputerUtil.playSpellAbilities(player, sas)) { return; } } diff --git a/src/main/java/forge/game/player/ComputerUtil.java b/src/main/java/forge/game/player/ComputerUtil.java index e1fbade3128..fbb012af7cd 100644 --- a/src/main/java/forge/game/player/ComputerUtil.java +++ b/src/main/java/forge/game/player/ComputerUtil.java @@ -18,7 +18,6 @@ package forge.game.player; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -85,20 +84,19 @@ public class ComputerUtil { * objects. * @return a boolean. */ - public static boolean playSpellAbilities(final SpellAbility[] all) { - Player computer = AllZone.getComputerPlayer(); + public static boolean playSpellAbilities(final Player ai, final List all) { // not sure "playing biggest spell" matters? ComputerUtil.sortSpellAbilityByCost(all); ArrayList abilities = new ArrayList(); final ArrayList newAbilities = new ArrayList(); for (SpellAbility sa : all) { abilities.add(abilities.size(), sa); - sa.setActivatingPlayer(computer); + sa.setActivatingPlayer(ai); //add alternative costs as additional spell abilities abilities.addAll(GameActionUtil.getAlternativeCosts(sa)); } for (SpellAbility sa : abilities) { - sa.setActivatingPlayer(computer); + sa.setActivatingPlayer(ai); newAbilities.addAll(GameActionUtil.getOptionalAdditionalCosts(sa)); } abilities = newAbilities; @@ -108,32 +106,15 @@ public class ComputerUtil { if ((af != null) && af.getAPI().equals("Counter")) { continue; } - sa.setActivatingPlayer(computer); + sa.setActivatingPlayer(ai); - if (ComputerUtil.canBePlayedAndPayedByAI(computer, sa) && ComputerUtil.handlePlayingSpellAbility(sa)) { + if (ComputerUtil.canBePlayedAndPayedByAI(ai, sa) && ComputerUtil.handlePlayingSpellAbility(ai, sa)) { return false; } } return true; } // playCards() - /** - *

- * playAbilities. - *

- * - * @param all - * a {@link java.util.ArrayList} object. - * @return a boolean. - */ - public static boolean playSpellAbilities(final ArrayList all) { - final SpellAbility[] sas = new SpellAbility[all.size()]; - for (int i = 0; i < sas.length; i++) { - sas[i] = all.get(i); - } - return ComputerUtil.playSpellAbilities(sas); - } // playCards() - /** *

* handlePlayingSpellAbility. @@ -143,15 +124,15 @@ public class ComputerUtil { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - public static boolean handlePlayingSpellAbility(final SpellAbility sa) { + public static boolean handlePlayingSpellAbility(final Player ai, final SpellAbility sa) { if (sa instanceof AbilityStatic) { final Cost cost = sa.getPayCosts(); - if (cost == null && ComputerUtil.payManaCost(sa, AllZone.getComputerPlayer(), false, 0, true)) { + if (cost == null && ComputerUtil.payManaCost(sa, ai, false, 0, true)) { sa.resolve(); } else { final CostPayment pay = new CostPayment(cost, sa); - if (pay.payComputerCosts()) { + if (pay.payComputerCosts(ai)) { sa.resolve(); } } @@ -180,7 +161,7 @@ public class ComputerUtil { } final CostPayment pay = new CostPayment(cost, sa); - if (pay.payComputerCosts()) { + if (pay.payComputerCosts(ai)) { AllZone.getStack().addAndUnfreeze(sa); if (sa.getSplicedCards() != null && !sa.getSplicedCards().isEmpty()) { GuiChoose.oneOrNone("Computer reveals spliced cards:", sa.getSplicedCards()); @@ -204,7 +185,7 @@ public class ComputerUtil { * a {@link forge.card.spellability.SpellAbility} object. * @return a int. */ - public static int counterSpellRestriction(final SpellAbility sa) { + public static int counterSpellRestriction(final Player ai, final SpellAbility sa) { // Move this to AF? // Restriction Level is Based off a handful of factors @@ -223,7 +204,7 @@ public class ComputerUtil { // Consider the costs here for relative "scoring" if (CostUtil.hasDiscardHandCost(cost)) { // Null Brooch aid - restrict -= (AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand).size() * 20); + restrict -= (ai.getCardsIn(ZoneType.Hand).size() * 20); } // Abilities before Spells (card advantage) @@ -241,7 +222,7 @@ public class ComputerUtil { if (unless != null) { final int amount = AbilityFactory.calculateAmount(source, unless, sa); - final int usableManaSources = CardFactoryUtil.getUsableManaSources(AllZone.getHumanPlayer()); + final int usableManaSources = CardFactoryUtil.getUsableManaSources(ai.getOpponent()); // If the Unless isn't enough, this should be less likely to be used if (amount > usableManaSources) { @@ -275,34 +256,33 @@ public class ComputerUtil { * a {@link java.util.ArrayList} object. * @return a boolean. */ - public static boolean playCounterSpell(final ArrayList possibleCounters) { - Player computer = AllZone.getComputerPlayer(); + public static boolean playCounterSpell(final Player ai, final ArrayList possibleCounters) { SpellAbility bestSA = null; int bestRestriction = Integer.MIN_VALUE; final ArrayList newAbilities = new ArrayList(); for (SpellAbility sa : possibleCounters) { - sa.setActivatingPlayer(computer); + sa.setActivatingPlayer(ai); //add alternative costs as additional spell abilities newAbilities.addAll(GameActionUtil.getAlternativeCosts(sa)); } possibleCounters.addAll(newAbilities); newAbilities.clear(); for (SpellAbility sa : possibleCounters) { - sa.setActivatingPlayer(computer); + sa.setActivatingPlayer(ai); newAbilities.addAll(GameActionUtil.getOptionalAdditionalCosts(sa)); } possibleCounters.addAll(newAbilities); for (final SpellAbility sa : possibleCounters) { SpellAbility currentSA = sa; - sa.setActivatingPlayer(computer); + sa.setActivatingPlayer(ai); // check everything necessary - if (ComputerUtil.canBePlayedAndPayedByAI(computer, currentSA)) { + if (ComputerUtil.canBePlayedAndPayedByAI(ai, currentSA)) { if (bestSA == null) { bestSA = currentSA; - bestRestriction = ComputerUtil.counterSpellRestriction(currentSA); + bestRestriction = ComputerUtil.counterSpellRestriction(ai, currentSA); } else { // Compare bestSA with this SA - final int restrictionLevel = ComputerUtil.counterSpellRestriction(currentSA); + final int restrictionLevel = ComputerUtil.counterSpellRestriction(ai, currentSA); if (restrictionLevel > bestRestriction) { bestRestriction = restrictionLevel; @@ -336,7 +316,7 @@ public class ComputerUtil { AllZone.getStack().addAndUnfreeze(bestSA); } else { final CostPayment pay = new CostPayment(cost, bestSA); - if (pay.payComputerCosts()) { + if (pay.payComputerCosts(ai)) { AllZone.getStack().addAndUnfreeze(bestSA); } } @@ -366,7 +346,7 @@ public class ComputerUtil { AllZone.getStack().add(sa); } else { final CostPayment pay = new CostPayment(cost, sa); - if (pay.payComputerCosts()) { + if (pay.payComputerCosts(ai)) { AllZone.getStack().add(sa); } } @@ -381,8 +361,8 @@ public class ComputerUtil { * @param sa * a {@link forge.card.spellability.SpellAbility} object. */ - public static final void playStackFree(final SpellAbility sa) { - sa.setActivatingPlayer(AllZone.getComputerPlayer()); + public static final void playStackFree(final Player ai, final SpellAbility sa) { + sa.setActivatingPlayer(ai); final Card source = sa.getSourceCard(); if (sa.isSpell() && !source.isCopiedSpell()) { @@ -400,7 +380,7 @@ public class ComputerUtil { * @param sa * a {@link forge.card.spellability.SpellAbility} object. */ - public static final void playSpellAbilityWithoutPayingManaCost(final SpellAbility sa) { + public static final void playSpellAbilityWithoutPayingManaCost(final Player ai, final SpellAbility sa) { final SpellAbility newSA = sa.copy(); final Cost cost = new Cost(sa.getSourceCard(), "", false); if (newSA.getPayCosts() != null) { @@ -415,9 +395,9 @@ public class ComputerUtil { final StringBuilder sb = new StringBuilder(); sb.append(sa.getDescription()).append(" (without paying its mana cost)"); newSA.setDescription(sb.toString()); - newSA.setActivatingPlayer(AllZone.getComputerPlayer()); + newSA.setActivatingPlayer(ai); - if (!ComputerUtil.canPayAdditionalCosts(newSA)) { + if (!ComputerUtil.canPayAdditionalCosts(ai, newSA)) { return; } @@ -427,7 +407,7 @@ public class ComputerUtil { } final CostPayment pay = new CostPayment(cost, newSA); - pay.payComputerCosts(); + pay.payComputerCosts(ai); AllZone.getStack().add(newSA); } @@ -456,7 +436,7 @@ public class ComputerUtil { ComputerUtil.payManaCost(sa); } else { final CostPayment pay = new CostPayment(cost, sa); - pay.payComputerCosts(); + pay.payComputerCosts(ai); } AbilityFactory.resolve(sa, false); @@ -492,12 +472,12 @@ public class ComputerUtil { * a {@link java.lang.String} object. * @return a boolean. */ - public static boolean shouldPayCost(final Card hostCard, final String costString) { + public static boolean shouldPayCost(final Player ai, final Card hostCard, final String costString) { final Cost cost = new Cost(hostCard, costString, false); for (final CostPart part : cost.getCostParts()) { if (part instanceof CostPayLife) { - final int remainingLife = AllZone.getComputerPlayer().getLife(); + final int remainingLife = ai.getLife(); final int lifeCost = ((CostPayLife) part).convertAmount(); if ((remainingLife - lifeCost) < 10) { return false; //Don't pay life if it would put AI under 10 life @@ -564,8 +544,8 @@ public class ComputerUtil { * a {@link forge.card.spellability.SpellAbility} object. * @return a boolean. */ - public static boolean canPayAdditionalCosts(final SpellAbility sa) { - return ComputerUtil.canPayAdditionalCosts(sa, AllZone.getComputerPlayer()); + public static boolean canPayAdditionalCosts(final Player ai, final SpellAbility sa) { + return ComputerUtil.canPayAdditionalCosts(sa, ai); } /** @@ -744,7 +724,7 @@ public class ComputerUtil { // Pay additional costs if (m.getPayCosts() != null) { final CostPayment pay = new CostPayment(m.getPayCosts(), m); - if (!pay.payComputerCosts()) { + if (!pay.payComputerCosts(player)) { continue; } } else { @@ -1273,18 +1253,17 @@ public class ComputerUtil { * * @return a boolean. */ - public static boolean chooseLandsToPlay() { - final Player computer = AllZone.getComputerPlayer(); - if (!computer.canPlayLand()) { + public static boolean chooseLandsToPlay(final Player ai) { + if (!ai.canPlayLand()) { return false; } - final List hand = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand); + final List hand = ai.getCardsIn(ZoneType.Hand); List landList = CardLists.filter(hand, Presets.LANDS); List nonLandList = CardLists.filter(hand, Predicates.not(CardPredicates.Presets.LANDS)); - List lands = computer.getCardsIn(ZoneType.Graveyard); - if (!computer.getCardsIn(ZoneType.Library).isEmpty()) { - lands.add(computer.getCardsIn(ZoneType.Library).get(0)); + final List lands = ai.getCardsIn(ZoneType.Graveyard); + if (!ai.getCardsIn(ZoneType.Library).isEmpty()) { + lands.add(ai.getCardsIn(ZoneType.Library).get(0)); } for (final Card crd : lands) { if (crd.isLand() && crd.hasKeyword("May be played")) { @@ -1295,9 +1274,9 @@ public class ComputerUtil { return false; } if (landList.size() == 1 && nonLandList.size() < 3) { - List cardsInPlay = computer.getCardsIn(ZoneType.Battlefield); + List cardsInPlay = ai.getCardsIn(ZoneType.Battlefield); List landsInPlay = CardLists.filter(cardsInPlay, Presets.LANDS); - List allCards = computer.getCardsIn(ZoneType.Graveyard); + List allCards = ai.getCardsIn(ZoneType.Graveyard); allCards.addAll(cardsInPlay); int maxCmcInHand = Aggregates.max(hand, CardPredicates.Accessors.fnGetCmc); int max = Math.max(maxCmcInHand, 6); @@ -1330,7 +1309,7 @@ public class ComputerUtil { } } if (c.isType("Legendary") && !c.getName().equals("Flagstones of Trokair")) { - final List list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); + final List list = ai.getCardsIn(ZoneType.Battlefield); if (Iterables.any(list, CardPredicates.nameEquals(c.getName()))) { return false; } @@ -1340,8 +1319,8 @@ public class ComputerUtil { // available final ArrayList spellAbilities = c.getSpellAbilities(); - final List hand = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand); - List lands = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); + final List hand = ai.getCardsIn(ZoneType.Hand); + List lands = ai.getCardsIn(ZoneType.Battlefield); lands.addAll(hand); lands = CardLists.filter(lands, CardPredicates.Presets.LANDS); int maxCmcInHand = Aggregates.max(hand, CardPredicates.Accessors.fnGetCmc); @@ -1356,7 +1335,7 @@ public class ComputerUtil { } }); - while (!landList.isEmpty() && computer.canPlayLand()) { + while (!landList.isEmpty() && ai.canPlayLand()) { // play as many lands as you can int ix = 0; while (landList.get(ix).isReflectedLand() && ((ix + 1) < landList.size())) { @@ -1368,7 +1347,7 @@ public class ComputerUtil { Card land = landList.get(ix); //play basic lands that are needed the most if (!Iterables.any(landList, CardPredicates.Presets.BASIC_LANDS)) { - final List combined = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); + final List combined = ai.getCardsIn(ZoneType.Battlefield); final ArrayList basics = new ArrayList(); @@ -1400,7 +1379,7 @@ public class ComputerUtil { land = landList.get(0); } landList.remove(land); - computer.playLand(land); + ai.playLand(land); if (AllZone.getStack().size() != 0) { return true; @@ -1422,7 +1401,7 @@ public class ComputerUtil { * a {@link forge.CardList} object. * @return a {@link forge.Card} object. */ - public static Card getCardPreference(final Card activate, final String pref, final List typeList) { + public static Card getCardPreference(final Player ai, final Card activate, final String pref, final List typeList) { if (activate != null) { final String[] prefValid = activate.getSVar("AIPreference").split("\\$"); @@ -1458,7 +1437,7 @@ public class ComputerUtil { final int priority = 6 - ip; for (Card c : typeList) { if (priority == 3 && c.isLand() - && !AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield, "Crucible of Worlds").isEmpty()) { + && !ai.getCardsIn(ZoneType.Battlefield, "Crucible of Worlds").isEmpty()) { return c; } if (!c.getSVar("DiscardMe").equals("") && (Integer.parseInt(c.getSVar("DiscardMe")) == priority)) { @@ -1470,8 +1449,8 @@ public class ComputerUtil { // Discard lands final List landsInHand = CardLists.getType(typeList, "Land"); if (!landsInHand.isEmpty()) { - final List landsInPlay = CardLists.getType(AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield), "Land"); - final List nonLandsInHand = CardLists.getNotType(AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand), "Land"); + final List landsInPlay = CardLists.getType(ai.getCardsIn(ZoneType.Battlefield), "Land"); + final List nonLandsInHand = CardLists.getNotType(ai.getCardsIn(ZoneType.Hand), "Land"); final int highestCMC = Math.max(6, Aggregates.max(nonLandsInHand, CardPredicates.Accessors.fnGetCmc)); if (landsInPlay.size() >= highestCMC || (landsInPlay.size() + landsInHand.size() > 6 && landsInHand.size() > 1)) { @@ -1499,12 +1478,11 @@ public class ComputerUtil { * a int. * @return a {@link forge.CardList} object. */ - public static List chooseSacrificeType(final String type, final Card activate, final Card target, + public static List chooseSacrificeType(final Player ai, final String type, final Card activate, final Card target, final int amount) { - Player activator = AllZone.getComputerPlayer(); - List typeList = activator.getCardsIn(ZoneType.Battlefield); + List typeList = ai.getCardsIn(ZoneType.Battlefield); typeList = CardLists.getValidCards(typeList, type.split(";"), activate.getController(), activate); - if (activator.hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) { + if (ai.hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) { typeList = CardLists.getNotType(typeList, "Creature"); } @@ -1520,7 +1498,7 @@ public class ComputerUtil { int count = 0; while (count < amount) { - final Card prefCard = ComputerUtil.getCardPreference(activate, "SacCost", typeList); + final Card prefCard = ComputerUtil.getCardPreference(ai, activate, "SacCost", typeList); if (prefCard != null) { sacList.add(prefCard); typeList.remove(prefCard); @@ -1552,8 +1530,8 @@ public class ComputerUtil { * a {@link forge.card.spellability.SpellAbility} object. * @return a List of discarded cards. */ - public static List discardNumTypeAI(final int numDiscard, final String[] uTypes, final SpellAbility sa) { - List hand = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand); + public static List discardNumTypeAI(final Player ai, final int numDiscard, final String[] uTypes, final SpellAbility sa) { + List hand = ai.getCardsIn(ZoneType.Hand); Card sourceCard = null; if ((uTypes != null) && (sa != null)) { @@ -1583,7 +1561,7 @@ public class ComputerUtil { } } if (prefCard == null) { - prefCard = ComputerUtil.getCardPreference(sourceCard, "DiscardCost", hand); + prefCard = ComputerUtil.getCardPreference(ai, sourceCard, "DiscardCost", hand); } if (prefCard != null) { discardList.add(prefCard); @@ -1878,24 +1856,6 @@ public class ComputerUtil { return returnList; } - /** - *

- * getPossibleAttackers. - *

- * - * @return a {@link forge.CardList} object. - */ - public static List getPossibleAttackers() { - List list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); - list = CardLists.filter(list, new Predicate() { - @Override - public boolean apply(final Card c) { - return CombatUtil.canAttack(c); - } - }); - return list; - } - /** *

* getAttackers. @@ -1932,7 +1892,7 @@ public class ComputerUtil { * an array of {@link forge.card.spellability.SpellAbility} * objects. */ - static void sortSpellAbilityByCost(final SpellAbility[] sa) { + static void sortSpellAbilityByCost(final List sa) { // sort from highest cost to lowest // we want the highest costs first final Comparator c = new Comparator() { @@ -1954,7 +1914,7 @@ public class ComputerUtil { return b1 - a1; } }; // Comparator - Arrays.sort(sa, c); + Collections.sort(sa, c); } // sortSpellAbilityByCost() public static int getSpellAbilityPriority(SpellAbility sa) { @@ -2176,18 +2136,18 @@ public class ComputerUtil { * a SpellAbility object. * @return a boolean. */ - public static boolean castPermanentInMain1(final SpellAbility sa) { + public static boolean castPermanentInMain1(final SpellAbility sa, final Player ai) { final Card card = sa.getSourceCard(); if (card.getSVar("PlayMain1").equals("TRUE")) { return true; } - if ((card.isCreature() && (ComputerAIGeneral.hasACardGivingHaste() + if ((card.isCreature() && (ComputerAIGeneral.hasACardGivingHaste(ai) || card.hasKeyword("Haste"))) || card.hasKeyword("Exalted")) { return true; } // get all cards the computer controls with BuffedBy - final List buffed = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); + final List buffed = ai.getCardsIn(ZoneType.Battlefield); for (int j = 0; j < buffed.size(); j++) { final Card buffedcard = buffed.get(j); if (buffedcard.getSVar("BuffedBy").length() > 0) { @@ -2209,7 +2169,7 @@ public class ComputerUtil { } // BuffedBy // get all cards the human controls with AntiBuffedBy - final List antibuffed = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield); + final List antibuffed = ai.getOpponent().getCardsIn(ZoneType.Battlefield); for (int k = 0; k < antibuffed.size(); k++) { final Card buffedcard = antibuffed.get(k); if (buffedcard.getSVar("AntiBuffedBy").length() > 0) { @@ -2220,9 +2180,9 @@ public class ComputerUtil { } } } // AntiBuffedBy - final List vengevines = AllZone.getComputerPlayer().getCardsIn(ZoneType.Graveyard, "Vengevine"); + final List vengevines = ai.getCardsIn(ZoneType.Graveyard, "Vengevine"); if (vengevines.size() > 0) { - final List creatures = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand); + final List creatures = ai.getCardsIn(ZoneType.Hand); final List creatures2 = new ArrayList(); for (int i = 0; i < creatures.size(); i++) { if (creatures.get(i).isCreature() && creatures.get(i).getManaCost().getCMC() <= 3) { @@ -2242,21 +2202,21 @@ public class ComputerUtil { * @param source the source Card * @return true if it's OK to cast this Card for less than the max targets */ - public static boolean shouldCastLessThanMax(final Card source) { + public static boolean shouldCastLessThanMax(final Player ai, final Card source) { boolean ret = true; if (source.getManaCost().countX() > 0) { // If TargetMax is MaxTgts (i.e., an "X" cost), this is fine because AI is limited by mana available. } else { // Otherwise, if life is possibly in danger, then this is fine. Combat combat = new Combat(); - combat.initiatePossibleDefenders(AllZone.getComputerPlayer()); - List attackers = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer()); + combat.initiatePossibleDefenders(ai); + List attackers = AllZoneUtil.getCreaturesInPlay(ai.getOpponent()); for (Card att : attackers) { if (CombatUtil.canAttackNextTurn(att)) { combat.addAttacker(att); } } - combat = ComputerUtilBlock.getBlockers(combat, AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer())); + combat = ComputerUtilBlock.getBlockers(combat, AllZoneUtil.getCreaturesInPlay(ai)); if (!CombatUtil.lifeInDanger(combat)) { // Otherwise, return false. Do not play now. ret = false; @@ -2270,13 +2230,13 @@ public class ComputerUtil { * @param discard Card to discard * @return boolean */ - public static boolean isWorseThanDraw(Card discard) { + public static boolean isWorseThanDraw(final Player ai, Card discard) { if (!discard.getSVar("DiscardMe").equals("")) { return true; } - final List landsInPlay = CardLists.filter(AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.LANDS); - final List landsInHand = CardLists.filter(AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand), CardPredicates.Presets.LANDS); - final List nonLandsInHand = CardLists.getNotType(AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand), "Land"); + final List landsInPlay = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.LANDS); + final List landsInHand = CardLists.filter(ai.getCardsIn(ZoneType.Hand), CardPredicates.Presets.LANDS); + final List nonLandsInHand = CardLists.getNotType(ai.getCardsIn(ZoneType.Hand), "Land"); final int highestCMC = Math.max(6, Aggregates.max(nonLandsInHand, CardPredicates.Accessors.fnGetCmc)); final int discardCMC = discard.getCMC(); if (discard.isLand()) { @@ -2290,7 +2250,7 @@ public class ComputerUtil { if (discardCMC > landsInPlay.size() + landsInHand.size() + 2) { // not castable for some time. return true; - } else if (Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(AllZone.getHumanPlayer()) + } else if (!Singletons.getModel().getGameState().getPhaseHandler().isPlayerTurn(ai) && Singletons.getModel().getGameState().getPhaseHandler().getPhase().isAfter(PhaseType.MAIN2) && discardCMC > landsInPlay.size() + landsInHand.size() && discardCMC > landsInPlay.size() + 1 @@ -2298,7 +2258,7 @@ public class ComputerUtil { // not castable for at least one other turn. return true; } else if (landsInPlay.size() > 5 && discard.getCMC() <= 1 - && !discard.hasProperty("hasXCost", AllZone.getComputerPlayer(), null)) { + && !discard.hasProperty("hasXCost", ai, null)) { // Probably don't need small stuff now. return true; } diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java index 9122f775770..d0b7c3eab85 100644 --- a/src/main/java/forge/game/player/Player.java +++ b/src/main/java/forge/game/player/Player.java @@ -2434,10 +2434,7 @@ public abstract class Player extends GameEntity implements Comparable { return false; } } else if (property.equals("wasDealtDamageBySourceThisGame")) { - if (this.isHuman() && !source.getDamageHistory().getDealtDmgToHumanThisGame()) { - return false; - } - if (this.isComputer() && !source.getDamageHistory().getDealtDmgToComputerThisGame()) { + if (!source.getDamageHistory().getThisGameDamaged().contains(this)) { return false; } } else if (property.startsWith("wasDealtDamageThisTurn")) { diff --git a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java index d6d327379c9..141768a3ff3 100644 --- a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java +++ b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java @@ -250,16 +250,13 @@ public enum CSubmenuGauntletContests implements ICDoc { public Object doInBackground() { final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); - AllZone.getHumanPlayer().setDeck(gd.getUserDeck()); - AllZone.getComputerPlayer().setDeck(gd.getDecks().get(gd.getCompleted())); + Deck human = gd.getUserDeck(); + Deck aiDeck = gd.getDecks().get(gd.getCompleted()); Singletons.getModel().getMatchState().setGameType(GameType.Gauntlet); - if (AllZone.getHumanPlayer().getDeck() != null && AllZone.getComputerPlayer().getDeck() != null) { - GameNew.newGame(new PlayerStartsGame( - AllZone.getHumanPlayer(), - AllZone.getHumanPlayer().getDeck()), - new PlayerStartsGame(AllZone.getComputerPlayer(), - AllZone.getComputerPlayer().getDeck())); + if (human != null && aiDeck != null) { + GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), human), + new PlayerStartsGame(AllZone.getComputerPlayer(), aiDeck)); } return null; } diff --git a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletLoad.java b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletLoad.java index 8307e6cdf4c..36746a72150 100644 --- a/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletLoad.java +++ b/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletLoad.java @@ -12,6 +12,7 @@ import javax.swing.SwingWorker; import forge.AllZone; import forge.Command; import forge.Singletons; +import forge.deck.Deck; import forge.game.GameNew; import forge.game.GameType; import forge.game.PlayerStartsGame; @@ -103,16 +104,14 @@ public enum CSubmenuGauntletLoad implements ICDoc { public Object doInBackground() { final GauntletData gd = FModel.SINGLETON_INSTANCE.getGauntletData(); - AllZone.getHumanPlayer().setDeck(gd.getUserDeck()); - AllZone.getComputerPlayer().setDeck(gd.getDecks().get(gd.getCompleted())); + Deck human = gd.getUserDeck(); + Deck aiDeck = gd.getDecks().get(gd.getCompleted()); + Singletons.getModel().getMatchState().setGameType(GameType.Gauntlet); - if (AllZone.getHumanPlayer().getDeck() != null && AllZone.getComputerPlayer().getDeck() != null) { - GameNew.newGame(new PlayerStartsGame( - AllZone.getHumanPlayer(), - AllZone.getHumanPlayer().getDeck()), - new PlayerStartsGame(AllZone.getComputerPlayer(), - AllZone.getComputerPlayer().getDeck())); + if (human != null && aiDeck != null) { + GameNew.newGame(new PlayerStartsGame(AllZone.getHumanPlayer(), human), + new PlayerStartsGame(AllZone.getComputerPlayer(), aiDeck)); } return null; } diff --git a/src/main/java/forge/model/FModel.java b/src/main/java/forge/model/FModel.java index 80ce7c19b1e..ea78f32852c 100644 --- a/src/main/java/forge/model/FModel.java +++ b/src/main/java/forge/model/FModel.java @@ -42,12 +42,15 @@ import forge.game.GameState; import forge.game.GameSummary; import forge.game.player.ComputerAIGeneral; import forge.game.player.ComputerAIInput; +import forge.game.player.Player; +import forge.game.player.PlayerType; import forge.gauntlet.GauntletData; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; import forge.properties.ForgeProps; import forge.properties.NewConstants; import forge.quest.data.QuestPreferences; +import forge.util.Aggregates; import forge.util.FileUtil; import forge.util.HttpUtil; import forge.util.IStorageView; @@ -146,7 +149,9 @@ public enum FModel { // Instantiate AI AllZone.setInputControl(new InputControl(FModel.this)); - AllZone.getInputControl().setComputer(new ComputerAIInput(new ComputerAIGeneral())); + Player computerPlayer = Aggregates.firstFieldEquals(gameState.getPlayers(), Player.Accessors.FN_GET_TYPE, PlayerType.COMPUTER); + AllZone.getInputControl().setComputer(new ComputerAIInput(new ComputerAIGeneral(computerPlayer))); + /// Wrong direction here. It is computer that lives inside player, not a player in computer testNetworkConnection();