mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
- Fixes, Updates and Ordering in CombatUtil and ComputerUtil.
This commit is contained in:
@@ -2,8 +2,6 @@
|
|||||||
package forge;
|
package forge;
|
||||||
|
|
||||||
|
|
||||||
import static forge.error.ErrorViewer.showError;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
@@ -14,7 +12,6 @@ import com.esotericsoftware.minlog.Log;
|
|||||||
import forge.card.abilityFactory.AbilityFactory;
|
import forge.card.abilityFactory.AbilityFactory;
|
||||||
import forge.card.cardFactory.CardFactoryUtil;
|
import forge.card.cardFactory.CardFactoryUtil;
|
||||||
import forge.card.spellability.Ability;
|
import forge.card.spellability.Ability;
|
||||||
import forge.card.spellability.SpellAbility;
|
|
||||||
import forge.card.trigger.Trigger;
|
import forge.card.trigger.Trigger;
|
||||||
import forge.gui.GuiUtils;
|
import forge.gui.GuiUtils;
|
||||||
import forge.gui.input.Input_PayManaCost_Ability;
|
import forge.gui.input.Input_PayManaCost_Ability;
|
||||||
@@ -1064,46 +1061,25 @@ public class CombatUtil {
|
|||||||
return toughness;
|
return toughness;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean canRegenerate(Card card) {
|
|
||||||
Player controller = card.getController();
|
|
||||||
CardList l = AllZoneUtil.getCardsInPlay();
|
|
||||||
for(Card c:l)
|
|
||||||
for(SpellAbility sa:c.getSpellAbility())
|
|
||||||
// if SA is from AF_Counter don't add to getPlayable
|
|
||||||
//This try/catch should fix the "computer is thinking" bug
|
|
||||||
try {
|
|
||||||
if(sa.canPlay() && ComputerUtil.canPayCost(sa,controller) && sa.getAbilityFactory() != null && sa.isAbility()){
|
|
||||||
AbilityFactory af = sa.getAbilityFactory();
|
|
||||||
HashMap <String,String> mapParams = af.getMapParams();
|
|
||||||
if (mapParams.get("AB").equals("Regenerate"))
|
|
||||||
if (AbilityFactory.getDefinedCards(sa.getSourceCard(), mapParams.get("Defined"), sa).contains(card))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} catch(Exception ex) {
|
|
||||||
showError(ex, "There is an error in the card code for %s:%n", c.getName(), ex.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//can the blocker destroy the attacker?
|
//can the blocker destroy the attacker?
|
||||||
public static boolean canDestroyAttacker(Card attacker, Card defender, Combat combat, boolean noRegen) {
|
public static boolean canDestroyAttacker(Card attacker, Card defender, Combat combat, boolean noRegen) {
|
||||||
|
|
||||||
if(attacker.getName().equals("Sylvan Basilisk") && !defender.getKeyword().contains("Indestructible")) return false;
|
if(attacker.getName().equals("Sylvan Basilisk") && !defender.hasKeyword("Indestructible")) return false;
|
||||||
|
|
||||||
int flankingMagnitude = 0;
|
int flankingMagnitude = 0;
|
||||||
if(attacker.getKeyword().contains("Flanking") && !defender.getKeyword().contains("Flanking")) {
|
if(attacker.hasKeyword("Flanking") && !defender.hasKeyword("Flanking")) {
|
||||||
|
|
||||||
flankingMagnitude = attacker.getAmountOfKeyword("Flanking");
|
flankingMagnitude = attacker.getAmountOfKeyword("Flanking");
|
||||||
|
|
||||||
if(flankingMagnitude >= defender.getNetDefense()) return false;
|
if(flankingMagnitude >= defender.getNetDefense()) return false;
|
||||||
if(flankingMagnitude >= defender.getNetDefense() - defender.getDamage() && !defender.getKeyword().contains("Indestructible"))
|
if(flankingMagnitude >= defender.getNetDefense() - defender.getDamage() && !defender.hasKeyword("Indestructible"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}//flanking
|
}//flanking
|
||||||
|
|
||||||
if((attacker.getKeyword().contains("Indestructible") || (canRegenerate(attacker) && !noRegen)) &&
|
if(defender.hasKeyword("CARDNAME can't be regenerated.")) noRegen = true;
|
||||||
!(defender.getKeyword().contains("Wither") || defender.getKeyword().contains("Infect"))) return false;
|
|
||||||
|
if((attacker.hasKeyword("Indestructible") || (ComputerUtil.canRegenerate(attacker) && !noRegen)) &&
|
||||||
|
!(defender.hasKeyword("Wither") || defender.hasKeyword("Infect"))) return false;
|
||||||
|
|
||||||
int defenderDamage = defender.getNetAttack() + predictPowerBonusOfBlocker(attacker, defender);
|
int defenderDamage = defender.getNetAttack() + predictPowerBonusOfBlocker(attacker, defender);
|
||||||
int attackerDamage = attacker.getNetAttack() + predictPowerBonusOfAttacker(attacker, defender, combat);
|
int attackerDamage = attacker.getNetAttack() + predictPowerBonusOfAttacker(attacker, defender, combat);
|
||||||
@@ -1119,15 +1095,15 @@ public class CombatUtil {
|
|||||||
int defenderLife = defender.getKillDamage() + predictToughnessBonusOfBlocker(attacker, defender);
|
int defenderLife = defender.getKillDamage() + predictToughnessBonusOfBlocker(attacker, defender);
|
||||||
int attackerLife = attacker.getKillDamage() + predictToughnessBonusOfAttacker(attacker, defender, combat);
|
int attackerLife = attacker.getKillDamage() + predictToughnessBonusOfAttacker(attacker, defender, combat);
|
||||||
|
|
||||||
if(defender.getKeyword().contains("Double Strike") ) {
|
if(defender.hasKeyword("Double Strike") ) {
|
||||||
if(defender.getKeyword().contains("Deathtouch") && defenderDamage > 0) return true;
|
if(defender.hasKeyword("Deathtouch") && defenderDamage > 0) return true;
|
||||||
if(defenderDamage >= attackerLife) return true;
|
if(defenderDamage >= attackerLife) return true;
|
||||||
|
|
||||||
//Attacker may kill the blocker before he can deal normal (secondary) damage
|
//Attacker may kill the blocker before he can deal normal (secondary) damage
|
||||||
if((attacker.getKeyword().contains("Double Strike") || attacker.getKeyword().contains("First Strike"))
|
if((attacker.hasKeyword("Double Strike") || attacker.hasKeyword("First Strike"))
|
||||||
&& !defender.getKeyword().contains("Indestructible")) {
|
&& !defender.hasKeyword("Indestructible")) {
|
||||||
if(attackerDamage >= defenderLife) return false;
|
if(attackerDamage >= defenderLife) return false;
|
||||||
if(attackerDamage > 0 && attacker.getKeyword().contains("Deathtouch")) return false;
|
if(attackerDamage > 0 && attacker.hasKeyword("Deathtouch")) return false;
|
||||||
}
|
}
|
||||||
if(attackerLife <= 2 * defenderDamage) return true;
|
if(attackerLife <= 2 * defenderDamage) return true;
|
||||||
}//defender double strike
|
}//defender double strike
|
||||||
@@ -1135,14 +1111,14 @@ public class CombatUtil {
|
|||||||
else //no double strike for defender
|
else //no double strike for defender
|
||||||
{
|
{
|
||||||
//Attacker may kill the blocker before he can deal any damage
|
//Attacker may kill the blocker before he can deal any damage
|
||||||
if(attacker.getKeyword().contains("Double Strike") || attacker.getKeyword().contains("First Strike")
|
if(attacker.hasKeyword("Double Strike") || attacker.hasKeyword("First Strike")
|
||||||
&& !defender.getKeyword().contains("Indestructible") && !defender.getKeyword().contains("First Strike")) {
|
&& !defender.hasKeyword("Indestructible") && !defender.hasKeyword("First Strike")) {
|
||||||
|
|
||||||
if(attackerDamage >= defenderLife) return false;
|
if(attackerDamage >= defenderLife) return false;
|
||||||
if(attackerDamage > 0 && attacker.getKeyword().contains("Deathtouch") ) return false;
|
if(attackerDamage > 0 && attacker.hasKeyword("Deathtouch") ) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(defender.getKeyword().contains("Deathtouch") && defenderDamage > 0) return true;
|
if(defender.hasKeyword("Deathtouch") && defenderDamage > 0) return true;
|
||||||
|
|
||||||
return defenderDamage >= attackerLife;
|
return defenderDamage >= attackerLife;
|
||||||
|
|
||||||
@@ -1156,7 +1132,7 @@ public class CombatUtil {
|
|||||||
Card attacker = AllZone.Combat.getAttackerBlockedBy(blocker);
|
Card attacker = AllZone.Combat.getAttackerBlockedBy(blocker);
|
||||||
|
|
||||||
if(canDestroyBlocker(blocker, attacker, AllZone.Combat, true) &&
|
if(canDestroyBlocker(blocker, attacker, AllZone.Combat, true) &&
|
||||||
!(attacker.getKeyword().contains("Wither") || attacker.getKeyword().contains("Infect")))
|
!(attacker.hasKeyword("Wither") || attacker.hasKeyword("Infect")))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1165,18 +1141,20 @@ public class CombatUtil {
|
|||||||
public static boolean canDestroyBlocker(Card defender, Card attacker, Combat combat, boolean noRegen) {
|
public static boolean canDestroyBlocker(Card defender, Card attacker, Combat combat, boolean noRegen) {
|
||||||
|
|
||||||
int flankingMagnitude = 0;
|
int flankingMagnitude = 0;
|
||||||
if(attacker.getKeyword().contains("Flanking") && !defender.getKeyword().contains("Flanking")) {
|
if(attacker.hasKeyword("Flanking") && !defender.hasKeyword("Flanking")) {
|
||||||
|
|
||||||
flankingMagnitude = attacker.getAmountOfKeyword("Flanking");
|
flankingMagnitude = attacker.getAmountOfKeyword("Flanking");
|
||||||
|
|
||||||
if(flankingMagnitude >= defender.getNetDefense()) return true;
|
if(flankingMagnitude >= defender.getNetDefense()) return true;
|
||||||
if((flankingMagnitude >= defender.getKillDamage()) && !defender.getKeyword().contains("Indestructible")) return true;
|
if((flankingMagnitude >= defender.getKillDamage()) && !defender.hasKeyword("Indestructible")) return true;
|
||||||
}//flanking
|
}//flanking
|
||||||
|
|
||||||
if((defender.getKeyword().contains("Indestructible") || (canRegenerate(defender) && !noRegen)) &&
|
if(defender.hasKeyword("CARDNAME can't be regenerated.")) noRegen = true;
|
||||||
!(attacker.getKeyword().contains("Wither") || attacker.getKeyword().contains("Infect"))) return false;
|
|
||||||
|
|
||||||
if(attacker.getName().equals("Sylvan Basilisk") && !defender.getKeyword().contains("Indestructible")) return true;
|
if((defender.hasKeyword("Indestructible") || (ComputerUtil.canRegenerate(defender) && !noRegen)) &&
|
||||||
|
!(attacker.hasKeyword("Wither") || attacker.hasKeyword("Infect"))) return false;
|
||||||
|
|
||||||
|
if(attacker.getName().equals("Sylvan Basilisk") && !defender.hasKeyword("Indestructible")) return true;
|
||||||
|
|
||||||
int defenderDamage = defender.getNetAttack() + predictPowerBonusOfBlocker(attacker, defender);
|
int defenderDamage = defender.getNetAttack() + predictPowerBonusOfBlocker(attacker, defender);
|
||||||
int attackerDamage = attacker.getNetAttack() + predictPowerBonusOfAttacker(attacker, defender, combat);
|
int attackerDamage = attacker.getNetAttack() + predictPowerBonusOfAttacker(attacker, defender, combat);
|
||||||
@@ -1192,15 +1170,15 @@ public class CombatUtil {
|
|||||||
int defenderLife = defender.getKillDamage() + predictToughnessBonusOfBlocker(attacker, defender);
|
int defenderLife = defender.getKillDamage() + predictToughnessBonusOfBlocker(attacker, defender);
|
||||||
int attackerLife = attacker.getKillDamage() + predictToughnessBonusOfAttacker(attacker, defender, combat);
|
int attackerLife = attacker.getKillDamage() + predictToughnessBonusOfAttacker(attacker, defender, combat);
|
||||||
|
|
||||||
if(attacker.getKeyword().contains("Double Strike") ) {
|
if(attacker.hasKeyword("Double Strike") ) {
|
||||||
if(attacker.getKeyword().contains("Deathtouch") && attackerDamage > 0) return true;
|
if(attacker.hasKeyword("Deathtouch") && attackerDamage > 0) return true;
|
||||||
if(attackerDamage >= defenderLife) return true;
|
if(attackerDamage >= defenderLife) return true;
|
||||||
|
|
||||||
//Attacker may kill the blocker before he can deal normal (secondary) damage
|
//Attacker may kill the blocker before he can deal normal (secondary) damage
|
||||||
if((defender.getKeyword().contains("Double Strike") || defender.getKeyword().contains("First Strike"))
|
if((defender.hasKeyword("Double Strike") || defender.hasKeyword("First Strike"))
|
||||||
&& !attacker.getKeyword().contains("Indestructible")) {
|
&& !attacker.hasKeyword("Indestructible")) {
|
||||||
if(defenderDamage >= attackerLife) return false;
|
if(defenderDamage >= attackerLife) return false;
|
||||||
if(defenderDamage > 0 && defender.getKeyword().contains("Deathtouch")) return false;
|
if(defenderDamage > 0 && defender.hasKeyword("Deathtouch")) return false;
|
||||||
}
|
}
|
||||||
if(defenderLife <= 2 * attackerDamage) return true;
|
if(defenderLife <= 2 * attackerDamage) return true;
|
||||||
}//attacker double strike
|
}//attacker double strike
|
||||||
@@ -1208,14 +1186,14 @@ public class CombatUtil {
|
|||||||
else //no double strike for attacker
|
else //no double strike for attacker
|
||||||
{
|
{
|
||||||
//Defender may kill the attacker before he can deal any damage
|
//Defender may kill the attacker before he can deal any damage
|
||||||
if(defender.getKeyword().contains("Double Strike") || defender.getKeyword().contains("First Strike")
|
if(defender.hasKeyword("Double Strike") || defender.hasKeyword("First Strike")
|
||||||
&& !attacker.getKeyword().contains("Indestructible") && !attacker.getKeyword().contains("First Strike")) {
|
&& !attacker.hasKeyword("Indestructible") && !attacker.hasKeyword("First Strike")) {
|
||||||
|
|
||||||
if(defenderDamage >= attackerLife) return false;
|
if(defenderDamage >= attackerLife) return false;
|
||||||
if(defenderDamage > 0 && defender.getKeyword().contains("Deathtouch")) return false;
|
if(defenderDamage > 0 && defender.hasKeyword("Deathtouch")) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(attacker.getKeyword().contains("Deathtouch") && attackerDamage > 0) return true;
|
if(attacker.hasKeyword("Deathtouch") && attackerDamage > 0) return true;
|
||||||
|
|
||||||
return attackerDamage >= defenderLife;
|
return attackerDamage >= defenderLife;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
package forge;
|
package forge;
|
||||||
|
|
||||||
|
import static forge.error.ErrorViewer.showError;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@@ -306,55 +308,7 @@ public class ComputerUtil
|
|||||||
|
|
||||||
static public boolean canPayCost(SpellAbility sa)
|
static public boolean canPayCost(SpellAbility sa)
|
||||||
{
|
{
|
||||||
Card card = sa.getSourceCard();
|
return canPayCost(sa, AllZone.ComputerPlayer);
|
||||||
|
|
||||||
CardList land = getAvailableMana();
|
|
||||||
|
|
||||||
if(sa.getSourceCard().isLand() /*&& sa.isTapAbility()*/)
|
|
||||||
{
|
|
||||||
land.remove(sa.getSourceCard());
|
|
||||||
}
|
|
||||||
// Beached - Delete old
|
|
||||||
String mana = sa.getPayCosts() != null ? sa.getPayCosts().getTotalMana() : sa.getManaCost();
|
|
||||||
|
|
||||||
ManaCost cost = new ManaCost(mana);
|
|
||||||
|
|
||||||
// Tack xMana Payments into mana here if X is a set value
|
|
||||||
if (sa.getPayCosts() != null && cost.getXcounter() > 0){
|
|
||||||
String xSvar = card.getSVar("X").equals("Count$xPaid") ? "PayX" : "X";
|
|
||||||
// For Count$xPaid set PayX in the AFs then use that here
|
|
||||||
// Else calculate it as appropriate.
|
|
||||||
if (!card.getSVar(xSvar).equals("")){
|
|
||||||
int manaToAdd = AbilityFactory.calculateAmount(card, xSvar, sa) * cost.getXcounter();
|
|
||||||
cost.increaseColorlessMana(manaToAdd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cost = AllZone.GameAction.getSpellCostChange(sa, cost);
|
|
||||||
if(cost.isPaid())
|
|
||||||
return canPayAdditionalCosts(sa);
|
|
||||||
// Beached - Delete old
|
|
||||||
ArrayList<String> colors;
|
|
||||||
|
|
||||||
for(int i = 0; i < land.size(); i++)
|
|
||||||
{
|
|
||||||
colors = getColors(land.get(i));
|
|
||||||
int once = 0;
|
|
||||||
|
|
||||||
for(int j =0; j < colors.size(); j++)
|
|
||||||
{
|
|
||||||
if(cost.isNeeded(colors.get(j)) && once == 0)
|
|
||||||
{
|
|
||||||
cost.payMana(colors.get(j));
|
|
||||||
once++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cost.isPaid()) {
|
|
||||||
return canPayAdditionalCosts(sa);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}//canPayCost()
|
}//canPayCost()
|
||||||
|
|
||||||
static public boolean canPayCost(SpellAbility sa, Player player)
|
static public boolean canPayCost(SpellAbility sa, Player player)
|
||||||
@@ -363,7 +317,7 @@ public class ComputerUtil
|
|||||||
|
|
||||||
CardList land = getAvailableMana(player);
|
CardList land = getAvailableMana(player);
|
||||||
|
|
||||||
if(card.isLand() && sa.getPayCosts().getTap())
|
if(card.isLand())
|
||||||
{
|
{
|
||||||
land.remove(card);
|
land.remove(card);
|
||||||
}
|
}
|
||||||
@@ -458,170 +412,7 @@ public class ComputerUtil
|
|||||||
|
|
||||||
static public boolean canPayAdditionalCosts(SpellAbility sa)
|
static public boolean canPayAdditionalCosts(SpellAbility sa)
|
||||||
{
|
{
|
||||||
// Add additional cost checks here before attempting to activate abilities
|
return canPayAdditionalCosts(sa, AllZone.ComputerPlayer);
|
||||||
Cost cost = sa.getPayCosts();
|
|
||||||
if (cost == null)
|
|
||||||
return true;
|
|
||||||
Card card = sa.getSourceCard();
|
|
||||||
|
|
||||||
if (cost.getTap() && (card.isTapped() || card.isSick()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (cost.getUntap() && (card.isUntapped() || card.isSick()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (cost.getTapXTypeCost())
|
|
||||||
{
|
|
||||||
CardList typeList = AllZoneUtil.getPlayerCardsInPlay(AllZone.ComputerPlayer);
|
|
||||||
typeList = typeList.getValidCards(cost.getTapXType().split(","),sa.getActivatingPlayer() ,sa.getSourceCard());
|
|
||||||
|
|
||||||
if (cost.getTap())
|
|
||||||
typeList.remove(sa.getSourceCard());
|
|
||||||
typeList = typeList.filter(AllZoneUtil.untapped);
|
|
||||||
|
|
||||||
if (cost.getTapXTypeAmount() > typeList.size())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cost.getSubCounter()){
|
|
||||||
Counters c = cost.getCounterType();
|
|
||||||
if (card.getCounters(c) - cost.getCounterNum() < 0 || !AllZoneUtil.isCardInPlay(card)){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cost.getAddCounter()){
|
|
||||||
// this should always be true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cost.getLifeCost()){
|
|
||||||
if (AllZone.ComputerPlayer.getLife() <= cost.getLifeAmount())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cost.getDiscardCost()){
|
|
||||||
CardList handList = AllZoneUtil.getPlayerHand(card.getController());
|
|
||||||
String discType = cost.getDiscardType();
|
|
||||||
int discAmount = cost.getDiscardAmount();
|
|
||||||
|
|
||||||
if (cost.getDiscardThis()){
|
|
||||||
if (!AllZone.getZone(card).getZoneName().equals(Constant.Zone.Hand))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if( discType.equals("LastDrawn")) {
|
|
||||||
//compy can't yet use this effectively
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (discType.equals("Hand")){
|
|
||||||
// this will always work
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (!discType.equals("Any") && !discType.equals("Random")){
|
|
||||||
String validType[] = discType.split(",");
|
|
||||||
handList = handList.getValidCards(validType, sa.getActivatingPlayer(), sa.getSourceCard());
|
|
||||||
}
|
|
||||||
if (discAmount > handList.size()){
|
|
||||||
// not enough cards in hand to pay
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cost.getSacCost()){
|
|
||||||
// if there's a sacrifice in the cost, just because we can Pay it doesn't mean we want to.
|
|
||||||
if (!cost.getSacThis()){
|
|
||||||
CardList typeList = AllZoneUtil.getPlayerCardsInPlay(AllZone.ComputerPlayer);
|
|
||||||
typeList = typeList.getValidCards(cost.getSacType().split(","), sa.getActivatingPlayer(), sa.getSourceCard());
|
|
||||||
Card target = sa.getTargetCard();
|
|
||||||
if (target != null && target.getController().isComputer()) // don't sacrifice the card we're pumping
|
|
||||||
typeList.remove(target);
|
|
||||||
|
|
||||||
if (cost.getSacAmount() > typeList.size())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (cost.getSacThis() && !AllZoneUtil.isCardInPlay(card))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cost.getExileCost()){
|
|
||||||
// if there's an exile in the cost, just because we can Pay it doesn't mean we want to.
|
|
||||||
if (!cost.getExileThis()){
|
|
||||||
CardList typeList = AllZoneUtil.getPlayerCardsInPlay(AllZone.ComputerPlayer);
|
|
||||||
typeList = typeList.getValidCards(cost.getExileType().split(","), sa.getActivatingPlayer(), sa.getSourceCard());
|
|
||||||
Card target = sa.getTargetCard();
|
|
||||||
if (target != null && target.getController().isComputer()) // don't exile the card we're pumping
|
|
||||||
typeList.remove(target);
|
|
||||||
|
|
||||||
if (cost.getExileAmount() > typeList.size())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (cost.getExileThis() && !AllZoneUtil.isCardInPlay(card))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cost.getExileFromHandCost()){
|
|
||||||
// if there's an exile in the cost, just because we can Pay it doesn't mean we want to.
|
|
||||||
if (!cost.getExileFromHandThis()){
|
|
||||||
CardList typeList = AllZoneUtil.getPlayerHand(AllZone.ComputerPlayer);
|
|
||||||
typeList = typeList.getValidCards(cost.getExileFromHandType().split(","), sa.getActivatingPlayer(), sa.getSourceCard());
|
|
||||||
Card target = sa.getTargetCard();
|
|
||||||
if (target != null && target.getController().isComputer()) // don't exile the card we're pumping
|
|
||||||
typeList.remove(target);
|
|
||||||
|
|
||||||
if (cost.getExileFromHandAmount() > typeList.size())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (cost.getExileFromHandThis() && !AllZoneUtil.isCardInPlayerHand(card.getController(), card))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cost.getExileFromGraveCost()){
|
|
||||||
if (!cost.getExileFromGraveThis()){
|
|
||||||
CardList typeList = AllZoneUtil.getPlayerGraveyard(AllZone.ComputerPlayer);
|
|
||||||
typeList = typeList.getValidCards(cost.getExileFromGraveType().split(","), sa.getActivatingPlayer(), sa.getSourceCard());
|
|
||||||
Card target = sa.getTargetCard();
|
|
||||||
if (target != null && target.getController().isComputer()) // don't exile the card we're pumping
|
|
||||||
typeList.remove(target);
|
|
||||||
|
|
||||||
if (cost.getExileFromGraveAmount() > typeList.size())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (cost.getExileFromGraveThis() && !AllZoneUtil.isCardInPlayerGraveyard(card.getController(), card))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cost.getExileFromTopCost()){
|
|
||||||
if(!cost.getExileFromTopThis()){
|
|
||||||
CardList typeList = AllZoneUtil.getPlayerCardsInLibrary(AllZone.ComputerPlayer);
|
|
||||||
typeList = typeList.getValidCards(cost.getExileFromTopType().split(","), sa.getActivatingPlayer(), sa.getSourceCard());
|
|
||||||
Card target = sa.getTargetCard();
|
|
||||||
if (target != null && target.getController().isComputer()) // don't exile the card we're pumping
|
|
||||||
typeList.remove(target);
|
|
||||||
|
|
||||||
if (cost.getExileFromTopAmount() > typeList.size())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (cost.getExileFromTopThis() && !AllZoneUtil.isCardInPlayerLibrary(card.getController(), card))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cost.getReturnCost()){
|
|
||||||
// if there's a return in the cost, just because we can Pay it doesn't mean we want to.
|
|
||||||
if (!cost.getReturnThis()){
|
|
||||||
CardList typeList = AllZoneUtil.getPlayerCardsInPlay(AllZone.ComputerPlayer);
|
|
||||||
typeList = typeList.getValidCards(cost.getReturnType().split(","), sa.getActivatingPlayer(), sa.getSourceCard());
|
|
||||||
Card target = sa.getTargetCard();
|
|
||||||
if (target != null && target.getController().isComputer()) // don't bounce the card we're pumping
|
|
||||||
typeList.remove(target);
|
|
||||||
|
|
||||||
if (cost.getReturnAmount() > typeList.size())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (!AllZoneUtil.isCardInPlay(card))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static public boolean canPayAdditionalCosts(SpellAbility sa, Player player)
|
static public boolean canPayAdditionalCosts(SpellAbility sa, Player player)
|
||||||
@@ -938,37 +729,7 @@ public class ComputerUtil
|
|||||||
|
|
||||||
static public CardList getAvailableMana()
|
static public CardList getAvailableMana()
|
||||||
{
|
{
|
||||||
CardList list = AllZoneUtil.getPlayerCardsInPlay(AllZone.ComputerPlayer);
|
return getAvailableMana(AllZone.ComputerPlayer);
|
||||||
CardList mana = list.filter(new CardListFilter()
|
|
||||||
{
|
|
||||||
public boolean addCard(Card c)
|
|
||||||
{
|
|
||||||
for (Ability_Mana am : c.getAIPlayableMana()) {
|
|
||||||
am.setActivatingPlayer(AllZone.ComputerPlayer);
|
|
||||||
if (am.canPlay()) return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});//CardListFilter
|
|
||||||
|
|
||||||
CardList sortedMana = new CardList();
|
|
||||||
|
|
||||||
for (int i=0; i<mana.size();i++)
|
|
||||||
{
|
|
||||||
Card card = mana.get(i);
|
|
||||||
if (card.isBasicLand()){
|
|
||||||
sortedMana.add(card);
|
|
||||||
mana.remove(card);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int j=0; j<mana.size();j++)
|
|
||||||
{
|
|
||||||
sortedMana.add(mana.get(j));
|
|
||||||
}
|
|
||||||
|
|
||||||
return sortedMana;
|
|
||||||
|
|
||||||
}//getAvailableMana()
|
}//getAvailableMana()
|
||||||
|
|
||||||
static public CardList getAvailableMana(final Player player)
|
static public CardList getAvailableMana(final Player player)
|
||||||
@@ -1261,4 +1022,26 @@ public class ComputerUtil
|
|||||||
AllZone.GameAction.sacrifice(c);
|
AllZone.GameAction.sacrifice(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean canRegenerate(Card card) {
|
||||||
|
Player controller = card.getController();
|
||||||
|
CardList l = AllZoneUtil.getCardsInPlay();
|
||||||
|
for(Card c:l)
|
||||||
|
for(SpellAbility sa:c.getSpellAbility())
|
||||||
|
// if SA is from AF_Counter don't add to getPlayable
|
||||||
|
//This try/catch should fix the "computer is thinking" bug
|
||||||
|
try {
|
||||||
|
if(sa.canPlay() && ComputerUtil.canPayCost(sa,controller) && sa.getAbilityFactory() != null && sa.isAbility()){
|
||||||
|
AbilityFactory af = sa.getAbilityFactory();
|
||||||
|
HashMap <String,String> mapParams = af.getMapParams();
|
||||||
|
if (mapParams.get("AB").equals("Regenerate"))
|
||||||
|
if (AbilityFactory.getDefinedCards(sa.getSourceCard(), mapParams.get("Defined"), sa).contains(card))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch(Exception ex) {
|
||||||
|
showError(ex, "There is an error in the card code for %s:%n", c.getName(), ex.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user