diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index ec6b6636151..c5c5720241d 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -337,27 +337,30 @@ public class ComputerUtil { return true; } - public static final void playNoStack(final Player ai, SpellAbility sa, final Game game, final boolean effect) { + public static final boolean playNoStack(final Player ai, SpellAbility sa, final Game game, final boolean effect) { sa.setActivatingPlayer(ai, true); // TODO: We should really restrict what doesn't use the Stack - if (ComputerUtilCost.canPayCost(sa, ai, effect)) { - final Card source = sa.getHostCard(); - if (sa.isSpell() && !source.isCopiedSpell()) { - sa.setHostCard(game.getAction().moveToStack(source, sa)); - } - - sa = GameActionUtil.addExtraKeywordCost(sa); - - final Cost cost = sa.getPayCosts(); - if (cost == null) { - ComputerUtilMana.payManaCost(ai, sa, effect); - } else { - final CostPayment pay = new CostPayment(cost, sa); - pay.payComputerCosts(new AiCostDecision(ai, sa, effect)); - } - - AbilityUtils.resolve(sa); + if (!ComputerUtilCost.canPayCost(sa, ai, effect)) { + return false; } + + final Card source = sa.getHostCard(); + if (sa.isSpell() && !source.isCopiedSpell()) { + sa.setHostCard(game.getAction().moveToStack(source, sa)); + } + + sa = GameActionUtil.addExtraKeywordCost(sa); + + final Cost cost = sa.getPayCosts(); + if (cost == null) { + ComputerUtilMana.payManaCost(ai, sa, effect); + } else { + final CostPayment pay = new CostPayment(cost, sa); + pay.payComputerCosts(new AiCostDecision(ai, sa, effect)); + } + + AbilityUtils.resolve(sa); + return true; } public static Card getCardPreference(final Player ai, final Card activate, final String pref, final CardCollection typeList) { diff --git a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java index f61c632b5c8..6e28cd69f83 100644 --- a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java +++ b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java @@ -707,8 +707,7 @@ public class PlayerControllerAi extends PlayerController { ability.setActivatingPlayer(c.getController(), true); ability.setCardState(sa.getCardState()); - if (ComputerUtilCost.canPayCost(ability, c.getController(), true)) { - ComputerUtil.playNoStack(c.getController(), ability, getGame(), true); + if (ComputerUtil.playNoStack(c.getController(), ability, getGame(), true)) { // transfer this info for Balduvian Fallen sa.setPayingMana(ability.getPayingMana()); return true; @@ -1082,9 +1081,8 @@ public class PlayerControllerAi extends PlayerController { emptyAbility.setSVars(sa.getSVars()); emptyAbility.setCardState(sa.getCardState()); emptyAbility.setXManaCostPaid(sa.getRootAbility().getXManaCostPaid()); - if (ComputerUtilCost.willPayUnlessCost(sa, player, cost, alreadyPaid, allPayers) && ComputerUtilCost.canPayCost(emptyAbility, player, true)) { - ComputerUtil.playNoStack(player, emptyAbility, getGame(), true); // AI needs something to resolve to pay that cost - return true; + if (ComputerUtilCost.willPayUnlessCost(sa, player, cost, alreadyPaid, allPayers)) { + return ComputerUtil.playNoStack(player, emptyAbility, getGame(), true); // AI needs something to resolve to pay that cost } return false; } diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index f3199e1f683..72d6b25dd39 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -421,8 +421,16 @@ public class AbilityUtils { // return empty strings and constants if (StringUtils.isBlank(amount)) { return 0; } if (card == null) { return 0; } - final Player player = card.getController(); - final Game game = player == null ? card.getGame() : player.getGame(); + + Player player = null; + if (ability instanceof SpellAbility) { + player = ((SpellAbility)ability).getActivatingPlayer(); + } + if (player == null) { + player = card.getController(); + } + + final Game game = card.getGame(); // Strip and save sign for calculations final boolean startsWithPlus = amount.charAt(0) == '+'; @@ -519,12 +527,7 @@ public class AbilityUtils { players.remove(game.getPhaseHandler().getPlayerTurn()); val = playerXCount(players, calcX[1], card, ability); } else if (hType.startsWith("PropertyYou")) { - if (ability instanceof SpellAbility) { - // Hollow One - players.add(((SpellAbility) ability).getActivatingPlayer()); - } else { - players.add(player); - } + players.add(player); val = playerXCount(players, calcX[1], card, ability); } else if (hType.startsWith("Property")) { String defined = hType.split("Property")[1]; @@ -3232,12 +3235,13 @@ public class AbilityUtils { * @return a int. */ public static int playerXCount(final List players, final String s, final Card source, CardTraitBase ctb) { - if (players.size() == 0) { + if (players.isEmpty()) { return 0; } final String[] l = s.split("/"); final String m = CardFactoryUtil.extractOperators(s); + final Player controller = ctb instanceof SpellAbility ? ((SpellAbility)ctb).getActivatingPlayer() : source.getController(); int n = 0; @@ -3318,7 +3322,7 @@ public class AbilityUtils { int totPlayer = 0; String property = sq[0].substring(11); for (Player p : players) { - if (p.hasProperty(property, source.getController(), source, ctb)) { + if (p.hasProperty(property, controller, source, ctb)) { totPlayer++; } }