AI: Fix counters calculation for Wildborn Preserver activation (#3119)

* - Remove legacy hacky code that's apparently not needed anymore.

* - Fix imports.

* - Restore the original code but tweak it to hopefully accomodate for Wildborn Preserver.

* - Clean up / clarify.

* Remove fake SVar

---------

Co-authored-by: tool4EvEr <tool4EvEr@192.168.0.59>
This commit is contained in:
Agetian
2023-05-16 21:42:48 +03:00
committed by GitHub
parent 5067d207a5
commit 6753ad23ad
6 changed files with 13 additions and 63 deletions

View File

@@ -1,43 +1,18 @@
package forge.ai.ability;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.ai.AiCardMemory;
import forge.ai.AiProps;
import forge.ai.ComputerUtil;
import forge.ai.ComputerUtilAbility;
import forge.ai.ComputerUtilCard;
import forge.ai.ComputerUtilCombat;
import forge.ai.ComputerUtilCost;
import forge.ai.PlayerControllerAi;
import forge.ai.SpecialAiLogic;
import forge.ai.SpecialCardAi;
import forge.ai.SpellAbilityAi;
import forge.card.CardStateName;
import forge.ai.*;
import forge.game.Game;
import forge.game.GameEntity;
import forge.game.ability.AbilityUtils;
import forge.game.ability.ApiType;
import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.card.CardLists;
import forge.game.card.CardPredicates;
import forge.game.card.CounterEnumType;
import forge.game.card.CounterType;
import forge.game.card.*;
import forge.game.combat.Combat;
import forge.game.combat.CombatUtil;
import forge.game.cost.Cost;
import forge.game.cost.CostPart;
import forge.game.cost.CostPutCounter;
import forge.game.cost.CostRemoveCounter;
import forge.game.cost.CostSacrifice;
import forge.game.cost.*;
import forge.game.keyword.Keyword;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
@@ -54,6 +29,10 @@ import forge.game.zone.ZoneType;
import forge.util.Aggregates;
import forge.util.MyRandom;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class CountersPutAi extends CountersAi {
/*
@@ -774,38 +753,17 @@ public class CountersPutAi extends CountersAi {
}
if (!sa.usesTargeting()) {
// No target. So must be defined
list = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa);
// No target. So must be defined. (Unused at the moment)
// list = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa);
if (amountStr.equals("X")
&& root.getXManaCostPaid() == null
&& source.getXManaCostPaid() == 0 /* SubAbility on something that already had set PayX, e.g. Endless One ETB counters */
&& source.getXManaCostPaid() == 0 // SubAbility on something that already had set PayX, e.g. Endless One ETB counters
&& amount == 0 // And counter amount wasn't set previously by something (e.g. Wildborn Preserver)
&& sa.hasSVar(amountStr) && sa.getSVar(amountStr).equals("Count$xPaid")) {
// detect if there's more than one X in the cost (Hangarback Walker, Walking Ballista, etc.)
SpellAbility testSa = sa;
int countX = 0;
int nonXGlyphs = 0;
while (testSa != null && countX == 0) {
countX = testSa.getPayCosts().getTotalMana().countX();
nonXGlyphs = testSa.getPayCosts().getTotalMana().getGlyphCount() - countX;
testSa = testSa.getSubAbility();
}
if (countX == 0) {
// try determining it from the card itself if neither SA has "X" in the cost
countX = source.getState(CardStateName.Original).getManaCost().countX();
nonXGlyphs = source.getState(CardStateName.Original).getManaCost().getGlyphCount() - countX;
}
// Spend all remaining mana to add X counters (eg. Hero of Leina Tower)
int payX = ComputerUtilCost.getMaxXValue(sa, ai, true);
// Account for the possible presence of additional glyphs in cost (e.g. Mikaeus, the Lunarch; Primordial Hydra)
payX -= nonXGlyphs;
// Account for the multiple X in cost
if (countX > 1) { payX /= countX; }
root.setXManaCostPaid(payX);
}

View File

@@ -36,17 +36,11 @@ public class ImmediateTriggerAi extends SpellAbilityAi {
return true;
}
String logic = sa.getParamOrDefault("AILogic", "");
SpellAbility trigsa = sa.getAdditionalAbility("Execute");
if (trigsa == null) {
return false;
}
if (logic.equals("MaxX")) {
sa.setXManaCostPaid(ComputerUtilCost.getMaxXValue(sa, ai, true));
}
AiController aic = ((PlayerControllerAi)ai.getController()).getAi();
trigsa.setActivatingPlayer(ai, true);

View File

@@ -4,6 +4,5 @@ Types:Sorcery
A:SP$ Token | Cost$ X W B | TokenAmount$ X | TokenScript$ wb_2_1_inkling_flying | TokenTapped$ True | SubAbility$ BlotDestroy | SpellDescription$ Create X tapped 2/1 white and black Inkling creature tokens with flying. If X is 6 or more, destroy all noncreature, nonland permanents.
SVar:BlotDestroy:DB$ DestroyAll | ValidCards$ Permanent.nonCreature+nonLand | ConditionCheckSVar$ X | ConditionSVarCompare$ GE6
SVar:X:Count$xPaid
SVar:PayX:6
DeckHas:Ability$Token
Oracle:Create X tapped 2/1 white and black Inkling creature tokens with flying. If X is 6 or more, destroy all noncreature, nonland permanents.

View File

@@ -21,7 +21,7 @@ Types:Enchantment Creature Dragon Spirit
PT:2/2
K:Flying
T:Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Creature.Other+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigImmediateTrig | TriggerDescription$ Whenever another creature enters the battlefield under your control, you may pay {X}. When you do, put X +1/+1 counters on that creature.
SVar:TrigImmediateTrig:AB$ ImmediateTrigger | Cost$ X | Execute$ TrigPutCounter | RememberObjects$ TriggeredCardLKICopy | AILogic$ MaxX | TriggerDescription$ When you do, put X +1/+1 counters on that creature.
SVar:TrigImmediateTrig:AB$ ImmediateTrigger | Cost$ X | Execute$ TrigPutCounter | RememberObjects$ TriggeredCardLKICopy | TriggerDescription$ When you do, put X +1/+1 counters on that creature.
SVar:TrigPutCounter:DB$ PutCounter | Defined$ DelayTriggerRememberedLKI | CounterType$ P1P1 | CounterNum$ X
S:Mode$ Continuous | IsPresent$ Creature.modified+YouCtrl | PresentCompare$ GE5 | Affected$ Card.Self | AddPower$ 5 | AddToughness$ 5 | AddKeyword$ Trample | Description$ As long as you control five or more modified creatures, CARDNAME gets +5/+5 and has trample.
SVar:X:Count$xPaid

View File

@@ -5,7 +5,6 @@ A:SP$ Token | Cost$ X W W | TokenAmount$ X | TokenScript$ w_1_1_soldier | Rememb
SVar:CoupDestroy:DB$ DestroyAll | ValidCards$ Creature.IsNotRemembered | ConditionCheckSVar$ X | ConditionSVarCompare$ GE5 | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:X:Count$xPaid
SVar:PayX:5
SVar:NeedsToPlayVar:OwnCreats LEOppCreats
SVar:OwnCreats:Count$SumPower_Creature.YouCtrl
SVar:OppCreats:Count$SumPower_Creature.OppCtrl

View File

@@ -5,7 +5,7 @@ PT:2/2
K:Flash
K:Reach
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.nonHuman+Other+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigImmediateTrig | TriggerDescription$ Whenever another non-Human creature enters the battlefield under your control, you may pay {X}. When you do, put X +1/+1 counters on CARDNAME.
SVar:TrigImmediateTrig:AB$ ImmediateTrigger | Cost$ X | Execute$ TrigPutCounter | AILogic$ MaxX | TriggerDescription$ When you do, put X +1/+1 counters on CARDNAME.
SVar:TrigImmediateTrig:AB$ ImmediateTrigger | Cost$ X | Execute$ TrigPutCounter | TriggerDescription$ When you do, put X +1/+1 counters on CARDNAME.
SVar:X:Count$xPaid
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ X
DeckHas:Ability$Counters