- Basic AI for Drain Life (will only go for opponent's face for 3+ damage for now, to be improved later). Soul Burn currently doesn't work with this logic due to complex xColorManaPaid which I'm not sure how to set properly for the AI.

This commit is contained in:
Agetian
2017-01-26 19:20:37 +00:00
parent 51e0c469be
commit 5247793a68
2 changed files with 36 additions and 2 deletions

View File

@@ -4,32 +4,40 @@ import com.google.common.base.Predicate;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import forge.ai.*; import forge.ai.*;
import forge.card.mana.ManaCost;
import forge.card.mana.ManaCostParser;
import forge.game.Game; import forge.game.Game;
import forge.game.GameObject; import forge.game.GameObject;
import forge.game.ability.AbilityUtils; import forge.game.ability.AbilityUtils;
import forge.game.ability.ApiType;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardCollection; import forge.game.card.CardCollection;
import forge.game.card.CardLists; import forge.game.card.CardLists;
import forge.game.card.CardPredicates; import forge.game.card.CardPredicates;
import forge.game.card.CounterType; import forge.game.card.CounterType;
import forge.game.cost.Cost; import forge.game.cost.Cost;
import forge.game.mana.ManaCostBeingPaid;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerPredicates;
import forge.game.spellability.AbilitySub; import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetChoices; import forge.game.spellability.TargetChoices;
import forge.game.spellability.TargetRestrictions; import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.util.Aggregates; import forge.util.Aggregates;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
public class DamageDealAi extends DamageAiBase { public class DamageDealAi extends DamageAiBase {
@Override @Override
public boolean chkAIDrawback(SpellAbility sa, Player ai) { public boolean chkAIDrawback(SpellAbility sa, Player ai) {
final String damage = sa.getParam("NumDmg"); final String damage = sa.getParam("NumDmg");
int dmg = AbilityUtils.calculateAmount(sa.getHostCard(), damage, sa); int dmg = AbilityUtils.calculateAmount(sa.getHostCard(), damage, sa);
final String logic = sa.getParam("AILogic");
Card source = sa.getHostCard(); Card source = sa.getHostCard();
@@ -58,6 +66,11 @@ public class DamageDealAi extends DamageAiBase {
// Set PayX here to maximum value. // Set PayX here to maximum value.
dmg = ComputerUtilMana.determineLeftoverMana(sa, ai); dmg = ComputerUtilMana.determineLeftoverMana(sa, ai);
source.setSVar("PayX", Integer.toString(dmg)); source.setSVar("PayX", Integer.toString(dmg));
// Life Drain
if ("XLifeDrain".equals(logic)) {
return doXLifeDrainLogic(ai, sa, dmg);
}
} else if (sa.getSVar(damage).equals("Count$CardsInYourHand") && source.getZone().is(ZoneType.Hand)) { } else if (sa.getSVar(damage).equals("Count$CardsInYourHand") && source.getZone().is(ZoneType.Hand)) {
dmg--; // the card will be spent casting the spell, so actual damage is 1 less dmg--; // the card will be spent casting the spell, so actual damage is 1 less
} }
@@ -694,4 +707,26 @@ public class DamageDealAi extends DamageAiBase {
return true; return true;
} }
private boolean doXLifeDrainLogic(Player ai, SpellAbility sa, int origDmg) {
Card source = sa.getHostCard();
int dmg = origDmg - source.getCMC(); // otherwise AI incorrectly calculates mana it can afford
// detect the top ability that actually targets in Drain Life and Soul Burn scripts
SpellAbility saTgt = sa;
while (saTgt.getParent() != null) {
saTgt = saTgt.getParent();
}
saTgt.resetTargets();
saTgt.getTargets().add(ai.getOpponents().min(PlayerPredicates.compareByLife()));
// TODO: this currently does not work for Soul Burn because of xColorManaPaid (B/R) which the AI doesn't set
if (dmg >= 3) {
source.setSVar("PayX", Integer.toString(dmg));
return true;
}
// TODO: improve to make it also target creatures
return false;
}
} }

View File

@@ -3,11 +3,10 @@ ManaCost:X 1 B
Types:Sorcery Types:Sorcery
A:SP$ StoreSVar | Cost$ X 1 B | XColor$ B | ValidTgts$ Creature,Player | TgtPrompt$ Select target creature or player | SVar$ Limit | Type$ Targeted | Expression$ CardToughness | SubAbility$ StoreTgtP | ConditionDefined$ Targeted | ConditionPresent$ Card.Creature | ConditionCompare$ GE1 | SpellDescription$ Spend only black mana on X. CARDNAME deals X damage to target creature or player. You gain life equal to the damage dealt, but not more life than the player's life total before CARDNAME dealt damage or the creature's toughness. A:SP$ StoreSVar | Cost$ X 1 B | XColor$ B | ValidTgts$ Creature,Player | TgtPrompt$ Select target creature or player | SVar$ Limit | Type$ Targeted | Expression$ CardToughness | SubAbility$ StoreTgtP | ConditionDefined$ Targeted | ConditionPresent$ Card.Creature | ConditionCompare$ GE1 | SpellDescription$ Spend only black mana on X. CARDNAME deals X damage to target creature or player. You gain life equal to the damage dealt, but not more life than the player's life total before CARDNAME dealt damage or the creature's toughness.
SVar:StoreTgtP:DB$ StoreSVar | SVar$ Limit | Type$ Count | Expression$ TargetedLifeTotal | SubAbility$ DBDamage | ConditionDefined$ Targeted | ConditionPresent$ Card.Creature | ConditionCompare$ EQ0 SVar:StoreTgtP:DB$ StoreSVar | SVar$ Limit | Type$ Count | Expression$ TargetedLifeTotal | SubAbility$ DBDamage | ConditionDefined$ Targeted | ConditionPresent$ Card.Creature | ConditionCompare$ EQ0
SVar:DBDamage:DB$ DealDamage | Defined$ Targeted | NumDmg$ X | SubAbility$ DBGainLife | References$ X SVar:DBDamage:DB$ DealDamage | Defined$ Targeted | NumDmg$ X | SubAbility$ DBGainLife | AILogic$ XLifeDrain | References$ X
SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ DrainedLifeCard | References$ DrainedLifeCard SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ DrainedLifeCard | References$ DrainedLifeCard
SVar:X:Count$xPaid SVar:X:Count$xPaid
SVar:DrainedLifeCard:SVar$X/LimitMax.Limit SVar:DrainedLifeCard:SVar$X/LimitMax.Limit
SVar:Limit:Count$xPaid SVar:Limit:Count$xPaid
SVar:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/drain_life.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/drain_life.jpg
Oracle:Spend only black mana on X.\nDrain Life deals X damage to target creature or player. You gain life equal to the damage dealt, but not more life than the player's life total before Drain Life dealt damage or the creature's toughness. Oracle:Spend only black mana on X.\nDrain Life deals X damage to target creature or player. You gain life equal to the damage dealt, but not more life than the player's life total before Drain Life dealt damage or the creature's toughness.