From caf6c73b7d7ab22fbc5c0ed5f761a80746eee181 Mon Sep 17 00:00:00 2001 From: Michael Kamensky Date: Sun, 9 Jun 2019 14:08:32 +0000 Subject: [PATCH] Fix Sorin, Vengeful Bloodlord and implement a basic AI for it. --- .../src/main/java/forge/ai/SpecialCardAi.java | 38 +++++++++++++++++++ .../java/forge/ai/ability/ChangeZoneAi.java | 2 + .../s/sorin_vengeful_bloodlord.txt | 3 +- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java index bdff0c1cb01..29e7c233aa0 100644 --- a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java +++ b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java @@ -1126,6 +1126,44 @@ public class SpecialCardAi { } } + // Sorin, Vengeful Bloodlord + public static class SorinVengefulBloodlord { + public static boolean consider(final Player ai, final SpellAbility sa) { + int loyalty = sa.getHostCard().getCounters(CounterType.LOYALTY); + CardCollection creaturesToGet = CardLists.filter(ai.getCardsIn(ZoneType.Graveyard), + Predicates.and(CardPredicates.Presets.CREATURES, CardPredicates.lessCMC(loyalty - 1), new Predicate() { + @Override + public boolean apply(Card card) { + final Card copy = CardUtil.getLKICopy(card); + ComputerUtilCard.applyStaticContPT(ai.getGame(), copy, null); + return copy.getNetToughness() > 0; + } + })); + CardLists.sortByCmcDesc(creaturesToGet); + + if (creaturesToGet.isEmpty()) { + return false; + } + + // pick the best creature that will stay on the battlefield + Card best = creaturesToGet.getFirst(); + for (Card c : creaturesToGet) { + if (best != c && ComputerUtilCard.evaluateCreature(c, true, false) > + ComputerUtilCard.evaluateCreature(best, true, false)) { + best = c; + } + } + + if (best != null) { + sa.resetTargets(); + sa.getTargets().add(best); + return true; + } + + return false; + } + } + // Survival of the Fittest public static class SurvivalOfTheFittest { public static Card considerDiscardTarget(final Player ai) { diff --git a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java index cf8cc117d8c..d2c4a7c55ef 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java @@ -121,6 +121,8 @@ public class ChangeZoneAi extends SpellAbilityAi { return SpecialCardAi.LivingDeath.consider(aiPlayer, sa); } else if (aiLogic.equals("TheScarabGod")) { return SpecialCardAi.TheScarabGod.consider(aiPlayer, sa); + } else if (aiLogic.equals("SorinVengefulBloodlord")) { + return SpecialCardAi.SorinVengefulBloodlord.consider(aiPlayer, sa); } else if (aiLogic.equals("Intuition")) { // This logic only fills the multiple cards array, the decision to play is made // separately in hiddenOriginCanPlayAI later. diff --git a/forge-gui/res/cardsfolder/s/sorin_vengeful_bloodlord.txt b/forge-gui/res/cardsfolder/s/sorin_vengeful_bloodlord.txt index 11291bb3ee1..dc657b9e48c 100644 --- a/forge-gui/res/cardsfolder/s/sorin_vengeful_bloodlord.txt +++ b/forge-gui/res/cardsfolder/s/sorin_vengeful_bloodlord.txt @@ -5,8 +5,7 @@ Loyalty:4 S:Mode$ Continuous | Affected$ Creature.YouCtrl,Planeswalker.YouCtrl | AddKeyword$ Lifelink | Condition$ PlayerTurn | Description$ As long as it's your turn, creatures and planeswalkers you control have lifelink. SVar:NonStackingEffect:True A:AB$ DealDamage | Cost$ AddCounter<2/LOYALTY> | Planeswalker$ True | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | NumDmg$ 1 | SpellDescription$ CARDNAME deals 1 damage to target player or planeswalker. -A:AB$ ChangeZone | Cost$ SubCounter | Planeswalker$ True | Origin$ Graveyard | Destination$ Battlefield | Announce$ X | References$ X | ValidTgts$ Creature.YouOwn | TgtPrompt$ Select target creature with converted mana cost X from your graveyard | SubAbility$ Animate | SpellDescription$ Return target creature card with converted mana cost X from your graveyard to the battlefield. That creature is a Vampire in addition to its other types. +A:AB$ ChangeZone | Cost$ SubCounter | Planeswalker$ True | Origin$ Graveyard | Destination$ Battlefield | References$ X | ValidTgts$ Creature.YouOwn | AILogic$ SorinVengefulBloodlord | TgtPrompt$ Select target creature with converted mana cost X from your graveyard | SubAbility$ Animate | SpellDescription$ Return target creature card with converted mana cost X from your graveyard to the battlefield. That creature is a Vampire in addition to its other types. SVar:Animate:DB$ Animate | Defined$ Targeted | Types$ Vampire | Permanent$ True SVar:X:Targeted$CardManaCost -AI:RemoveDeck:All Oracle:As long as it's your turn, creatures and planeswalkers you control have lifelink.\n[+2]: Sorin, Vengeful Bloodlord deals 1 damage to target player or planeswalker.\n-X: Return target creature card with converted mana cost X from your graveyard to the battlefield. That creature is a Vampire in addition to its other types.