From 887f2f9a52b67431532217e2063bdb60b786aa33 Mon Sep 17 00:00:00 2001 From: Seravy Date: Thu, 15 Feb 2018 00:53:40 +0100 Subject: [PATCH 1/5] Mark Spirit Mirror and Breeding Pit tokens as things to sacrifice. If Grave Pact is in play, activate Spirit Mirror to destroy own token and force enemy to sac a creature if possible. --- .../main/java/forge/ai/ability/DestroyAi.java | 22 +++++++++++++++++++ forge-gui/res/cardsfolder/b/breeding_pit.txt | 3 ++- forge-gui/res/cardsfolder/s/spirit_mirror.txt | 5 +++-- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java b/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java index 9770e0e756d..16dd5e3f950 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java @@ -32,6 +32,28 @@ public class DestroyAi extends SpellAbilityAi { final String logic = sa.getParam("AILogic"); boolean hasXCost = false; + // Ability that's intended to destroy own useless token to trigger Grave Pacts + // should be fired at end of turn or when under attack after blocking to make opponent sac something + boolean havepact = false; + for (Card cardInPlay : ai.getGame().getCardsIn(ZoneType.Battlefield)) { + if ((cardInPlay.getController().equals(ai)) + && ("Grave_Pact".equals(cardInPlay.getName()))) { + havepact = true; + } + } + if ("Pactivator".equals(logic)) { + if ( + (!ai.getGame().getPhaseHandler().isPlayerTurn(ai)) && + ((ai.getGame().getPhaseHandler().is(PhaseType.END_OF_TURN)) + || (ai.getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS))) + && + (ai.getOpponents().get(0).getCreaturesInPlay().size() > 0) + && (havepact) + ) { + return ai.getController().chooseTargetsFor(sa); + } + } + CardCollection list; if (abCost != null) { diff --git a/forge-gui/res/cardsfolder/b/breeding_pit.txt b/forge-gui/res/cardsfolder/b/breeding_pit.txt index 6727d95f238..d435caf407c 100644 --- a/forge-gui/res/cardsfolder/b/breeding_pit.txt +++ b/forge-gui/res/cardsfolder/b/breeding_pit.txt @@ -3,6 +3,7 @@ ManaCost:3 B Types:Enchantment K:UpkeepCost:B B T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ At the beginning of your end step, create a 0/1 black Thrull creature token. -SVar:TrigToken:DB$Token | TokenImage$ b 0 1 thrull | TokenName$ Thrull | TokenColors$ Black | TokenTypes$ Creature,Thrull | TokenPower$ 0 | TokenToughness$ 1 | TokenOwner$ You | TokenAmount$ 1 +SVar:TrigToken:DB$Token | TokenImage$ b 0 1 thrull | TokenName$ Thrull | TokenColors$ Black | TokenTypes$ Creature,Thrull | TokenPower$ 0 | TokenToughness$ 1 | TokenOwner$ You | TokenAmount$ 1 | TokenSVar$ PitSac +SVar:PitSac:SVar:SacMe:1 SVar:Picture:http://www.wizards.com/global/images/magic/general/breeding_pit.jpg Oracle:At the beginning of your upkeep, sacrifice Breeding Pit unless you pay {B}{B}.\nAt the beginning of your end step, create a 0/1 black Thrull creature token. diff --git a/forge-gui/res/cardsfolder/s/spirit_mirror.txt b/forge-gui/res/cardsfolder/s/spirit_mirror.txt index f0e8c68ba99..b6f838bfe50 100644 --- a/forge-gui/res/cardsfolder/s/spirit_mirror.txt +++ b/forge-gui/res/cardsfolder/s/spirit_mirror.txt @@ -2,7 +2,8 @@ Name:Spirit Mirror ManaCost:2 W W Types:Enchantment T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | IsPresent$ Reflection.token | PresentCompare$ EQ0 | Execute$ TrigToken | TriggerDescription$ At the beginning of your upkeep, if there are no Reflection tokens on the battlefield, create a 2/2 white Reflection creature token. -SVar:TrigToken:DB$Token | TokenAmount$ 1 | TokenName$ Reflection | TokenTypes$ Creature,Reflection | TokenOwner$ You | TokenColors$ White | TokenPower$ 2 | TokenToughness$ 2 -A:AB$ Destroy | Cost$ 0 | ValidTgts$ Reflection | TgtPrompt$ Select target Reflection | SpellDescription$ Destroy target Reflection. +SVar:TrigToken:DB$Token | TokenAmount$ 1 | TokenName$ Reflection | TokenTypes$ Creature,Reflection | TokenOwner$ You | TokenColors$ White | TokenPower$ 2 | TokenToughness$ 2 | TokenSVar$ ReflectionSac +A:AB$ Destroy | Cost$ 0 | ValidTgts$ Reflection | TgtPrompt$ Select target Reflection | AILogic$ Pactivator| SpellDescription$ Destroy target Reflection. +SVar:ReflectionSac:SVar:SacMe:2 SVar:Picture:http://www.wizards.com/global/images/magic/general/spirit_mirror.jpg Oracle:At the beginning of your upkeep, if there are no Reflection tokens on the battlefield, create a 2/2 white Reflection creature token.\n{0}: Destroy target Reflection. From c47242e40e6a7145eaf2bdc0068dbf4a5145b948 Mon Sep 17 00:00:00 2001 From: Seravy Date: Thu, 15 Feb 2018 11:25:08 +0100 Subject: [PATCH 2/5] fixed card name --- forge-ai/src/main/java/forge/ai/ability/DestroyAi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java b/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java index 16dd5e3f950..2c46009acd6 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java @@ -37,7 +37,7 @@ public class DestroyAi extends SpellAbilityAi { boolean havepact = false; for (Card cardInPlay : ai.getGame().getCardsIn(ZoneType.Battlefield)) { if ((cardInPlay.getController().equals(ai)) - && ("Grave_Pact".equals(cardInPlay.getName()))) { + && ("Grave Pact".equals(cardInPlay.getName()))) { havepact = true; } } From f271c7a74eef1d82a4e0b9fbddd86c21a57e1822 Mon Sep 17 00:00:00 2001 From: Seravy Date: Thu, 15 Feb 2018 12:34:06 +0100 Subject: [PATCH 3/5] Now the AI properly realizes this can be played, but doesn't actually play it. Is there something that prevents it from playing things that destroy own tokens? --- forge-ai/src/main/java/forge/ai/ability/DestroyAi.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java b/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java index 2c46009acd6..4051d3bd339 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java @@ -41,16 +41,16 @@ public class DestroyAi extends SpellAbilityAi { havepact = true; } } - if ("Pactivator".equals(logic)) { + if (("Pactivator".equals(logic)) && (havepact)) { if ( (!ai.getGame().getPhaseHandler().isPlayerTurn(ai)) && ((ai.getGame().getPhaseHandler().is(PhaseType.END_OF_TURN)) || (ai.getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS))) && (ai.getOpponents().get(0).getCreaturesInPlay().size() > 0) - && (havepact) ) { - return ai.getController().chooseTargetsFor(sa); + sa.getTargetRestrictions().setMandatory(true); + return true; //ai.getController().chooseTargetsFor(sa); } } From 602f761552a29e31d4c5f2cd226871db64ce53f2 Mon Sep 17 00:00:00 2001 From: Seravy Date: Fri, 16 Feb 2018 00:04:25 +0100 Subject: [PATCH 4/5] This should work? --- .../main/java/forge/ai/ability/DestroyAi.java | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java b/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java index 4051d3bd339..ae0c36e2c7d 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DestroyAi.java @@ -32,28 +32,6 @@ public class DestroyAi extends SpellAbilityAi { final String logic = sa.getParam("AILogic"); boolean hasXCost = false; - // Ability that's intended to destroy own useless token to trigger Grave Pacts - // should be fired at end of turn or when under attack after blocking to make opponent sac something - boolean havepact = false; - for (Card cardInPlay : ai.getGame().getCardsIn(ZoneType.Battlefield)) { - if ((cardInPlay.getController().equals(ai)) - && ("Grave Pact".equals(cardInPlay.getName()))) { - havepact = true; - } - } - if (("Pactivator".equals(logic)) && (havepact)) { - if ( - (!ai.getGame().getPhaseHandler().isPlayerTurn(ai)) && - ((ai.getGame().getPhaseHandler().is(PhaseType.END_OF_TURN)) - || (ai.getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS))) - && - (ai.getOpponents().get(0).getCreaturesInPlay().size() > 0) - ) { - sa.getTargetRestrictions().setMandatory(true); - return true; //ai.getController().chooseTargetsFor(sa); - } - } - CardCollection list; if (abCost != null) { @@ -93,6 +71,28 @@ public class DestroyAi extends SpellAbilityAi { return false; } + // Ability that's intended to destroy own useless token to trigger Grave Pacts + // should be fired at end of turn or when under attack after blocking to make opponent sac something + boolean havepact = false; + for (Card cardInPlay : ai.getGame().getCardsIn(ZoneType.Battlefield)) { + if ((cardInPlay.getController().equals(ai)) + && ("Grave Pact".equals(cardInPlay.getName()))) { + havepact = true; + } + } + if (("Pactivator".equals(logic)) && (havepact)) { + if ( + (!ai.getGame().getPhaseHandler().isPlayerTurn(ai)) && + ((ai.getGame().getPhaseHandler().is(PhaseType.END_OF_TURN)) + || (ai.getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS))) + && + (ai.getOpponents().get(0).getCreaturesInPlay().size() > 0) + ) { + ai.getController().chooseTargetsFor(sa); + return true; + } + } + // Targeting if (abTgt != null) { sa.resetTargets(); From 229ecc9ba7671006da07df602fa609ee886f8bd6 Mon Sep 17 00:00:00 2001 From: Seravy Date: Fri, 16 Feb 2018 00:51:56 +0100 Subject: [PATCH 5/5] missing an "s" in script --- forge-gui/res/cardsfolder/b/breeding_pit.txt | 2 +- forge-gui/res/cardsfolder/s/spirit_mirror.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui/res/cardsfolder/b/breeding_pit.txt b/forge-gui/res/cardsfolder/b/breeding_pit.txt index d435caf407c..af0adad2d40 100644 --- a/forge-gui/res/cardsfolder/b/breeding_pit.txt +++ b/forge-gui/res/cardsfolder/b/breeding_pit.txt @@ -3,7 +3,7 @@ ManaCost:3 B Types:Enchantment K:UpkeepCost:B B T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ At the beginning of your end step, create a 0/1 black Thrull creature token. -SVar:TrigToken:DB$Token | TokenImage$ b 0 1 thrull | TokenName$ Thrull | TokenColors$ Black | TokenTypes$ Creature,Thrull | TokenPower$ 0 | TokenToughness$ 1 | TokenOwner$ You | TokenAmount$ 1 | TokenSVar$ PitSac +SVar:TrigToken:DB$Token | TokenImage$ b 0 1 thrull | TokenName$ Thrull | TokenColors$ Black | TokenTypes$ Creature,Thrull | TokenPower$ 0 | TokenToughness$ 1 | TokenOwner$ You | TokenAmount$ 1 | TokenSVars$ PitSac SVar:PitSac:SVar:SacMe:1 SVar:Picture:http://www.wizards.com/global/images/magic/general/breeding_pit.jpg Oracle:At the beginning of your upkeep, sacrifice Breeding Pit unless you pay {B}{B}.\nAt the beginning of your end step, create a 0/1 black Thrull creature token. diff --git a/forge-gui/res/cardsfolder/s/spirit_mirror.txt b/forge-gui/res/cardsfolder/s/spirit_mirror.txt index b6f838bfe50..099ffe7b808 100644 --- a/forge-gui/res/cardsfolder/s/spirit_mirror.txt +++ b/forge-gui/res/cardsfolder/s/spirit_mirror.txt @@ -2,7 +2,7 @@ Name:Spirit Mirror ManaCost:2 W W Types:Enchantment T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | IsPresent$ Reflection.token | PresentCompare$ EQ0 | Execute$ TrigToken | TriggerDescription$ At the beginning of your upkeep, if there are no Reflection tokens on the battlefield, create a 2/2 white Reflection creature token. -SVar:TrigToken:DB$Token | TokenAmount$ 1 | TokenName$ Reflection | TokenTypes$ Creature,Reflection | TokenOwner$ You | TokenColors$ White | TokenPower$ 2 | TokenToughness$ 2 | TokenSVar$ ReflectionSac +SVar:TrigToken:DB$Token | TokenAmount$ 1 | TokenName$ Reflection | TokenTypes$ Creature,Reflection | TokenOwner$ You | TokenColors$ White | TokenPower$ 2 | TokenToughness$ 2 | TokenSVars$ ReflectionSac A:AB$ Destroy | Cost$ 0 | ValidTgts$ Reflection | TgtPrompt$ Select target Reflection | AILogic$ Pactivator| SpellDescription$ Destroy target Reflection. SVar:ReflectionSac:SVar:SacMe:2 SVar:Picture:http://www.wizards.com/global/images/magic/general/spirit_mirror.jpg