diff --git a/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java b/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java index 920146771ff..7a38e503055 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CountersPutAi.java @@ -11,6 +11,7 @@ import forge.game.GameEntity; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.card.*; +import forge.game.combat.Combat; import forge.game.combat.CombatUtil; import forge.game.cost.*; import forge.game.keyword.Keyword; @@ -43,17 +44,19 @@ public class CountersPutAi extends SpellAbilityAi { protected boolean willPayCosts(Player ai, SpellAbility sa, Cost cost, Card source) { final String type = sa.getParam("CounterType"); + final String aiLogic = sa.getParamOrDefault("AILogic", ""); + // TODO Auto-generated method stub if (!super.willPayCosts(ai, sa, cost, source)) { return false; } - // disable moving counters + // disable moving counters (unless a specialized AI logic supports it) for (final CostPart part : cost.getCostParts()) { if (part instanceof CostRemoveCounter) { final CostRemoveCounter remCounter = (CostRemoveCounter) part; final CounterType counterType = remCounter.counter; - if (counterType.name().equals(type)) { + if (counterType.name().equals(type) && !aiLogic.startsWith("MoveCounter")) { return false; } if (!part.payCostFromSource()) { @@ -279,6 +282,8 @@ public class CountersPutAi extends SpellAbilityAi { if (!source.canTransform()) { return false; } + } else if (logic.equals("MoveCounterSpike")) { + return doMoveCounterSpikeLogic(ai, sa, ph); } if (sa.getConditions() != null && !sa.getConditions().areMet(sa) && sa.getSubAbility() == null) { @@ -999,4 +1004,38 @@ public class CountersPutAi extends SpellAbilityAi { } return Iterables.getFirst(options, null); } + + private boolean doMoveCounterSpikeLogic(Player ai, SpellAbility sa, PhaseHandler ph) { + // Spikes (Tempest) + + // Try not to do it unless at the end of opponent's turn or the creature is threatened + Combat combat = ai.getGame().getCombat(); + boolean threatened = ComputerUtil.predictThreatenedObjects(ai, null, true).contains(sa.getHostCard()) + || (combat != null && combat.isBlocked(sa.getHostCard()) && ComputerUtilCombat.attackerWouldBeDestroyed(ai, sa.getHostCard(), combat)); + + if (!(threatened || (ph.is(PhaseType.END_OF_TURN) && ph.getNextTurn() == ai))) { + return false; + } + + CardCollection targets = CardLists.getTargetableCards(ai.getCreaturesInPlay(), sa); + targets.remove(sa.getHostCard()); + + targets = CardLists.filter(targets, new Predicate() { + @Override + public boolean apply(Card card) { + // when threatened, any target is good to preserve the counter + return threatened || ComputerUtilCard.evaluateCreature(card, false, false) > ComputerUtilCard.evaluateCreature(sa.getHostCard(), false, false) + 1; + } + }); + + Card bestTgt = ComputerUtilCard.getBestCreatureAI(targets); + + if (bestTgt != null) { + sa.getTargets().add(bestTgt); + return true; + } + + return false; + } + } diff --git a/forge-gui/res/cardsfolder/s/spike_breeder.txt b/forge-gui/res/cardsfolder/s/spike_breeder.txt index 68bc18a3bd2..ed8a550c3ff 100644 --- a/forge-gui/res/cardsfolder/s/spike_breeder.txt +++ b/forge-gui/res/cardsfolder/s/spike_breeder.txt @@ -3,7 +3,7 @@ ManaCost:3 G Types:Creature Spike PT:0/0 K:etbCounter:P1P1:3 -A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target creature. +A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | AILogic$ MoveCounterSpike | SpellDescription$ Put a +1/+1 counter on target creature. A:AB$ Token | Cost$ 2 SubCounter<1/P1P1> | TokenAmount$ 1 | TokenName$ Spike | TokenTypes$ Creature,Spike | TokenOwner$ You | TokenColors$ Green | TokenPower$ 1 | TokenToughness$ 1 | SpellDescription$ Create a 1/1 green Spike creature token. SVar:Picture:http://www.wizards.com/global/images/magic/general/spike_breeder.jpg Oracle:Spike Breeder enters the battlefield with three +1/+1 counters on it.\n{2}, Remove a +1/+1 counter from Spike Breeder: Put a +1/+1 counter on target creature.\n{2}, Remove a +1/+1 counter from Spike Breeder: Create a 1/1 green Spike creature token. diff --git a/forge-gui/res/cardsfolder/s/spike_colony.txt b/forge-gui/res/cardsfolder/s/spike_colony.txt index dfb1573e10f..afcd2b32c48 100644 --- a/forge-gui/res/cardsfolder/s/spike_colony.txt +++ b/forge-gui/res/cardsfolder/s/spike_colony.txt @@ -3,6 +3,6 @@ ManaCost:4 G Types:Creature Spike PT:0/0 K:etbCounter:P1P1:4 -A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target creature. +A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | AILogic$ MoveCounterSpike | SpellDescription$ Put a +1/+1 counter on target creature. SVar:Picture:http://www.wizards.com/global/images/magic/general/spike_colony.jpg Oracle:Spike Colony enters the battlefield with four +1/+1 counters on it.\n{2}, Remove a +1/+1 counter from Spike Colony: Put a +1/+1 counter on target creature. diff --git a/forge-gui/res/cardsfolder/s/spike_drone.txt b/forge-gui/res/cardsfolder/s/spike_drone.txt index 3e06e6ca6f4..511c6892116 100644 --- a/forge-gui/res/cardsfolder/s/spike_drone.txt +++ b/forge-gui/res/cardsfolder/s/spike_drone.txt @@ -3,6 +3,6 @@ ManaCost:G Types:Creature Spike Drone PT:0/0 K:etbCounter:P1P1:1 -A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target creature. +A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | AILogic$ MoveCounterSpike | SpellDescription$ Put a +1/+1 counter on target creature. SVar:Picture:http://www.wizards.com/global/images/magic/general/spike_drone.jpg Oracle:Spike Drone enters the battlefield with a +1/+1 counter on it.\n{2}, Remove a +1/+1 counter from Spike Drone: Put a +1/+1 counter on target creature. diff --git a/forge-gui/res/cardsfolder/s/spike_feeder.txt b/forge-gui/res/cardsfolder/s/spike_feeder.txt index 9eb9c25d30f..5cfd12ab571 100644 --- a/forge-gui/res/cardsfolder/s/spike_feeder.txt +++ b/forge-gui/res/cardsfolder/s/spike_feeder.txt @@ -3,7 +3,7 @@ ManaCost:1 G G Types:Creature Spike PT:0/0 K:etbCounter:P1P1:2 -A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target creature. +A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | AILogic$ MoveCounterSpike | SpellDescription$ Put a +1/+1 counter on target creature. A:AB$ GainLife | Cost$ SubCounter<1/P1P1> | LifeAmount$ 2 | SpellDescription$ You gain 2 life. SVar:Picture:http://www.wizards.com/global/images/magic/general/spike_feeder.jpg Oracle:Spike Feeder enters the battlefield with two +1/+1 counters on it.\n{2}, Remove a +1/+1 counter from Spike Feeder: Put a +1/+1 counter on target creature.\nRemove a +1/+1 counter from Spike Feeder: You gain 2 life. diff --git a/forge-gui/res/cardsfolder/s/spike_hatcher.txt b/forge-gui/res/cardsfolder/s/spike_hatcher.txt index 3c17a232f4e..a5ecaa56a45 100644 --- a/forge-gui/res/cardsfolder/s/spike_hatcher.txt +++ b/forge-gui/res/cardsfolder/s/spike_hatcher.txt @@ -3,7 +3,7 @@ ManaCost:6 G Types:Creature Spike PT:0/0 K:etbCounter:P1P1:6 -A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target creature. +A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | AILogic$ MoveCounterSpike | SpellDescription$ Put a +1/+1 counter on target creature. A:AB$ Regenerate | Cost$ 1 SubCounter<1/P1P1> | SpellDescription$ Regenerate Spike Hatcher. SVar:Picture:http://www.wizards.com/global/images/magic/general/spike_hatcher.jpg Oracle:Spike Hatcher enters the battlefield with six +1/+1 counters on it.\n{2}, Remove a +1/+1 counter from Spike Hatcher: Put a +1/+1 counter on target creature.\n{1}, Remove a +1/+1 counter from Spike Hatcher: Regenerate Spike Hatcher. diff --git a/forge-gui/res/cardsfolder/s/spike_rogue.txt b/forge-gui/res/cardsfolder/s/spike_rogue.txt index 26e18ab754b..2c79de74c9a 100644 --- a/forge-gui/res/cardsfolder/s/spike_rogue.txt +++ b/forge-gui/res/cardsfolder/s/spike_rogue.txt @@ -3,7 +3,7 @@ ManaCost:1 G G Types:Creature Spike PT:0/0 K:etbCounter:P1P1:2 -A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target creature. +A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | AILogic$ MoveCounterSpike | SpellDescription$ Put a +1/+1 counter on target creature. A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1/Creature.YouCtrl/Creature you Control> | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on CARDNAME. AI:RemoveDeck:All SVar:Picture:http://www.wizards.com/global/images/magic/general/spike_rogue.jpg diff --git a/forge-gui/res/cardsfolder/s/spike_soldier.txt b/forge-gui/res/cardsfolder/s/spike_soldier.txt index d57c54688eb..20454d45538 100644 --- a/forge-gui/res/cardsfolder/s/spike_soldier.txt +++ b/forge-gui/res/cardsfolder/s/spike_soldier.txt @@ -3,7 +3,7 @@ ManaCost:2 G G Types:Creature Spike Soldier PT:0/0 K:etbCounter:P1P1:3 -A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target creature. +A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | AILogic$ MoveCounterSpike | SpellDescription$ Put a +1/+1 counter on target creature. A:AB$ Pump | Cost$ SubCounter<1/P1P1> | Defined$ Self | NumAtt$ 2 | NumDef$ 2 | SpellDescription$ CARDNAME gets +2/+2 until end of turn. SVar:Picture:http://www.wizards.com/global/images/magic/general/spike_soldier.jpg Oracle:Spike Soldier enters the battlefield with three +1/+1 counters on it.\n{2}, Remove a +1/+1 counter from Spike Soldier: Put a +1/+1 counter on target creature.\nRemove a +1/+1 counter from Spike Soldier: Spike Soldier gets +2/+2 until end of turn. diff --git a/forge-gui/res/cardsfolder/s/spike_tiller.txt b/forge-gui/res/cardsfolder/s/spike_tiller.txt index d8544eb7173..eeecb2191da 100644 --- a/forge-gui/res/cardsfolder/s/spike_tiller.txt +++ b/forge-gui/res/cardsfolder/s/spike_tiller.txt @@ -3,7 +3,7 @@ ManaCost:3 G G Types:Creature Spike PT:0/0 K:etbCounter:P1P1:3 -A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target creature. +A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | AILogic$ MoveCounterSpike | SpellDescription$ Put a +1/+1 counter on target creature. A:AB$ Animate | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Land | TgtPrompt$ Choose target land. | Power$ 2 | Toughness$ 2 | Types$ Creature | Permanent$ True | SubAbility$ DBPutCounter | SpellDescription$ Target land becomes a 2/2 creature that's still a land. Put a +1/+1 counter on it. SVar:DBPutCounter:DB$PutCounter | Defined$ Targeted | CounterType$ P1P1 | CounterNum$ 1 SVar:Picture:http://www.wizards.com/global/images/magic/general/spike_tiller.jpg diff --git a/forge-gui/res/cardsfolder/s/spike_weaver.txt b/forge-gui/res/cardsfolder/s/spike_weaver.txt index 5937873b693..788f373bdc5 100644 --- a/forge-gui/res/cardsfolder/s/spike_weaver.txt +++ b/forge-gui/res/cardsfolder/s/spike_weaver.txt @@ -3,7 +3,7 @@ ManaCost:2 G G Types:Creature Spike PT:0/0 K:etbCounter:P1P1:3 -A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target creature. +A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | AILogic$ MoveCounterSpike | SpellDescription$ Put a +1/+1 counter on target creature. A:AB$ Fog | Cost$ 1 SubCounter<1/P1P1> | AILogic$ SeriousDamage | SpellDescription$ Prevent all combat damage that would be dealt this turn. SVar:Picture:http://www.wizards.com/global/images/magic/general/spike_weaver.jpg Oracle:Spike Weaver enters the battlefield with three +1/+1 counters on it.\n{2}, Remove a +1/+1 counter from Spike Weaver: Put a +1/+1 counter on target creature.\n{1}, Remove a +1/+1 counter from Spike Weaver: Prevent all combat damage that would be dealt this turn. diff --git a/forge-gui/res/cardsfolder/s/spike_worker.txt b/forge-gui/res/cardsfolder/s/spike_worker.txt index 70223734d96..1fba05ca944 100644 --- a/forge-gui/res/cardsfolder/s/spike_worker.txt +++ b/forge-gui/res/cardsfolder/s/spike_worker.txt @@ -3,6 +3,6 @@ ManaCost:2 G Types:Creature Spike PT:0/0 K:etbCounter:P1P1:2 -A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target creature. +A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | AILogic$ MoveCounterSpike | SpellDescription$ Put a +1/+1 counter on target creature. SVar:Picture:http://www.wizards.com/global/images/magic/general/spike_worker.jpg Oracle:Spike Worker enters the battlefield with two +1/+1 counters on it.\n{2}, Remove a +1/+1 counter from Spike Worker: Put a +1/+1 counter on target creature.