mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
predictThreatenedObjects moved from AbilityFactory to ComputerUtil (for now, will find a more specific place later)
GameActionUtil.payCostDuringAbilityResolve method now demands player parameter (though it is always human player)
This commit is contained in:
@@ -555,7 +555,7 @@ public class GameAction {
|
||||
public void resolve() {
|
||||
Player p = recoverable.getController();
|
||||
if (p.isHuman()) {
|
||||
GameActionUtil.payCostDuringAbilityResolve(abRecover, abRecover.getPayCosts(),
|
||||
GameActionUtil.payCostDuringAbilityResolve(p, abRecover, abRecover.getPayCosts(),
|
||||
paidCommand, unpaidCommand, null, game);
|
||||
} else { // computer
|
||||
if (ComputerUtilCost.canPayCost(abRecover, p)) {
|
||||
|
||||
@@ -423,11 +423,10 @@ public final class GameActionUtil {
|
||||
* a {@link forge.Command} object.
|
||||
* @param sourceAbility TODO
|
||||
*/
|
||||
public static void payCostDuringAbilityResolve(final SpellAbility ability, final Cost cost, final Command paid,
|
||||
public static void payCostDuringAbilityResolve(final Player p, final SpellAbility ability, final Cost cost, final Command paid,
|
||||
final Command unpaid, SpellAbility sourceAbility, final GameState game) {
|
||||
final Card source = ability.getSourceCard();
|
||||
final List<CostPart> parts = cost.getCostParts();
|
||||
Player p = Singletons.getControl().getPlayer();
|
||||
ArrayList<CostPart> remainingParts = new ArrayList<CostPart>(cost.getCostParts());
|
||||
CostPart costPart = null;
|
||||
if (!parts.isEmpty()) {
|
||||
|
||||
@@ -1237,196 +1237,6 @@ public class AbilityFactory {
|
||||
return objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* predictThreatenedObjects.
|
||||
* </p>
|
||||
*
|
||||
* @param saviourAf
|
||||
* a AbilityFactory object
|
||||
* @return a {@link java.util.ArrayList} object.
|
||||
* @since 1.0.15
|
||||
*/
|
||||
public static ArrayList<Object> predictThreatenedObjects(final Player aiPlayer, final SpellAbility sa) {
|
||||
final ArrayList<Object> objects = new ArrayList<Object>();
|
||||
if (Singletons.getModel().getGame().getStack().isEmpty()) {
|
||||
return objects;
|
||||
}
|
||||
|
||||
// check stack for something that will kill this
|
||||
final SpellAbility topStack = Singletons.getModel().getGame().getStack().peekAbility();
|
||||
objects.addAll(AbilityFactory.predictThreatenedObjects(aiPlayer, sa, topStack));
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* predictThreatenedObjects.
|
||||
* </p>
|
||||
*
|
||||
* @param saviourAf
|
||||
* a AbilityFactory object
|
||||
* @param topStack
|
||||
* a {@link forge.card.spellability.SpellAbility} object.
|
||||
* @return a {@link java.util.ArrayList} object.
|
||||
* @since 1.0.15
|
||||
*/
|
||||
public static ArrayList<Object> predictThreatenedObjects(final Player aiPlayer, final SpellAbility saviour,
|
||||
final SpellAbility topStack) {
|
||||
ArrayList<Object> objects = new ArrayList<Object>();
|
||||
final ArrayList<Object> threatened = new ArrayList<Object>();
|
||||
ApiType saviourApi = saviour.getApi();
|
||||
|
||||
if (topStack == null) {
|
||||
return objects;
|
||||
}
|
||||
|
||||
final Card source = topStack.getSourceCard();
|
||||
final ApiType threatApi = topStack.getApi();
|
||||
|
||||
// Can only Predict things from AFs
|
||||
if (threatApi != null) {
|
||||
final Target tgt = topStack.getTarget();
|
||||
|
||||
if (tgt == null) {
|
||||
if (topStack.hasParam("Defined")) {
|
||||
objects = AbilityFactory.getDefinedObjects(source, topStack.getParam("Defined"), topStack);
|
||||
} else if (topStack.hasParam("ValidCards")) {
|
||||
List<Card> battleField = aiPlayer.getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> cards = CardLists.getValidCards(battleField, topStack.getParam("ValidCards").split(","), source.getController(), source);
|
||||
for (Card card : cards) {
|
||||
objects.add(card);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
objects = tgt.getTargets();
|
||||
}
|
||||
|
||||
// Determine if Defined Objects are "threatened" will be destroyed
|
||||
// due to this SA
|
||||
|
||||
// Lethal Damage => prevent damage/regeneration/bounce/shroud
|
||||
if (threatApi == ApiType.DealDamage || threatApi == ApiType.DamageAll) {
|
||||
// If PredictDamage is >= Lethal Damage
|
||||
final int dmg = AbilityFactory.calculateAmount(topStack.getSourceCard(),
|
||||
topStack.getParam("NumDmg"), topStack);
|
||||
for (final Object o : objects) {
|
||||
if (o instanceof Card) {
|
||||
final Card c = (Card) o;
|
||||
|
||||
// indestructible
|
||||
if (c.hasKeyword("Indestructible")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// already regenerated
|
||||
if (c.getShield() > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't use it on creatures that can't be regenerated
|
||||
if ((saviourApi == ApiType.Regenerate || saviourApi == ApiType.RegenerateAll) && !c.canBeShielded()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// give Shroud to targeted creatures
|
||||
if (saviourApi == ApiType.Pump && tgt == null && saviour.hasParam("KW")
|
||||
&& (saviour.getParam("KW").endsWith("Shroud")
|
||||
|| saviour.getParam("KW").endsWith("Hexproof"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't bounce or blink a permanent that the human
|
||||
// player owns or is a token
|
||||
if (saviourApi == ApiType.ChangeZone && (c.getOwner().isHuman() || c.isToken())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c.predictDamage(dmg, source, false) >= c.getKillDamage()) {
|
||||
threatened.add(c);
|
||||
}
|
||||
} else if (o instanceof Player) {
|
||||
final Player p = (Player) o;
|
||||
|
||||
if (source.hasKeyword("Infect")) {
|
||||
if (p.predictDamage(dmg, source, false) >= p.getPoisonCounters()) {
|
||||
threatened.add(p);
|
||||
}
|
||||
} else if (p.predictDamage(dmg, source, false) >= p.getLife()) {
|
||||
threatened.add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Destroy => regeneration/bounce/shroud
|
||||
else if ((threatApi == ApiType.Destroy || threatApi == ApiType.DestroyAll)
|
||||
&& (((saviourApi == ApiType.Regenerate || saviourApi == ApiType.RegenerateAll)
|
||||
&& !topStack.hasParam("NoRegen")) || saviourApi == ApiType.ChangeZone || saviourApi == ApiType.Pump)) {
|
||||
for (final Object o : objects) {
|
||||
if (o instanceof Card) {
|
||||
final Card c = (Card) o;
|
||||
// indestructible
|
||||
if (c.hasKeyword("Indestructible")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// already regenerated
|
||||
if (c.getShield() > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// give Shroud to targeted creatures
|
||||
if (saviourApi == ApiType.Pump && tgt == null && saviour.hasParam("KW")
|
||||
&& (saviour.getParam("KW").endsWith("Shroud")
|
||||
|| saviour.getParam("KW").endsWith("Hexproof"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't bounce or blink a permanent that the human
|
||||
// player owns or is a token
|
||||
if (saviourApi == ApiType.ChangeZone && (c.getOwner().isHuman() || c.isToken())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't use it on creatures that can't be regenerated
|
||||
if (saviourApi == ApiType.Regenerate && !c.canBeShielded()) {
|
||||
continue;
|
||||
}
|
||||
threatened.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Exiling => bounce/shroud
|
||||
else if ((threatApi == ApiType.ChangeZone || threatApi == ApiType.ChangeZoneAll)
|
||||
&& (saviourApi == ApiType.ChangeZone || saviourApi == ApiType.Pump)
|
||||
&& topStack.hasParam("Destination")
|
||||
&& topStack.getParam("Destination").equals("Exile")) {
|
||||
for (final Object o : objects) {
|
||||
if (o instanceof Card) {
|
||||
final Card c = (Card) o;
|
||||
// give Shroud to targeted creatures
|
||||
if (saviourApi == ApiType.Pump && tgt == null && saviour.hasParam("KW")
|
||||
&& (saviour.getParam("KW").endsWith("Shroud") || saviour.getParam("KW").endsWith("Hexproof"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't bounce or blink a permanent that the human
|
||||
// player owns or is a token
|
||||
if (saviourApi == ApiType.ChangeZone && (c.getOwner().isHuman() || c.isToken())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
threatened.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
threatened.addAll(AbilityFactory.predictThreatenedObjects(aiPlayer, saviour, topStack.getSubAbility()));
|
||||
return threatened;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* handleRemembering.
|
||||
@@ -1667,7 +1477,7 @@ public class AbilityFactory {
|
||||
if (paid) {
|
||||
unpaidCommand = paidCommand;
|
||||
}
|
||||
GameActionUtil.payCostDuringAbilityResolve(ability, cost, paidCommand, unpaidCommand, sa, game);
|
||||
GameActionUtil.payCostDuringAbilityResolve(payer, ability, cost, paidCommand, unpaidCommand, sa, game);
|
||||
waitForInput = true; // wait for the human input
|
||||
break; // multiple human players are not supported
|
||||
}
|
||||
|
||||
@@ -600,7 +600,7 @@ public class ChangeZoneAi extends SpellAiLogic {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ArrayList<Object> objects = AbilityFactory.predictThreatenedObjects(ai, sa);
|
||||
final ArrayList<Object> objects = ComputerUtil.predictThreatenedObjects(ai, sa);
|
||||
boolean contains = false;
|
||||
for (final Card c : retrieval) {
|
||||
if (objects.contains(c)) {
|
||||
@@ -720,7 +720,7 @@ public class ChangeZoneAi extends SpellAiLogic {
|
||||
// check stack for something on the stack that will kill
|
||||
// anything i control
|
||||
if (Singletons.getModel().getGame().getStack().size() > 0) {
|
||||
final ArrayList<Object> objects = AbilityFactory.predictThreatenedObjects(ai, sa);
|
||||
final ArrayList<Object> objects = ComputerUtil.predictThreatenedObjects(ai, sa);
|
||||
|
||||
final List<Card> threatenedTargets = new ArrayList<Card>();
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
@@ -56,7 +57,7 @@ public class DamagePreventAi extends SpellAiLogic {
|
||||
|
||||
// react to threats on the stack
|
||||
if (Singletons.getModel().getGame().getStack().size() > 0) {
|
||||
final ArrayList<Object> threatenedObjects = AbilityFactory.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
|
||||
final ArrayList<Object> threatenedObjects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
|
||||
for (final Object o : objects) {
|
||||
if (threatenedObjects.contains(o)) {
|
||||
chance = true;
|
||||
|
||||
@@ -17,6 +17,7 @@ import forge.card.abilityfactory.SpellAiLogic;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.GameState;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.phase.Combat;
|
||||
import forge.game.phase.CombatUtil;
|
||||
@@ -336,7 +337,7 @@ public abstract class PumpAiBase extends SpellAiLogic {
|
||||
return false;
|
||||
}
|
||||
} else if (keyword.equals("Shroud") || keyword.equals("Hexproof")) {
|
||||
if (!AbilityFactory.predictThreatenedObjects(sa.getActivatingPlayer(), sa).contains(card)) {
|
||||
if (!ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa).contains(card)) {
|
||||
return false;
|
||||
}
|
||||
} else if (keyword.equals("Islandwalk")) {
|
||||
|
||||
@@ -31,6 +31,7 @@ import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.phase.PhaseType;
|
||||
@@ -83,7 +84,7 @@ public class RegenerateAi extends SpellAiLogic {
|
||||
final List<Card> list = AbilityFactory.getDefinedCards(hostCard, sa.getParam("Defined"), sa);
|
||||
|
||||
if (Singletons.getModel().getGame().getStack().size() > 0) {
|
||||
final List<Object> objects = AbilityFactory.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
|
||||
final List<Object> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
|
||||
|
||||
for (final Card c : list) {
|
||||
if (objects.contains(c)) {
|
||||
@@ -119,7 +120,7 @@ public class RegenerateAi extends SpellAiLogic {
|
||||
if (Singletons.getModel().getGame().getStack().size() > 0) {
|
||||
// check stack for something on the stack will kill anything i
|
||||
// control
|
||||
final ArrayList<Object> objects = AbilityFactory.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
|
||||
final ArrayList<Object> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
|
||||
|
||||
final List<Card> threatenedTargets = new ArrayList<Card>();
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.Singletons;
|
||||
import forge.card.abilityfactory.AbilityFactory;
|
||||
import forge.card.abilityfactory.SpellAiLogic;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.phase.PhaseType;
|
||||
@@ -56,7 +56,7 @@ public class RegenerateAllAi extends SpellAiLogic {
|
||||
|
||||
int numSaved = 0;
|
||||
if (Singletons.getModel().getGame().getStack().size() > 0) {
|
||||
final ArrayList<Object> objects = AbilityFactory.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
|
||||
final ArrayList<Object> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
|
||||
|
||||
for (final Card c : list) {
|
||||
if (objects.contains(c) && c.getShield() == 0) {
|
||||
|
||||
@@ -1047,4 +1047,194 @@ public class ComputerUtil {
|
||||
|
||||
return false;
|
||||
} // hasACardGivingHaste
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* predictThreatenedObjects.
|
||||
* </p>
|
||||
*
|
||||
* @param saviourAf
|
||||
* a AbilityFactory object
|
||||
* @return a {@link java.util.ArrayList} object.
|
||||
* @since 1.0.15
|
||||
*/
|
||||
public static ArrayList<Object> predictThreatenedObjects(final Player aiPlayer, final SpellAbility sa) {
|
||||
final ArrayList<Object> objects = new ArrayList<Object>();
|
||||
if (Singletons.getModel().getGame().getStack().isEmpty()) {
|
||||
return objects;
|
||||
}
|
||||
|
||||
// check stack for something that will kill this
|
||||
final SpellAbility topStack = Singletons.getModel().getGame().getStack().peekAbility();
|
||||
objects.addAll(ComputerUtil.predictThreatenedObjects(aiPlayer, sa, topStack));
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* predictThreatenedObjects.
|
||||
* </p>
|
||||
*
|
||||
* @param saviourAf
|
||||
* a AbilityFactory object
|
||||
* @param topStack
|
||||
* a {@link forge.card.spellability.SpellAbility} object.
|
||||
* @return a {@link java.util.ArrayList} object.
|
||||
* @since 1.0.15
|
||||
*/
|
||||
public static ArrayList<Object> predictThreatenedObjects(final Player aiPlayer, final SpellAbility saviour,
|
||||
final SpellAbility topStack) {
|
||||
ArrayList<Object> objects = new ArrayList<Object>();
|
||||
final ArrayList<Object> threatened = new ArrayList<Object>();
|
||||
ApiType saviourApi = saviour.getApi();
|
||||
|
||||
if (topStack == null) {
|
||||
return objects;
|
||||
}
|
||||
|
||||
final Card source = topStack.getSourceCard();
|
||||
final ApiType threatApi = topStack.getApi();
|
||||
|
||||
// Can only Predict things from AFs
|
||||
if (threatApi != null) {
|
||||
final Target tgt = topStack.getTarget();
|
||||
|
||||
if (tgt == null) {
|
||||
if (topStack.hasParam("Defined")) {
|
||||
objects = AbilityFactory.getDefinedObjects(source, topStack.getParam("Defined"), topStack);
|
||||
} else if (topStack.hasParam("ValidCards")) {
|
||||
List<Card> battleField = aiPlayer.getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> cards = CardLists.getValidCards(battleField, topStack.getParam("ValidCards").split(","), source.getController(), source);
|
||||
for (Card card : cards) {
|
||||
objects.add(card);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
objects = tgt.getTargets();
|
||||
}
|
||||
|
||||
// Determine if Defined Objects are "threatened" will be destroyed
|
||||
// due to this SA
|
||||
|
||||
// Lethal Damage => prevent damage/regeneration/bounce/shroud
|
||||
if (threatApi == ApiType.DealDamage || threatApi == ApiType.DamageAll) {
|
||||
// If PredictDamage is >= Lethal Damage
|
||||
final int dmg = AbilityFactory.calculateAmount(topStack.getSourceCard(),
|
||||
topStack.getParam("NumDmg"), topStack);
|
||||
for (final Object o : objects) {
|
||||
if (o instanceof Card) {
|
||||
final Card c = (Card) o;
|
||||
|
||||
// indestructible
|
||||
if (c.hasKeyword("Indestructible")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// already regenerated
|
||||
if (c.getShield() > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't use it on creatures that can't be regenerated
|
||||
if ((saviourApi == ApiType.Regenerate || saviourApi == ApiType.RegenerateAll) && !c.canBeShielded()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// give Shroud to targeted creatures
|
||||
if (saviourApi == ApiType.Pump && tgt == null && saviour.hasParam("KW")
|
||||
&& (saviour.getParam("KW").endsWith("Shroud")
|
||||
|| saviour.getParam("KW").endsWith("Hexproof"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't bounce or blink a permanent that the human
|
||||
// player owns or is a token
|
||||
if (saviourApi == ApiType.ChangeZone && (c.getOwner().isHuman() || c.isToken())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c.predictDamage(dmg, source, false) >= c.getKillDamage()) {
|
||||
threatened.add(c);
|
||||
}
|
||||
} else if (o instanceof Player) {
|
||||
final Player p = (Player) o;
|
||||
|
||||
if (source.hasKeyword("Infect")) {
|
||||
if (p.predictDamage(dmg, source, false) >= p.getPoisonCounters()) {
|
||||
threatened.add(p);
|
||||
}
|
||||
} else if (p.predictDamage(dmg, source, false) >= p.getLife()) {
|
||||
threatened.add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Destroy => regeneration/bounce/shroud
|
||||
else if ((threatApi == ApiType.Destroy || threatApi == ApiType.DestroyAll)
|
||||
&& (((saviourApi == ApiType.Regenerate || saviourApi == ApiType.RegenerateAll)
|
||||
&& !topStack.hasParam("NoRegen")) || saviourApi == ApiType.ChangeZone || saviourApi == ApiType.Pump)) {
|
||||
for (final Object o : objects) {
|
||||
if (o instanceof Card) {
|
||||
final Card c = (Card) o;
|
||||
// indestructible
|
||||
if (c.hasKeyword("Indestructible")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// already regenerated
|
||||
if (c.getShield() > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// give Shroud to targeted creatures
|
||||
if (saviourApi == ApiType.Pump && tgt == null && saviour.hasParam("KW")
|
||||
&& (saviour.getParam("KW").endsWith("Shroud")
|
||||
|| saviour.getParam("KW").endsWith("Hexproof"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't bounce or blink a permanent that the human
|
||||
// player owns or is a token
|
||||
if (saviourApi == ApiType.ChangeZone && (c.getOwner().isHuman() || c.isToken())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't use it on creatures that can't be regenerated
|
||||
if (saviourApi == ApiType.Regenerate && !c.canBeShielded()) {
|
||||
continue;
|
||||
}
|
||||
threatened.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Exiling => bounce/shroud
|
||||
else if ((threatApi == ApiType.ChangeZone || threatApi == ApiType.ChangeZoneAll)
|
||||
&& (saviourApi == ApiType.ChangeZone || saviourApi == ApiType.Pump)
|
||||
&& topStack.hasParam("Destination")
|
||||
&& topStack.getParam("Destination").equals("Exile")) {
|
||||
for (final Object o : objects) {
|
||||
if (o instanceof Card) {
|
||||
final Card c = (Card) o;
|
||||
// give Shroud to targeted creatures
|
||||
if (saviourApi == ApiType.Pump && tgt == null && saviour.hasParam("KW")
|
||||
&& (saviour.getParam("KW").endsWith("Shroud") || saviour.getParam("KW").endsWith("Hexproof"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't bounce or blink a permanent that the human
|
||||
// player owns or is a token
|
||||
if (saviourApi == ApiType.ChangeZone && (c.getOwner().isHuman() || c.isToken())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
threatened.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
threatened.addAll(ComputerUtil.predictThreatenedObjects(aiPlayer, saviour, topStack.getSubAbility()));
|
||||
return threatened;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ public class ComputerUtilCost {
|
||||
final GameState game = Singletons.getModel().getGame();
|
||||
// Check for stuff like Nether Void
|
||||
int extraManaNeeded = 0;
|
||||
if (sa instanceof Spell && player.isComputer()) {
|
||||
if (sa instanceof Spell) {
|
||||
for (Player opp : player.getOpponents()) {
|
||||
for (Card c : opp.getCardsIn(ZoneType.Battlefield)) {
|
||||
final String snem = c.getSVar("SpellsNeedExtraMana");
|
||||
|
||||
@@ -1201,7 +1201,7 @@ public class CombatUtil {
|
||||
|
||||
ability.setActivatingPlayer(c.getController());
|
||||
if (c.getController().isHuman()) {
|
||||
GameActionUtil.payCostDuringAbilityResolve(ability, attackCost, paidCommand, unpaidCommand, null, game);
|
||||
GameActionUtil.payCostDuringAbilityResolve(c.getController(), ability, attackCost, paidCommand, unpaidCommand, null, game);
|
||||
} else { // computer
|
||||
if (ComputerUtilCost.canPayCost(ability, c.getController())) {
|
||||
ComputerUtil.playNoStack(c.getController(), ability, game);
|
||||
|
||||
@@ -197,7 +197,7 @@ public class Upkeep extends Phase {
|
||||
Player controller = c.getController();
|
||||
if (controller.isHuman()) {
|
||||
Cost cost = new Cost(c, c.getEchoCost().trim(), true);
|
||||
GameActionUtil.payCostDuringAbilityResolve(blankAbility, cost, paidCommand, unpaidCommand, null, game);
|
||||
GameActionUtil.payCostDuringAbilityResolve(controller, blankAbility, cost, paidCommand, unpaidCommand, null, game);
|
||||
} else { // computer
|
||||
if (ComputerUtilCost.canPayCost(blankAbility, controller)) {
|
||||
ComputerUtil.playNoStack(controller, blankAbility, game);
|
||||
@@ -357,7 +357,7 @@ public class Upkeep extends Phase {
|
||||
@Override
|
||||
public void resolve() {
|
||||
if (controller.isHuman()) {
|
||||
GameActionUtil.payCostDuringAbilityResolve(blankAbility, blankAbility.getPayCosts(),
|
||||
GameActionUtil.payCostDuringAbilityResolve(controller, blankAbility, blankAbility.getPayCosts(),
|
||||
paidCommand, unpaidCommand, null, game);
|
||||
} else { // computer
|
||||
if (ComputerUtilCost.shouldPayCost(controller, c, upkeepCost) && ComputerUtilCost.canPayCost(blankAbility, controller)) {
|
||||
|
||||
Reference in New Issue
Block a user