mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
Another portion of removal of global getters getXXXPlayer
This commit is contained in:
@@ -1362,7 +1362,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ComputerUtil.playSpellAbilityWithoutPayingManaCost(sa);
|
||||
ComputerUtil.playSpellAbilityWithoutPayingManaCost(c.getOwner(), sa);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -6920,20 +6920,15 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
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")) {
|
||||
|
||||
@@ -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<Player> thisTurnDamaged = new ArrayList<Player>(2);
|
||||
private final List<Player> thisTurnCombatDamaged = new ArrayList<Player>(2);
|
||||
private final List<Player> thisGameDamaged = new ArrayList<Player>(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;
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* Setter for the field <code>dealtDmgToHumanThisTurn</code>.
|
||||
* </p>
|
||||
*
|
||||
* @param b
|
||||
* a boolean.
|
||||
*/
|
||||
public final void setDealtDmgToHumanThisTurn(final boolean b) {
|
||||
this.dealtDmgToHumanThisTurn = b;
|
||||
if (b) {
|
||||
this.setDealtDmgToHumanThisGame(true);
|
||||
}
|
||||
public final List<Player> getThisTurnDamaged() {
|
||||
return thisTurnDamaged;
|
||||
}
|
||||
public final List<Player> getThisTurnCombatDamaged() {
|
||||
return thisTurnCombatDamaged;
|
||||
}
|
||||
public final List<Player> getThisGameDamaged() {
|
||||
return thisGameDamaged;
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* Getter for the field <code>dealtDmgToHumanThisTurn</code>.
|
||||
* </p>
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* Setter for the field <code>dealtDmgToComputerThisTurn</code>.
|
||||
* </p>
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* Getter for the field <code>dealtCombatDmgToComputerThisGame</code>.
|
||||
* </p>
|
||||
*
|
||||
* @return a boolean.
|
||||
* TODO: Write javadoc for this method.
|
||||
* @param player
|
||||
*/
|
||||
public final boolean getDealtDmgToComputerThisTurn() {
|
||||
return this.dealtDmgToComputerThisTurn;
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* Setter for the field <code>dealtDmgToHumanThisGame</code>.
|
||||
* </p>
|
||||
*
|
||||
* @param b
|
||||
* a boolean.
|
||||
*/
|
||||
public final void setDealtDmgToHumanThisGame(final boolean b) {
|
||||
this.dealtDmgToHumanThisGame = b;
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* Getter for the field <code>dealtDmgToHumanThisGame</code>.
|
||||
* </p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public final boolean getDealtDmgToHumanThisGame() {
|
||||
return this.dealtDmgToHumanThisGame;
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* Setter for the field <code>dealtDmgToComputerThisGame</code>.
|
||||
* </p>
|
||||
*
|
||||
* @param b
|
||||
* a boolean.
|
||||
*/
|
||||
public final void setDealtDmgToComputerThisGame(final boolean b) {
|
||||
this.dealtDmgToComputerThisGame = b;
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* Getter for the field <code>dealtCombatDmgToComputerThisGame</code>.
|
||||
* </p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public final boolean getDealtDmgToComputerThisGame() {
|
||||
return this.dealtDmgToComputerThisGame;
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* Setter for the field <code>dealtCombatDmgToHumanThisTurn</code>.
|
||||
* </p>
|
||||
*
|
||||
* @param b
|
||||
* a boolean.
|
||||
*/
|
||||
public final void setDealtCombatDmgToHumanThisTurn(final boolean b) {
|
||||
this.dealtCombatDmgToHumanThisTurn = b;
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* Getter for the field <code>dealtDmgToHumanThisTurn</code>.
|
||||
* </p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public final boolean getDealtCombatDmgToHumanThisTurn() {
|
||||
return this.dealtCombatDmgToHumanThisTurn;
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* Setter for the field <code>dealtCombatDmgToComputerThisTurn</code>.
|
||||
* </p>
|
||||
*
|
||||
* @param b
|
||||
* a boolean.
|
||||
*/
|
||||
public final void setDealtCombatDmgToComputerThisTurn(final boolean b) {
|
||||
this.dealtCombatDmgToComputerThisTurn = b;
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* Getter for the field <code>dealtDmgToComputerThisTurn</code>.
|
||||
* </p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public final boolean getDealtCombatDmgToComputerThisTurn() {
|
||||
return this.dealtCombatDmgToComputerThisTurn;
|
||||
public void registerDamage(Player player) {
|
||||
if ( !thisTurnDamaged.contains(player) )
|
||||
thisTurnDamaged.add(player);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -106,11 +106,20 @@ public final class CardPredicates {
|
||||
return new Predicate<Card>() {
|
||||
@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<Card> possibleBlockerForAtLeastOne(final Iterable<Card> attackers) {
|
||||
return new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.isCreature() && CombatUtil.canBlockAtLeastOne(c, attackers);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static final Predicate<Card> possibleAttackers = new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
@@ -181,7 +190,7 @@ public final class CardPredicates {
|
||||
return c.isCreature() && CombatUtil.canAttack(c);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* a Predicate<Card> to get all enchantments.
|
||||
*/
|
||||
|
||||
@@ -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<Card> res = new ArrayList<Card>();
|
||||
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);
|
||||
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
|
||||
@@ -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<String, String> 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;
|
||||
|
||||
@@ -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<Object> objects = AbilityFactory.predictThreatenedObjects(aiPlayer, af);
|
||||
final ArrayList<Object> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String> chosen = new ArrayList<String>();
|
||||
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<String> prominence = CardFactoryUtil.getColorByProminence(CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), AllZone.getComputerPlayer()));
|
||||
List<String> 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<Card> list = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer());
|
||||
List<Card> 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<Card> 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<Card> list = CardLists.filterControlledBy(AllZoneUtil.getCardsInGame(), p.getOpponent());
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,7 +398,7 @@ public class AbilityFactoryDealDamage {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CostUtil.checkSacrificeCost(abCost, source)) {
|
||||
if (!CostUtil.checkSacrificeCost(ai, abCost, source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -229,7 +229,7 @@ public class AbilityFactoryDestroy {
|
||||
List<Card> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String, String> 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<Card> comp = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer());
|
||||
List<Card> human = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer());
|
||||
List<Card> comp = AllZoneUtil.getCreaturesInPlay(ai);
|
||||
List<Card> human = AllZoneUtil.getCreaturesInPlay(ai.getOpponent());
|
||||
|
||||
// only count creatures that can attack or block
|
||||
comp = CardLists.filter(comp, new Predicate<Card>() {
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String, String> params = af.getMapParams();
|
||||
final Target tgt = sa.getTarget();
|
||||
@@ -1299,12 +1300,12 @@ public class AbilityFactoryMana {
|
||||
if (tgt == null) {
|
||||
final ArrayList<Player> 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();
|
||||
|
||||
@@ -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<Card> list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> 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<Card> attackers;
|
||||
if (phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
|
||||
//Combat has already started
|
||||
final List<Card> attackers = AllZone.getCombat().getAttackerList();
|
||||
List<Card> creatureList = CardLists.filter(tapList, new Predicate<Card>() {
|
||||
@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<Card> attackers = ComputerUtil.getPossibleAttackers();
|
||||
attackers = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES_CAN_ATTACK);
|
||||
attackers.remove(sa.getSourceCard());
|
||||
List<Card> creatureList = CardLists.filter(tapList, new Predicate<Card>() {
|
||||
@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<Card> findBlockers = CardPredicates.possibleBlockerForAtLeastOne(attackers);
|
||||
List<Card> 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<Card> 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<Card> tapList,
|
||||
private static boolean tapTargetList(final Player ai, final AbilityFactory af, final SpellAbility sa, final List<Card> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String, String> 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());
|
||||
}
|
||||
|
||||
@@ -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<String, String> 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<Object> objects = new ArrayList<Object>();
|
||||
// AbilityFactory.predictThreatenedObjects(af);
|
||||
|
||||
if (objects.contains(AllZone.getComputerPlayer())) {
|
||||
tgt.addTarget(AllZone.getComputerPlayer());
|
||||
if (objects.contains(ai)) {
|
||||
tgt.addTarget(ai);
|
||||
}
|
||||
|
||||
final List<Card> threatenedTargets = new ArrayList<Card>();
|
||||
// filter AIs battlefield by what I can target
|
||||
List<Card> targetables = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), AllZone.getComputerPlayer(), hostCard);
|
||||
List<Card> 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<Card> targetables = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), AllZone.getComputerPlayer(), hostCard);
|
||||
List<Card> 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<Card> targetables = AllZoneUtil.getCardsIn(ZoneType.Battlefield);
|
||||
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), AllZone.getComputerPlayer(), hostCard);
|
||||
final List<Card> compTargetables = CardLists.filterControlledBy(targetables, AllZone.getComputerPlayer());
|
||||
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, hostCard);
|
||||
final List<Card> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Card> getProtectCreatures(final AbilityFactory af, final SpellAbility sa) {
|
||||
private static List<Card> getProtectCreatures(final Player ai, final AbilityFactory af, final SpellAbility sa) {
|
||||
final Card hostCard = af.getHostCard();
|
||||
final ArrayList<String> gains = AbilityFactoryProtection.getProtectionList(hostCard, af.getMapParams());
|
||||
|
||||
List<Card> list = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer());
|
||||
List<Card> list = AllZoneUtil.getCreaturesInPlay(ai);
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@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<String, String> 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<Card> list = AbilityFactoryProtection.getProtectCreatures(af, sa);
|
||||
List<Card> 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<String, String> params = af.getMapParams();
|
||||
final Card host = af.getHostCard();
|
||||
@@ -484,7 +484,7 @@ public final class AbilityFactoryProtection {
|
||||
list.remove(c);
|
||||
}
|
||||
|
||||
List<Card> pref = CardLists.filterControlledBy(list, AllZone.getComputerPlayer());
|
||||
List<Card> pref = CardLists.filterControlledBy(list, ai);
|
||||
pref = CardLists.filter(pref, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
@@ -492,7 +492,7 @@ public final class AbilityFactoryProtection {
|
||||
AbilityFactoryProtection.getProtectionList(host, params));
|
||||
}
|
||||
});
|
||||
final List<Card> pref2 = CardLists.filterControlledBy(list, AllZone.getComputerPlayer());
|
||||
final List<Card> pref2 = CardLists.filterControlledBy(list, ai);
|
||||
pref = CardLists.filter(pref, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
@@ -500,7 +500,7 @@ public final class AbilityFactoryProtection {
|
||||
AbilityFactoryProtection.getProtectionList(host, params));
|
||||
}
|
||||
});
|
||||
final List<Card> forced = CardLists.filterControlledBy(list, AllZone.getHumanPlayer());
|
||||
final List<Card> 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<String> choices = AbilityFactoryProtection.getProtectionList(host, params);
|
||||
final ArrayList<String> gains = new ArrayList<String>();
|
||||
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<Card> list = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer());
|
||||
List<Card> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String> keywords, final Card card, final SpellAbility sa) {
|
||||
public boolean containsUsefulKeyword(final Player ai, final ArrayList<String> 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<Card> attackers = CardLists.filter(AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.possibleAttackers);
|
||||
List<Card> 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<Card> attackers = CardLists.filter(AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.possibleAttackers);
|
||||
List<Card> 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<Card> opBlockers = CardPredicates.possibleBlockers(card);
|
||||
List<Card> cardsCanBlock = CardLists.filter(AllZoneUtil.getCreaturesInPlay(human), opBlockers);
|
||||
List<Card> 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<Card> 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<Card> 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<Card> blockers = AllZoneUtil.getCreaturesInPlay(human);
|
||||
List<Card> 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<Card> getPumpCreatures(final SpellAbility sa) {
|
||||
private List<Card> getPumpCreatures(final Player ai, final SpellAbility sa) {
|
||||
|
||||
List<Card> list = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer());
|
||||
List<Card> list = AllZoneUtil.getCreaturesInPlay(ai);
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@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<Card> getCurseCreatures(final SpellAbility sa, final int defense, final int attack) {
|
||||
List<Card> list = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer());
|
||||
private List<Card> getCurseCreatures(final Player ai, final SpellAbility sa, final int defense, final int attack) {
|
||||
List<Card> 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<Card>() {
|
||||
@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<Card> list = new ArrayList<Card>();
|
||||
@@ -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<Card> 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<Card> comp = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
final Player opp = ai.getOpponent();
|
||||
List<Card> comp = ai.getCardsIn(ZoneType.Battlefield);
|
||||
comp = CardLists.getValidCards(comp, valid, source.getController(), source);
|
||||
List<Card> human = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> 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<Card>();
|
||||
}
|
||||
|
||||
@@ -1775,7 +1776,7 @@ public class AbilityFactoryPump {
|
||||
comp = CardLists.filter(comp, new Predicate<Card>() {
|
||||
@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()) {
|
||||
|
||||
@@ -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<String, String> 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<Card> targetables = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), AllZone.getComputerPlayer(), hostCard);
|
||||
List<Card> 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<Card> targetables = AllZoneUtil.getCardsIn(ZoneType.Battlefield);
|
||||
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), AllZone.getComputerPlayer(), hostCard);
|
||||
final List<Card> compTargetables = CardLists.filterControlledBy(targetables, AllZone.getComputerPlayer());
|
||||
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, hostCard);
|
||||
final List<Card> 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<String, String> 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<Card> 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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String, String> 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
|
||||
|
||||
@@ -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<Card> 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<Card> list = ComputerUtil.discardNumTypeAI(max, dValid, sa);
|
||||
List<Card> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<Card> hand = activator.getCardsIn(ZoneType.Hand);
|
||||
|
||||
final List<Card> 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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<CostPart> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Card> typeList = CardLists.getValidCards(activator.getCardsIn(ZoneType.Battlefield), this.getType().split(";"), activator, source);
|
||||
final List<Card> typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), this.getType().split(";"), ai, source);
|
||||
|
||||
Card card = null;
|
||||
if (this.getType().equals("Creature.YouCtrl")) {
|
||||
|
||||
@@ -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<Card> typeList = CardLists
|
||||
.getValidCards(computer.getCardsIn(this.getZone()), this.getType().split(";"), computer, source);
|
||||
final List<Card> 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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<Card> hand = activator.getCardsIn(ZoneType.Hand);
|
||||
List<Card> 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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Card> typeList = ability.getActivatingPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> 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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Card> 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);
|
||||
}
|
||||
|
||||
@@ -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<Card> typeList = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> 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<Card> typeList = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> 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<Card> typeList = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand);
|
||||
if (typeList.size() > AllZone.getComputerPlayer().getMaxHandSize()) {
|
||||
List<Card> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Card> list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
final List<Card> list = ai.getCardsIn(ZoneType.Battlefield);
|
||||
if (Iterables.any(list, CardPredicates.nameEquals(card.getName()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (card.isPlaneswalker()) {
|
||||
List<Card> list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> 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<Card> list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> list = ai.getCardsIn(ZoneType.Battlefield);
|
||||
list = CardLists.getType(list, "World");
|
||||
if (list.size() > 0) {
|
||||
return false;
|
||||
|
||||
@@ -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<Card> attackers) {
|
||||
public static boolean canBlockAtLeastOne(final Card blocker, final Iterable<Card> attackers) {
|
||||
for (Card attacker : attackers) {
|
||||
if (CombatUtil.canBlock(attacker, blocker)) {
|
||||
return true;
|
||||
|
||||
@@ -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())) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ public class AIPlayer extends Player {
|
||||
public final List<Card> discard(final int num, final SpellAbility sa, final boolean duringResolution) {
|
||||
int max = this.getCardsIn(ZoneType.Hand).size();
|
||||
max = Math.min(max, num);
|
||||
final List<Card> discarded = ComputerUtil.discardNumTypeAI(max, null, sa);
|
||||
final List<Card> discarded = ComputerUtil.discardNumTypeAI(this, max, null, sa);
|
||||
for (int i = 0; i < discarded.size(); i++) {
|
||||
this.doDiscard(discarded.get(i), sa);
|
||||
}
|
||||
|
||||
@@ -49,13 +49,14 @@ import forge.game.zone.ZoneType;
|
||||
*/
|
||||
public class ComputerAIGeneral implements Computer {
|
||||
|
||||
final private Player player;
|
||||
/**
|
||||
* <p>
|
||||
* Constructor for ComputerAI_General.
|
||||
* </p>
|
||||
*/
|
||||
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<Card> 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<Card> 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<Card> 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<Card> getAvailableCards() {
|
||||
final Player computer = AllZone.getComputerPlayer();
|
||||
final Player human = AllZone.getHumanPlayer();
|
||||
List<Card> 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<Card> 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<SpellAbility> getPossibleETBCounters() {
|
||||
final Player computer = AllZone.getComputerPlayer();
|
||||
final Player human = AllZone.getHumanPlayer();
|
||||
List<Card> 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<Card> 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<SpellAbility> spellAbilities = new ArrayList<SpellAbility>();
|
||||
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<Card> blockers = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer());
|
||||
final List<Card> 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<SpellAbility> 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<SpellAbility> sas = this.getSpellAbilities(cards);
|
||||
if (sas.size() > 0) {
|
||||
// Spell not Countered
|
||||
if (!ComputerUtil.playSpellAbilities(sas)) {
|
||||
if (!ComputerUtil.playSpellAbilities(player, sas)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<SpellAbility> all) {
|
||||
// not sure "playing biggest spell" matters?
|
||||
ComputerUtil.sortSpellAbilityByCost(all);
|
||||
ArrayList<SpellAbility> abilities = new ArrayList<SpellAbility>();
|
||||
final ArrayList<SpellAbility> newAbilities = new ArrayList<SpellAbility>();
|
||||
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()
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* playAbilities.
|
||||
* </p>
|
||||
*
|
||||
* @param all
|
||||
* a {@link java.util.ArrayList} object.
|
||||
* @return a boolean.
|
||||
*/
|
||||
public static boolean playSpellAbilities(final ArrayList<SpellAbility> 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()
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 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<SpellAbility> possibleCounters) {
|
||||
Player computer = AllZone.getComputerPlayer();
|
||||
public static boolean playCounterSpell(final Player ai, final ArrayList<SpellAbility> possibleCounters) {
|
||||
SpellAbility bestSA = null;
|
||||
int bestRestriction = Integer.MIN_VALUE;
|
||||
final ArrayList<SpellAbility> newAbilities = new ArrayList<SpellAbility>();
|
||||
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<Card> hand = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand);
|
||||
final List<Card> hand = ai.getCardsIn(ZoneType.Hand);
|
||||
List<Card> landList = CardLists.filter(hand, Presets.LANDS);
|
||||
List<Card> nonLandList = CardLists.filter(hand, Predicates.not(CardPredicates.Presets.LANDS));
|
||||
|
||||
List<Card> lands = computer.getCardsIn(ZoneType.Graveyard);
|
||||
if (!computer.getCardsIn(ZoneType.Library).isEmpty()) {
|
||||
lands.add(computer.getCardsIn(ZoneType.Library).get(0));
|
||||
final List<Card> 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<Card> cardsInPlay = computer.getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> cardsInPlay = ai.getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> landsInPlay = CardLists.filter(cardsInPlay, Presets.LANDS);
|
||||
List<Card> allCards = computer.getCardsIn(ZoneType.Graveyard);
|
||||
List<Card> 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<Card> list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
final List<Card> 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<SpellAbility> spellAbilities = c.getSpellAbilities();
|
||||
|
||||
final List<Card> hand = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand);
|
||||
List<Card> lands = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
final List<Card> hand = ai.getCardsIn(ZoneType.Hand);
|
||||
List<Card> 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<Card> combined = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
final List<Card> combined = ai.getCardsIn(ZoneType.Battlefield);
|
||||
|
||||
final ArrayList<String> basics = new ArrayList<String>();
|
||||
|
||||
@@ -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<Card> typeList) {
|
||||
public static Card getCardPreference(final Player ai, final Card activate, final String pref, final List<Card> 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<Card> landsInHand = CardLists.getType(typeList, "Land");
|
||||
if (!landsInHand.isEmpty()) {
|
||||
final List<Card> landsInPlay = CardLists.getType(AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield), "Land");
|
||||
final List<Card> nonLandsInHand = CardLists.getNotType(AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand), "Land");
|
||||
final List<Card> landsInPlay = CardLists.getType(ai.getCardsIn(ZoneType.Battlefield), "Land");
|
||||
final List<Card> 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<Card> chooseSacrificeType(final String type, final Card activate, final Card target,
|
||||
public static List<Card> chooseSacrificeType(final Player ai, final String type, final Card activate, final Card target,
|
||||
final int amount) {
|
||||
Player activator = AllZone.getComputerPlayer();
|
||||
List<Card> typeList = activator.getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> 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<Card> of discarded cards.
|
||||
*/
|
||||
public static List<Card> discardNumTypeAI(final int numDiscard, final String[] uTypes, final SpellAbility sa) {
|
||||
List<Card> hand = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand);
|
||||
public static List<Card> discardNumTypeAI(final Player ai, final int numDiscard, final String[] uTypes, final SpellAbility sa) {
|
||||
List<Card> 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getPossibleAttackers.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link forge.CardList} object.
|
||||
*/
|
||||
public static List<Card> getPossibleAttackers() {
|
||||
List<Card> list = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return CombatUtil.canAttack(c);
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 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<SpellAbility> sa) {
|
||||
// sort from highest cost to lowest
|
||||
// we want the highest costs first
|
||||
final Comparator<SpellAbility> c = new Comparator<SpellAbility>() {
|
||||
@@ -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<Card> buffed = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
final List<Card> 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<Card> antibuffed = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield);
|
||||
final List<Card> 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<Card> vengevines = AllZone.getComputerPlayer().getCardsIn(ZoneType.Graveyard, "Vengevine");
|
||||
final List<Card> vengevines = ai.getCardsIn(ZoneType.Graveyard, "Vengevine");
|
||||
if (vengevines.size() > 0) {
|
||||
final List<Card> creatures = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand);
|
||||
final List<Card> creatures = ai.getCardsIn(ZoneType.Hand);
|
||||
final List<Card> creatures2 = new ArrayList<Card>();
|
||||
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<Card> attackers = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer());
|
||||
combat.initiatePossibleDefenders(ai);
|
||||
List<Card> 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<Card> landsInPlay = CardLists.filter(AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.LANDS);
|
||||
final List<Card> landsInHand = CardLists.filter(AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand), CardPredicates.Presets.LANDS);
|
||||
final List<Card> nonLandsInHand = CardLists.getNotType(AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand), "Land");
|
||||
final List<Card> landsInPlay = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.LANDS);
|
||||
final List<Card> landsInHand = CardLists.filter(ai.getCardsIn(ZoneType.Hand), CardPredicates.Presets.LANDS);
|
||||
final List<Card> 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;
|
||||
}
|
||||
|
||||
@@ -2434,10 +2434,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
||||
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")) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user