update exile zone for CraftAbility to share between card sides

* updated and added test coverage for previously converted cards Altar of the Wretched and Eye of Ojer Taq
This commit is contained in:
jmlundeen 2025-12-04 09:36:26 -06:00
parent ae97f8944d
commit 99bb467bdc
5 changed files with 216 additions and 42 deletions

View file

@ -0,0 +1,72 @@
package org.mage.test.cards.single.lcc;
import mage.abilities.Ability;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author Jmlundeen
*/
public class AltarOfTheWretchedTest extends CardTestPlayerBase {
/*
Altar of the Wretched
{2}{B}
Artifact
When Altar of the Wretched enters the battlefield, you may sacrifice a nontoken creature. If you do, draw X cards, then mill X cards, where X is that creature's power.
Craft with one or more creatures {2}{B}{B}
{2}{B}: Return Altar of the Wretched from your graveyard to your hand.
Wretched Bonemass
Color Indicator: Black
Creature Skeleton Horror
Wretched Bonemasss power and toughness are each equal to the total power of the exiled cards used to craft it.
This creature has flying as long as an exiled card used to craft it has flying. The same is true for first strike, double strike, deathtouch, haste, hexproof, indestructible, lifelink, menace, protection, reach, trample, and vigilance.
0/0
*/
private static final String altarOfTheWretched = "Altar of the Wretched";
private static final String wretchedBoneMass = "Wretched Bonemass";
/*
Angel of Invention
{3}{W}{W}
Creature - Angel
Flying, vigilance, lifelink
Fabricate 2
Other creatures you control get +1/+1.
2/1
*/
private static final String angelOfInvention = "Angel of Invention";
@Test
public void testAltarOfTheWretched() {
addCard(Zone.BATTLEFIELD, playerA, altarOfTheWretched);
addCard(Zone.BATTLEFIELD, playerA, angelOfInvention);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Craft with one or more");
addTarget(playerA, angelOfInvention);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute();
assertPowerToughness(playerA, wretchedBoneMass, 2, 2);
assertExileCount(playerA, angelOfInvention, 1);
List<Ability> abilities = new ArrayList<>();
abilities.add(FlyingAbility.getInstance());
abilities.add(VigilanceAbility.getInstance());
abilities.add(LifelinkAbility.getInstance());
assertAbilities(playerA, wretchedBoneMass, abilities);
}
}

View file

@ -0,0 +1,86 @@
package org.mage.test.cards.single.lcc;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author Jmlundeen
*/
public class EyeOfOjerTaqTest extends CardTestPlayerBase {
/*
Eye of Ojer Taq
{3}
Artifact
{T}: Add one mana of any color.
Craft with two that share a card type {6}
Apex Observatory
Artifact
Apex Observatory enters the battlefield tapped. As it enters, choose a card type shared among two exiled cards used to craft it.
{T}: The next spell you cast this turn of the chosen type can be cast without paying its mana cost.
*/
private static final String eyeOfOjerTaq = "Eye of Ojer Taq";
private static final String apexObservatory = "Apex Observatory";
/*
Lightning Bolt
{R}
Instant
Lightning Bolt deals 3 damage to any target.
*/
private static final String lightningBolt = "Lightning Bolt";
/*
Ponder
{U}
Sorcery
Look at the top three cards of your library, then put them back in any order. You may shuffle your library.
Draw a card.
*/
private static final String ponder = "Ponder";
/*
Shock
{R}
Instant
Shock deals 2 damage to any target.
*/
private static final String shock = "Shock";
@Test
public void testEyeOfOjerTaq() {
addCard(Zone.BATTLEFIELD, playerA, eyeOfOjerTaq);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 6);
addCard(Zone.GRAVEYARD, playerA, lightningBolt);
addCard(Zone.GRAVEYARD, playerA, shock);
addCard(Zone.HAND, playerA, shock, 2);
addCard(Zone.HAND, playerA, ponder);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Craft with two that share a card type");
addTarget(playerA, lightningBolt + "^" + shock);
setChoice(playerA, "Instant");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: The next spell");
waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN, playerA);
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, shock, playerB); // should be able to cast for free
setChoice(playerA, "Cast without paying");
checkPlayableAbility("Can't cast second shock", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Shock", false);
checkPlayableAbility("Can't cast ponder", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Cast Ponder", false);
setStrictChooseMode(true);
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerB, 20 - 2); // took 2 damage from shock
assertExileCount(playerA, lightningBolt, 1);
assertExileCount(playerA, shock, 1);
assertGraveyardCount(playerA, shock, 1);
assertPermanentCount(playerA, apexObservatory, 1);
}
}