From f57df312c0c4611d16d9ed4e7b6d46f387cb19fb Mon Sep 17 00:00:00 2001
From: Sloth
Date: Sat, 29 Nov 2014 12:03:55 +0000
Subject: [PATCH] - Improved AI handling Mishra's Factory.
---
.../src/main/java/forge/ai/AiController.java | 7 ++-
.../java/forge/ai/ComputerUtilCombat.java | 62 +++++++++----------
.../main/java/forge/ai/ability/AnimateAi.java | 2 +-
.../main/java/forge/ai/ability/PumpAi.java | 2 +-
.../java/forge/ai/ability/PumpAiBase.java | 3 +-
5 files changed, 40 insertions(+), 36 deletions(-)
diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java
index 0334ed72fc7..2ed7fd995ab 100644
--- a/forge-ai/src/main/java/forge/ai/AiController.java
+++ b/forge-ai/src/main/java/forge/ai/AiController.java
@@ -794,9 +794,9 @@ public class AiController {
}
// cast 0 mana cost spells first (might be a Mox)
- if (a1 == 0 && b1 > 0) {
+ if (a1 == 0 && b1 > 0 && ApiType.Mana != a.getApi()) {
return -1;
- } else if (a1 > 0 && b1 == 0) {
+ } else if (a1 > 0 && b1 == 0 && ApiType.Mana != b.getApi()) {
return 1;
}
@@ -836,6 +836,9 @@ public class AiController {
if (ApiType.DestroyAll == sa.getApi()) {
p += 4;
+ }
+ else if (ApiType.Mana == sa.getApi()) {
+ p -= 9;
}
return p;
diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java
index f84a30664ca..2bf6bea71e5 100644
--- a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java
+++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java
@@ -1780,7 +1780,7 @@ public class ComputerUtilCombat {
*
* @param ai
*
- * @param defender
+ * @param blocker
* a {@link forge.game.card.Card} object.
* @param attacker
* a {@link forge.game.card.Card} object.
@@ -1790,7 +1790,7 @@ public class ComputerUtilCombat {
* a boolean.
* @return a boolean.
*/
- public static boolean canDestroyBlocker(Player ai, final Card defender, final Card attacker, final Combat combat,
+ public static boolean canDestroyBlocker(Player ai, final Card blocker, final Card attacker, final Combat combat,
final boolean withoutAbilities) {
final Game game = ai.getGame();
@@ -1803,76 +1803,76 @@ public class ComputerUtilCombat {
}
int flankingMagnitude = 0;
- if (attacker.hasKeyword("Flanking") && !defender.hasKeyword("Flanking")) {
+ if (attacker.hasKeyword("Flanking") && !blocker.hasKeyword("Flanking")) {
flankingMagnitude = attacker.getAmountOfKeyword("Flanking");
- if (flankingMagnitude >= defender.getNetToughness()) {
+ if (flankingMagnitude >= blocker.getNetToughness()) {
return true;
}
- if ((flankingMagnitude >= ComputerUtilCombat.getDamageToKill(defender)) && !defender.hasKeyword("Indestructible")) {
+ if ((flankingMagnitude >= ComputerUtilCombat.getDamageToKill(blocker)) && !blocker.hasKeyword("Indestructible")) {
return true;
}
} // flanking
- if (((defender.hasKeyword("Indestructible") || (ComputerUtil.canRegenerate(ai, defender) && !withoutAbilities)) && !(attacker
+ if (((blocker.hasKeyword("Indestructible") || (ComputerUtil.canRegenerate(ai, blocker) && !withoutAbilities)) && !(attacker
.hasKeyword("Wither") || attacker.hasKeyword("Infect")))
- || (defender.hasKeyword("Persist") && !defender.canReceiveCounters(CounterType.M1M1) && (defender
+ || (blocker.hasKeyword("Persist") && !blocker.canReceiveCounters(CounterType.M1M1) && (blocker
.getCounters(CounterType.M1M1) == 0))
- || (defender.hasKeyword("Undying") && !defender.canReceiveCounters(CounterType.P1P1) && (defender
+ || (blocker.hasKeyword("Undying") && !blocker.canReceiveCounters(CounterType.P1P1) && (blocker
.getCounters(CounterType.P1P1) == 0))) {
return false;
}
- if (checkDestroyBlockerTrigger(attacker, defender) && !defender.hasKeyword("Indestructible")) {
+ if (checkDestroyBlockerTrigger(attacker, blocker) && !blocker.hasKeyword("Indestructible")) {
return true;
}
- if (defender.isEquipped()) {
- for (Card equipment : defender.getEquippedBy(false)) {
+ if (blocker.isEquipped()) {
+ for (Card equipment : blocker.getEquippedBy(false)) {
if (equipment.getName().equals("Godsend")) {
return false;
}
}
}
- int defenderDamage = defender.getNetPower()
- + ComputerUtilCombat.predictPowerBonusOfBlocker(attacker, defender, withoutAbilities);
+ int defenderDamage = blocker.getNetPower()
+ + ComputerUtilCombat.predictPowerBonusOfBlocker(attacker, blocker, withoutAbilities);
int attackerDamage = attacker.getNetPower()
- + ComputerUtilCombat.predictPowerBonusOfAttacker(attacker, defender, combat, withoutAbilities);
+ + ComputerUtilCombat.predictPowerBonusOfAttacker(attacker, blocker, combat, withoutAbilities);
if (game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.toughnessAssignsDamage)) {
- defenderDamage = defender.getNetToughness()
- + ComputerUtilCombat.predictToughnessBonusOfBlocker(attacker, defender, withoutAbilities);
+ defenderDamage = blocker.getNetToughness()
+ + ComputerUtilCombat.predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities);
attackerDamage = attacker.getNetToughness()
- + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, defender, combat, withoutAbilities);
+ + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities);
}
int possibleDefenderPrevention = 0;
int possibleAttackerPrevention = 0;
if (!withoutAbilities) {
- possibleDefenderPrevention = ComputerUtil.possibleDamagePrevention(defender);
+ possibleDefenderPrevention = ComputerUtil.possibleDamagePrevention(blocker);
possibleAttackerPrevention = ComputerUtil.possibleDamagePrevention(attacker);
}
// consider Damage Prevention/Replacement
- defenderDamage = predictDamageTo(attacker, defenderDamage, possibleAttackerPrevention, defender, true);
- attackerDamage = predictDamageTo(defender, attackerDamage, possibleDefenderPrevention, attacker, true);
+ defenderDamage = predictDamageTo(attacker, defenderDamage, possibleAttackerPrevention, blocker, true);
+ attackerDamage = predictDamageTo(blocker, attackerDamage, possibleDefenderPrevention, attacker, true);
if (combat != null) {
- for (Card atkr : combat.getAttackersBlockedBy(defender)) {
+ for (Card atkr : combat.getAttackersBlockedBy(blocker)) {
if (!atkr.equals(attacker)) {
- attackerDamage += predictDamageTo(defender, atkr.getNetCombatDamage(), 0, atkr, true);
+ attackerDamage += predictDamageTo(blocker, atkr.getNetCombatDamage(), 0, atkr, true);
}
}
}
- final int defenderLife = ComputerUtilCombat.getDamageToKill(defender)
- + ComputerUtilCombat.predictToughnessBonusOfBlocker(attacker, defender, withoutAbilities);
+ final int defenderLife = ComputerUtilCombat.getDamageToKill(blocker)
+ + ComputerUtilCombat.predictToughnessBonusOfBlocker(attacker, blocker, withoutAbilities);
final int attackerLife = ComputerUtilCombat.getDamageToKill(attacker)
- + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, defender, combat, withoutAbilities);
+ + ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, withoutAbilities);
if (attacker.hasKeyword("Double Strike")) {
- if (attackerDamage > 0 && (hasKeyword(attacker, "Deathtouch", withoutAbilities, combat) || defender.hasSVar("DestroyWhenDamaged"))) {
+ if (attackerDamage > 0 && (hasKeyword(attacker, "Deathtouch", withoutAbilities, combat) || blocker.hasSVar("DestroyWhenDamaged"))) {
return true;
}
if (attackerDamage >= defenderLife) {
@@ -1881,11 +1881,11 @@ public class ComputerUtilCombat {
// Attacker may kill the blocker before he can deal normal
// (secondary) damage
- if (dealsFirstStrikeDamage(defender, withoutAbilities, combat) && !attacker.hasKeyword("Indestructible")) {
+ if (dealsFirstStrikeDamage(blocker, withoutAbilities, combat) && !attacker.hasKeyword("Indestructible")) {
if (defenderDamage >= attackerLife) {
return false;
}
- if (defenderDamage > 0 && (hasKeyword(defender, "Deathtouch", withoutAbilities, combat) || attacker.hasSVar("DestroyWhenDamaged"))) {
+ if (defenderDamage > 0 && (hasKeyword(blocker, "Deathtouch", withoutAbilities, combat) || attacker.hasSVar("DestroyWhenDamaged"))) {
return false;
}
}
@@ -1896,18 +1896,18 @@ public class ComputerUtilCombat {
else { // no double strike for attacker
// Defender may kill the attacker before he can deal any damage
- if (dealsFirstStrikeDamage(defender, withoutAbilities, combat) && !attacker.hasKeyword("Indestructible")
+ if (dealsFirstStrikeDamage(blocker, withoutAbilities, combat) && !attacker.hasKeyword("Indestructible")
&& !dealsFirstStrikeDamage(attacker, withoutAbilities, combat)) {
if (defenderDamage >= attackerLife) {
return false;
}
- if (defenderDamage > 0 && (hasKeyword(defender, "Deathtouch", withoutAbilities, combat) || attacker.hasSVar("DestroyWhenDamaged"))) {
+ if (defenderDamage > 0 && (hasKeyword(blocker, "Deathtouch", withoutAbilities, combat) || attacker.hasSVar("DestroyWhenDamaged"))) {
return false;
}
}
- if (attackerDamage > 0 && (hasKeyword(attacker, "Deathtouch", withoutAbilities, combat) || defender.hasSVar("DestroyWhenDamaged"))) {
+ if (attackerDamage > 0 && (hasKeyword(attacker, "Deathtouch", withoutAbilities, combat) || blocker.hasSVar("DestroyWhenDamaged"))) {
return true;
}
diff --git a/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java b/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java
index 679f7efadad..702a5522302 100644
--- a/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java
+++ b/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java
@@ -152,7 +152,7 @@ public class AnimateAi extends SpellAbilityAi {
boolean givesHaste = sa.hasParam("Keywords") && sa.getParam("Keywords").contains("Haste");
for (final Card c : defined) {
bFlag |= !c.isCreature() && !c.isTapped()
- && (c.getTurnInZone() != game.getPhaseHandler().getTurn() || givesHaste)
+ && (c.getTurnInZone() != ph.getTurn() || givesHaste || ph.getPlayerTurn().isOpponentOf(aiPlayer))
&& !c.isEquipping();
// for creatures that could be improved (like Figure of Destiny)
diff --git a/forge-ai/src/main/java/forge/ai/ability/PumpAi.java b/forge-ai/src/main/java/forge/ai/ability/PumpAi.java
index 29e9d8d8e64..1c1357f4d8d 100644
--- a/forge-ai/src/main/java/forge/ai/ability/PumpAi.java
+++ b/forge-ai/src/main/java/forge/ai/ability/PumpAi.java
@@ -324,7 +324,7 @@ public class PumpAi extends PumpAiBase {
list.remove(sa.getHostCard());
}
if (game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS)
- && game.getPhaseHandler().isPlayerTurn(opp)) {
+ && game.getPhaseHandler().getPlayerTurn().isOpponentOf(ai)) {
list.remove(sa.getHostCard());
}
}
diff --git a/forge-ai/src/main/java/forge/ai/ability/PumpAiBase.java b/forge-ai/src/main/java/forge/ai/ability/PumpAiBase.java
index 0bbc7b6463d..c8627ff088b 100644
--- a/forge-ai/src/main/java/forge/ai/ability/PumpAiBase.java
+++ b/forge-ai/src/main/java/forge/ai/ability/PumpAiBase.java
@@ -436,7 +436,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
return false;
}
- if ((c.getNetToughness() + defense) <= 0) {
+ if (c.getNetToughness() + defense <= 0) {
return false;
}
@@ -754,6 +754,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
kws.add(kw);
}
}
+ pumped.addNewPT(c.getCurrentPower(), c.getCurrentPower(), timestamp);
pumped.addTempPowerBoost(c.getTempPowerBoost() + a);
pumped.addTempToughnessBoost(c.getTempToughnessBoost() + d);
pumped.addChangedCardKeywords(kws, new ArrayList(), false, timestamp);