tests: added additional use cases for Connive ability (related to #9101, #9100)

This commit is contained in:
Oleg Agafonov 2024-10-13 11:34:39 +04:00
parent 1bebc62902
commit ccb1a0aeed
3 changed files with 181 additions and 16 deletions

View file

@ -69,7 +69,7 @@ class ChangeOfPlansEffect extends OneShotEffect {
.getTargetPointer()
.getTargets(game, source)
.stream()
.map(game::getPermanent)
.map(game::getPermanentOrLKIBattlefield)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
if (permanents.isEmpty()) {

View file

@ -39,6 +39,7 @@ public final class SpymastersVault extends CardImpl {
// {T}: Add {B}.
this.addAbility(new BlackManaAbility());
// {B}, {T}: Target creature you control connives X, where X is the number of creatures that died this turn.
Ability ability = new SimpleActivatedAbility(new SpymastersVaultEffect(), new ManaCostsImpl<>("{B}"));
ability.addCost(new TapSourceCost());
@ -80,7 +81,7 @@ class SpymastersVaultEffect extends OneShotEffect {
if (deaths < 1) {
return false;
}
Permanent permanent = game.getPermanent(source.getFirstTarget());
Permanent permanent = game.getPermanentOrLKIBattlefield(source.getFirstTarget());
if (permanent == null) {
return false;
}

View file

@ -3,11 +3,23 @@ package org.mage.test.cards.abilities.keywords;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author Alex-Vasile
* To have a creature connive, draw a card, then discard a card. If you discarded a nonland card, put a +1/+1 counter on that creature.
* @author Alex-Vasile, JayDi85
* <p>
* Once an ability that causes a creature to connive begins to resolve, no player may take any other actions until it's done. Notably, opponents can't try to remove the conniving creature after you discard cards but before it receives +1/+1 counters, if any.
* (2024-06-07)
* <p>
* To have a creature connive, draw a card, then discard a card. If you discarded a nonland card,
* put a +1/+1 counter on that creature.
* <p>
* If no cards are discarded, most likely because that player's hand is empty and an effect says they can't draw cards, the conniving creature does not receive any +1/+1 counters.
* (2024-06-07)
* <p>
* If a resolving spell or ability instructs a specific creature to connive but that creature has left the battlefield, the creature still connives, although you can't put any +1/+1 counters on it. Abilities that trigger "when [that creature] connives" will trigger.
* (2024-06-07)
*/
public class ConniveTest extends CardTestPlayerBase {
@ -16,7 +28,7 @@ public class ConniveTest extends CardTestPlayerBase {
* Creature should not get a +1/+1 counter.
*/
@Test
public void conniveDiscardLand() {
public void test_OnLandDiscard() {
// P/T : 1/2
// {3}: Hypnotic Grifter connives
addCard(Zone.BATTLEFIELD, playerA, "Hypnotic Grifter");
@ -41,7 +53,7 @@ public class ConniveTest extends CardTestPlayerBase {
* Creature should get a +1/+1 counter.
*/
@Test
public void conniveDiscardCreature() {
public void test_OnCreatureDiscard() {
// P/T : 1/2
// {3}: Hypnotic Grifter connives
addCard(Zone.BATTLEFIELD, playerA, "Hypnotic Grifter");
@ -66,7 +78,7 @@ public class ConniveTest extends CardTestPlayerBase {
* Creature should get a +1/+1 counter and the madness card gets played.
*/
@Test
public void conniveMadness() {
public void test_Madness() {
// P/T : 1/2
// {3}: Hypnotic Grifter connives
addCard(Zone.BATTLEFIELD, playerA, "Hypnotic Grifter");
@ -95,10 +107,10 @@ public class ConniveTest extends CardTestPlayerBase {
/**
* Obscura Confluence allows you to connive a creature you don't control.
* It's the only card that causes you to coonnive a creature you don't control.
* It's the only card that causes you to connive a creature you don't control.
*/
@Test
public void conniveNonControlledCreature() {
public void test_OpponentCreature() {
// Choose three. You may choose the same mode more than once.
// Until end of turn, target creature loses all abilities and has base power and toughness 1/1.
// Target creature connives. (Draw a card, then discard a card. If you discarded a nonland card, put a +1/+1 counter on that creature.)
@ -135,16 +147,16 @@ public class ConniveTest extends CardTestPlayerBase {
/**
* Reported bug: https://github.com/magefree/mage/issues/9252
* Connive fizzles if the creature that connived leaves the battlefield before connive resolves.
*
* <p>
* Ruling:
* If a resolving spell or ability instructs a specific creature to connive but that creature has left the battlefield,
* the creature still connives.
* If you discard a nonland card this way, you wont put a +1/+1 counter on anything.
* Abilities that trigger when [that creature] connives will trigger.
* (2022-04-29)
* If a resolving spell or ability instructs a specific creature to connive but that creature has left the battlefield,
* the creature still connives.
* If you discard a nonland card this way, you wont put a +1/+1 counter on anything.
* Abilities that trigger when [that creature] connives will trigger.
* (2022-04-29)
*/
@Test
public void conniveDoesNotFizzle() {
public void test_LKI_PsychicPickpocket() {
// {4}{U}
// 3/2
// When Psychic Pickpocket enters the battlefield, it connives.
@ -175,4 +187,156 @@ public class ConniveTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Psychic Pickpocket", 1); // Destroyed by Lightning Bolt
assertGraveyardCount(playerB, "Lightning Bolt", 1);
}
@Test
public void test_LKI_Source_Normal() {
// When Raffines Silencer enters, it connives.
addCard(Zone.HAND, playerA, "Raffine's Silencer");// {2}{B}
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
addCard(Zone.HAND, playerA, "Grizzly Bears", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Raffine's Silencer");
setChoice(playerA, "Grizzly Bears"); // to discard
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertPowerToughness(playerA, "Raffine's Silencer", 1 + 1, 1 + 1);
assertGraveyardCount(playerA, "Grizzly Bears", 1);
}
@Test
public void test_LKI_Source_Dies() {
// When Raffines Silencer enters, it connives.
addCard(Zone.HAND, playerA, "Raffine's Silencer");// {2}{B}
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
addCard(Zone.HAND, playerA, "Grizzly Bears", 1);
//
addCard(Zone.HAND, playerA, "Lightning Bolt", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
// cast and kill raffine before cannive resolve
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {B}", 3);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Raffine's Silencer");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1); // resolve raffine
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt");
addTarget(playerA, "Raffine's Silencer"); // to kill
setChoice(playerA, "Grizzly Bears"); // to discard
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertGraveyardCount(playerA, "Raffine's Silencer", 1);
assertGraveyardCount(playerA, "Grizzly Bears", 1);
}
@Test
public void test_LKI_SpymastersVault_Normal() {
// {B}, {T}: Target creature you control connives X, where X is the number of creatures that died this turn.
addCard(Zone.BATTLEFIELD, playerA, "Spymaster's Vault");
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
addCard(Zone.HAND, playerA, "Grizzly Bears", 1);
//
addCustomEffect_DestroyTarget(playerA);
addCard(Zone.BATTLEFIELD, playerA, "Razorclaw Bear", 1);
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
// prepare X = 1 from died amount
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "target destroy", "Razorclaw Bear");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
checkGraveyardCount("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Razorclaw Bear", 1);
// cannive lion
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{B}, {T}: Target creature", "Silvercoat Lion");
setChoice(playerA, "Grizzly Bears"); // to discard
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertPowerToughness(playerA, "Silvercoat Lion", 2 + 1, 2 + 1);
assertGraveyardCount(playerA, "Grizzly Bears", 1);
}
@Test
public void test_LKI_SpymastersVault_Fizzle() {
// {B}, {T}: Target creature you control connives X, where X is the number of creatures that died this turn.
addCard(Zone.BATTLEFIELD, playerA, "Spymaster's Vault");
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
addCard(Zone.HAND, playerA, "Grizzly Bears", 1);
//
addCustomEffect_DestroyTarget(playerA);
addCard(Zone.BATTLEFIELD, playerA, "Razorclaw Bear", 1);
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
// prepare X = 1 from died amount
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "target destroy", "Razorclaw Bear");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
checkGraveyardCount("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Razorclaw Bear", 1);
// cannive lion
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{B}, {T}: Target creature", "Silvercoat Lion");
// destroy lion before cannive
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "target destroy", "Silvercoat Lion");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
// no connive due invalid target (ability fizzled)
assertGraveyardCount(playerA, "Silvercoat Lion", 1);
assertGraveyardCount(playerA, "Grizzly Bears", 0);
}
@Test
public void test_LKI_ChangeOfPlans_Normal() {
// Each of X target creatures you control connive. You may have any number of them phase out.
addCard(Zone.HAND, playerA, "Change of Plans"); // {X}{1}{U}
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
addCard(Zone.HAND, playerA, "Grizzly Bears", 1);
//
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
// connive lion
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Change of Plans");
setChoice(playerA, "X=1");
addTarget(playerA, "Silvercoat Lion");
setChoice(playerA, "Grizzly Bears"); // to discard
setChoice(playerA, TestPlayer.CHOICE_SKIP); // no phase out
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertPowerToughness(playerA, "Silvercoat Lion", 2 + 1, 2 + 1);
assertGraveyardCount(playerA, "Grizzly Bears", 1);
}
@Test
public void test_LKI_ChangeOfPlans_Fizzle() {
// Each of X target creatures you control connive. You may have any number of them phase out.
addCard(Zone.HAND, playerA, "Change of Plans"); // {X}{1}{U}
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
addCard(Zone.HAND, playerA, "Grizzly Bears", 1);
//
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
//
addCustomEffect_DestroyTarget(playerA);
// connive lion
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Change of Plans");
setChoice(playerA, "X=1");
addTarget(playerA, "Silvercoat Lion");
// destroy lion before connive resolve
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "target destroy", "Silvercoat Lion");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
// no connive due invalid target (ability fizzled)
assertGraveyardCount(playerA, "Silvercoat Lion", 1);
}
}