* Kicker abilities - fixed that AI can't cast cards with kicker for normal cost (AI don't use kicker now);

This commit is contained in:
Oleg Agafonov 2020-01-05 01:04:35 +04:00
parent 3c9e967642
commit 2dd64cf5cd
8 changed files with 139 additions and 26 deletions

View file

@ -6,7 +6,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author noxx
*/
public class AetherFigmentTest extends CardTestPlayerBase {
@ -25,13 +24,16 @@ public class AetherFigmentTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Aether Figment");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Aether Figment");
setChoice(playerA, "Yes"); // use kicker
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertPermanentCount(playerA, "Aether Figment", 1);
assertPowerToughness(playerA, "Aether Figment", 3, 3);
assertPowerToughness(playerA, "Aether Figment", 3, 3);
}
}

View file

@ -1,4 +1,3 @@
package org.mage.test.cards.abilities.keywords;
import mage.constants.PhaseStep;
@ -7,7 +6,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author BetaSteward
*/
public class ConspireTest extends CardTestPlayerBase {
@ -32,11 +30,10 @@ public class ConspireTest extends CardTestPlayerBase {
/**
* Burn Trail Sorcery, 3R (4) Burn Trail deals 3 damage to target creature
* or player.
*
* <p>
* Conspire (As you cast this spell, you may tap two untapped creatures you
* control that share a color with it. When you do, copy it and you may
* choose a new target for the copy.)
*
*/
@Test
public void testConspire() {
@ -124,4 +121,79 @@ public class ConspireTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Burn Trail", 1);
}
@Test
public void testConspire_User() {
// Burn Trail deals 3 damage to any target.
// Conspire (As you cast this spell, you may tap two untapped creatures you control that share a color with it.
// When you do, copy it and you may choose a new target for the copy.)
addCard(Zone.HAND, playerA, "Burn Trail", 1); // {3}{R}
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
addCard(Zone.BATTLEFIELD, playerA, "Goblin Assailant", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Burn Trail");
addTarget(playerA, playerB);
setChoice(playerA, "Yes"); // use conspire
setChoice(playerA, "Goblin Assailant^Goblin Assailant");
setChoice(playerA, "No"); // don't change target 1
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Burn Trail", 1);
assertLife(playerB, 20 - 3 * 2);
assertTapped("Goblin Assailant", true);
}
@Test
public void testConspire_AI_can() {
// Burn Trail deals 3 damage to any target.
// Conspire (As you cast this spell, you may tap two untapped creatures you control that share a color with it.
// When you do, copy it and you may choose a new target for the copy.)
addCard(Zone.HAND, playerA, "Burn Trail", 1); // {3}{R}
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
addCard(Zone.BATTLEFIELD, playerA, "Goblin Assailant", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Burn Trail");
addTarget(playerA, playerB);
//setChoice(playerA, "Yes"); // use conspire - AI must choose
//setChoice(playerA, "Goblin Assailant^Goblin Assailant"); - AI must choose
//setChoice(playerA, "No"); // don't change target 1 - AI must choose
//setStrictChooseMode(true); - AI must choose
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Burn Trail", 1);
assertLife(playerB, 20 - 3 * 2);
assertTapped("Goblin Assailant", true);
}
@Test
public void testConspire_AI_cannot() {
// Burn Trail deals 3 damage to any target.
// Conspire (As you cast this spell, you may tap two untapped creatures you control that share a color with it.
// When you do, copy it and you may choose a new target for the copy.)
addCard(Zone.HAND, playerA, "Burn Trail", 1); // {3}{R}
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
addCard(Zone.BATTLEFIELD, playerA, "Goblin Assailant", 2 - 1); // AI can't pay additional cost, must use simple mode
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Burn Trail");
addTarget(playerA, playerB);
//setChoice(playerA, "Yes"); // use conspire - AI must choose
//setChoice(playerA, "Goblin Assailant^Goblin Assailant"); - AI must choose
//setChoice(playerA, "No"); // don't change target 1 - AI must choose
//setStrictChooseMode(true); - AI must choose
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Burn Trail", 1);
assertLife(playerB, 20 - 3); // simple cast
assertTapped("Goblin Assailant", false);
}
}

View file

@ -1,15 +1,14 @@
package org.mage.test.cards.abilities.keywords;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author BetaSteward
*/
public class KickerTest extends CardTestPlayerBase {
@ -48,40 +47,81 @@ public class KickerTest extends CardTestPlayerBase {
* additional {3} as you cast this spell.) Aether Figment can't be blocked.
* If Aether Figment was kicked, it enters the battlefield with two +1/+1
* counters on it.
*
*/
@Test
public void testUseKicker() {
public void testUseKicker_User() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
addCard(Zone.HAND, playerA, "Aether Figment");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Aether Figment");
setChoice(playerA, "Yes"); // with Kicker
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Aether Figment", 1);
assertCounterCount("Aether Figment", CounterType.P1P1, 2);
assertPowerToughness(playerA, "Aether Figment", 3, 3);
}
@Test
public void testDontUseKicker() {
@Ignore
// TODO: enable test after replicate ability will be supported by AI (don't forget about multikicker support too)
public void testUseKicker_AI() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
addCard(Zone.HAND, playerA, "Aether Figment");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Aether Figment");
//setChoice(playerA, "Yes"); // with Kicker - AI must choose
//setStrictChooseMode(true); - AI must choose
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Aether Figment", 1);
assertCounterCount("Aether Figment", CounterType.P1P1, 2);
assertPowerToughness(playerA, "Aether Figment", 3, 3);
}
@Test
public void testDontUseKicker_User() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
addCard(Zone.HAND, playerA, "Aether Figment");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Aether Figment");
setChoice(playerA, "No");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Aether Figment", 1);
assertCounterCount("Aether Figment", CounterType.P1P1, 0);
assertPowerToughness(playerA, "Aether Figment", 1, 1);
}
@Test
@Ignore
// TODO: enable test after replicate ability will be supported by AI (don't forget about multikicker support too)
public void testDontUseKicker_AI() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 5 - 1); // haven't all mana
addCard(Zone.HAND, playerA, "Aether Figment");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Aether Figment");
//setChoice(playerA, "No"); - AI must choose
//setStrictChooseMode(true); - AI must choose
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Aether Figment", 1);
assertCounterCount("Aether Figment", CounterType.P1P1, 0);
assertPowerToughness(playerA, "Aether Figment", 1, 1);
}
/**
@ -89,7 +129,6 @@ public class KickerTest extends CardTestPlayerBase {
* additional {1}{W} any number of times as you cast this spell.) Flying
* Apex Hawks enters the battlefield with a +1/+1 counter on it for each
* time it was kicked.
*
*/
@Test
public void testUseMultikickerOnce() {
@ -305,7 +344,6 @@ public class KickerTest extends CardTestPlayerBase {
/**
* Check that kicker condition does also work for kicker cards with multiple
* kicker options
*
*/
@Test
public void testKickerCondition() {
@ -342,7 +380,6 @@ public class KickerTest extends CardTestPlayerBase {
* Paying the Kicker on "Marsh Casualties" has no effect. Target player's
* creatures still only get -1/-1 instead of -2/-2. Was playing against AI.
* It was me who cast the spell.
*
*/
@Test
public void testMarshCasualties() {

View file

@ -21,14 +21,17 @@ public class GoblinBushwhackerTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Elite Vanguard");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Goblin Bushwhacker");
setChoice(playerA, "Yes"); // use kicker
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Elite Vanguard", 1);
assertPowerToughness(playerA, "Elite Vanguard", 3, 1);
}
/**
* Tests doesn't work in library and in hand
*/

View file

@ -6,7 +6,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author noxx
*/
public class GatekeeperOfMalakirTest extends CardTestPlayerBase {
@ -20,6 +19,7 @@ public class GatekeeperOfMalakirTest extends CardTestPlayerBase {
// Kicker {B} (You may pay an additional {B} as you cast this spell.)
// When Gatekeeper of Malakir enters the battlefield, if it was kicked, target player sacrifices a creature.
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Gatekeeper of Malakir");
setChoice(playerA, "Yes"); // use kicker
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -30,5 +30,4 @@ public class GatekeeperOfMalakirTest extends CardTestPlayerBase {
assertPermanentCount(playerB, "Llanowar Elves", 0);
assertGraveyardCount(playerB, 1);
}
}

View file

@ -1,4 +1,3 @@
package mage.abilities.keyword;
import mage.abilities.Ability;
@ -13,9 +12,12 @@ import mage.abilities.costs.common.TapTargetCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.SharesColorWithSourcePredicate;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
@ -29,9 +31,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.UUID;
import mage.constants.CardType;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
/*
* 702.77. Conspire
@ -61,7 +60,6 @@ public class ConspireAbility extends StaticAbility implements OptionalAdditional
}
public enum ConspireTargets {
NONE,
ONE,
MORE
@ -140,10 +138,11 @@ public class ConspireAbility extends StaticAbility implements OptionalAdditional
Player player = game.getPlayer(getControllerId());
if (player != null) {
resetConspire(ability, game);
// AI supports conspire
if (conspireCost.canPay(ability, getSourceId(), getControllerId(), game)
&& player.chooseUse(Outcome.Benefit, "Pay " + conspireCost.getText(false) + " ?", ability, game)) {
activateConspire(ability, game);
for (Iterator it = conspireCost.iterator(); it.hasNext();) {
for (Iterator it = conspireCost.iterator(); it.hasNext(); ) {
Cost cost = (Cost) it.next();
ability.getCosts().add(cost.copy());
}

View file

@ -181,8 +181,10 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo
int activatedCount = getKickedCounter(game, ability);
times = (activatedCount + 1) + (activatedCount == 0 ? " time " : " times ");
}
// TODO: add AI support to find max number of possible activations (from available mana)
// canPay checks only single mana available, not total mana usage
if (kickerCost.canPay(ability, sourceId, controllerId, game)
&& player.chooseUse(Outcome.Benefit, "Pay " + times + kickerCost.getText(false) + " ?", ability, game)) {
&& player.chooseUse(/*Outcome.Benefit*/Outcome.AIDontUseIt, "Pay " + times + kickerCost.getText(false) + " ?", ability, game)) {
this.activateKicker(kickerCost, ability, game);
if (kickerCost instanceof Costs) {
for (Iterator itKickerCost = ((Costs) kickerCost).iterator(); itKickerCost.hasNext(); ) {

View file

@ -89,7 +89,6 @@ public class ReplicateAbility extends StaticAbility implements OptionalAdditiona
times = (numActivations + 1) + (numActivations == 0 ? " time " : " times ");
}
// test costs
// TODO: add AI support to find max number of possible activations (from available mana)
// canPay checks only single mana available, not total mana usage
if (additionalCost.canPay(ability, sourceId, controllerId, game)