- The AI will no longer kill itself with damage from Eidolon of the Great Revel, Ruric Thar, the Unbowed, Spellshock or similar cards.

This commit is contained in:
Sloth
2015-07-19 11:38:59 +00:00
parent 6cc38f04ce
commit 9e9a5aea86
2 changed files with 83 additions and 3 deletions

View File

@@ -711,6 +711,11 @@ public class AiController {
return canPlayFromEffectAI((SpellPermanent)sa, false, true);
}
if (sa instanceof Spell) {
if (ComputerUtil.getDamageForPlaying(player, sa) >= player.getLife()
&& !player.cantLoseForZeroOrLessLife() && player.canLoseLife()) {
return AiPlayDecision.CurseEffects;
}
return canPlaySpellBasic(card);
}
return AiPlayDecision.WillPlay;
@@ -1009,6 +1014,13 @@ public class AiController {
public AiPlayDecision canPlayFromEffectAI(Spell spell, boolean mandatory, boolean withoutPayingManaCost) {
final Card card = spell.getHostCard();
int damage = ComputerUtil.getDamageForPlaying(player, spell);
if (damage >= player.getLife() && !player.cantLoseForZeroOrLessLife() && player.canLoseLife()) {
return AiPlayDecision.CurseEffects;
}
if (spell instanceof SpellApiBased) {
boolean chance = false;
if (withoutPayingManaCost) {
@@ -1081,7 +1093,7 @@ public class AiController {
if (!checkETBEffects(card, spell, null)) {
return AiPlayDecision.BadEtbEffects;
}
if (ComputerUtil.damageFromETB(player, card) >= player.getLife() && !player.cantLoseForZeroOrLessLife()
if (damage + ComputerUtil.getDamageFromETB(player, card) >= player.getLife() && !player.cantLoseForZeroOrLessLife()
&& player.canLoseLife()) {
return AiPlayDecision.BadEtbEffects;
}
@@ -1097,7 +1109,7 @@ public class AiController {
CardCollection landsWannaPlay = getLandsToPlay();
if (landsWannaPlay != null && !landsWannaPlay.isEmpty() && player.canPlayLand(null)) {
Card land = chooseBestLandToPlay(landsWannaPlay);
if (ComputerUtil.damageFromETB(player, land) < player.getLife() || !player.canLoseLife()
if (ComputerUtil.getDamageFromETB(player, land) < player.getLife() || !player.canLoseLife()
|| player.cantLoseForZeroOrLessLife() ) {
game.PLAY_LAND_SURROGATE.setHostCard(land);
final List<SpellAbility> abilities = new ArrayList<SpellAbility>();

View File

@@ -1766,8 +1766,76 @@ public class ComputerUtil {
});
return ComputerUtilCard.getBestCreatureAI(killables);
}
public static int getDamageForPlaying(final Player player, final SpellAbility sa) {
// check for bad spell cast triggers
int damage = 0;
final Game game = player.getGame();
final Card card = sa.getHostCard();
final FCollection<Trigger> theTriggers = new FCollection<Trigger>();
public static int damageFromETB(final Player player, final Card permanent) {
for (Card c : game.getCardsIn(ZoneType.Battlefield)) {
theTriggers.addAll(c.getTriggers());
}
for (Trigger trigger : theTriggers) {
Map<String, String> trigParams = trigger.getMapParams();
final Card source = trigger.getHostCard();
if (!trigger.zonesCheck(game.getZoneOf(source))) {
continue;
}
if (!trigger.requirementsCheck(game)) {
continue;
}
TriggerType mode = trigger.getMode();
if (mode != TriggerType.SpellCast) {
continue;
}
if (trigParams.containsKey("ValidCard")) {
if (!card.isValid(trigParams.get("ValidCard"), source.getController(), source)) {
continue;
}
}
if (trigParams.containsKey("ValidActivatingPlayer")) {
if (!player.isValid(trigParams.get("ValidActivatingPlayer"), source.getController(), source)) {
continue;
}
}
String ability = source.getSVar(trigParams.get("Execute"));
if (ability.isEmpty()) {
continue;
}
final Map<String, String> abilityParams = AbilityFactory.getMapParams(ability);
if ((abilityParams.containsKey("AB") && abilityParams.get("AB").equals("DealDamage"))
|| (abilityParams.containsKey("DB") && abilityParams.get("DB").equals("DealDamage"))) {
if (!"TriggeredActivator".equals(abilityParams.get("Defined"))) {
continue;
}
if (!abilityParams.containsKey("NumDmg")) {
continue;
}
damage += ComputerUtilCombat.predictDamageTo(player, AbilityUtils.calculateAmount(source, abilityParams.get("NumDmg"), null), source, false);
} else if ((abilityParams.containsKey("AB") && abilityParams.get("AB").equals("LoseLife"))
|| (abilityParams.containsKey("DB") && abilityParams.get("DB").equals("LoseLife"))) {
if (!"TriggeredActivator".equals(abilityParams.get("Defined"))) {
continue;
}
if (!abilityParams.containsKey("LifeAmount")) {
continue;
}
damage += AbilityUtils.calculateAmount(source, abilityParams.get("LifeAmount"), null);
}
}
return damage;
}
public static int getDamageFromETB(final Player player, final Card permanent) {
int damage = 0;
final Game game = player.getGame();
final FCollection<Trigger> theTriggers = new FCollection<Trigger>();