mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
- 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:
@@ -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>();
|
||||
|
||||
@@ -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>();
|
||||
|
||||
Reference in New Issue
Block a user