mirror of
https://github.com/correl/mage.git
synced 2025-03-07 20:53:18 -10:00
Fixed and improved tests for latest changes like asThough and adventure cards;
This commit is contained in:
parent
b3e17ba85f
commit
732a48e936
10 changed files with 113 additions and 37 deletions
|
@ -73,6 +73,7 @@ class ViviensInvocationEffect extends OneShotEffect {
|
|||
Zone.LIBRARY,
|
||||
new FilterCreatureCard("creature card to put on the battlefield")
|
||||
);
|
||||
target.setNotTarget(true);
|
||||
if (controller.choose(Outcome.PutCreatureInPlay, cards, target, game)) {
|
||||
Card card = cards.get(target.getFirstTarget(), game);
|
||||
if (card != null) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package org.mage.test.AI.basic;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
|
@ -8,7 +7,6 @@ import org.junit.Test;
|
|||
import org.mage.test.serverside.base.CardTestPlayerBaseAI;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class CastCreaturesTest extends CardTestPlayerBaseAI {
|
||||
|
@ -173,7 +171,7 @@ public class CastCreaturesTest extends CardTestPlayerBaseAI {
|
|||
|
||||
/**
|
||||
* Tests that the creature is cast if enough mana is available.
|
||||
*
|
||||
* <p>
|
||||
* Once Ammit Eternal is cast against a computer AI opponent, the AI just
|
||||
* decides to sit there and only play basic lands. I've sat there and decked
|
||||
* it because it just plays lands. It's like it views giving the Ammit
|
||||
|
@ -194,8 +192,11 @@ public class CastCreaturesTest extends CardTestPlayerBaseAI {
|
|||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 3);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Ammit Eternal");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(3, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertPermanentCount(playerB, "Ammit Eternal", 1);
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package org.mage.test.cards.abilities.activated;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
|
@ -7,7 +6,6 @@ import org.junit.Test;
|
|||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class LightningStormTest extends CardTestPlayerBase {
|
||||
|
@ -16,10 +14,9 @@ public class LightningStormTest extends CardTestPlayerBase {
|
|||
* So, this just happened to me. My opponent cast Lightning Storm and while
|
||||
* it was on the stack I couldn't use the ability despite having land in
|
||||
* hand which isn't something I've had an issue with before.
|
||||
*
|
||||
* <p>
|
||||
* My opponent had a Leyline of Sanctity in play, so perhaps that was
|
||||
* causing the issue somehow? Does anyone want to try and replicate it?
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void ActivateByBothPlayersTest() {
|
||||
|
@ -31,22 +28,32 @@ public class LightningStormTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerA, "Mountain");
|
||||
addCard(Zone.HAND, playerB, "Mountain");
|
||||
|
||||
// A activate
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Storm", playerB);
|
||||
|
||||
// B discard and re-target
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Discard");
|
||||
setChoice(playerB, "playerA");
|
||||
setChoice(playerB, "Mountain");
|
||||
setChoice(playerB, "Yes");
|
||||
addTarget(playerB, playerA);
|
||||
|
||||
// A discard and re-target
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Discard");
|
||||
setChoice(playerA, "playerB");
|
||||
setChoice(playerA, "Mountain");
|
||||
setChoice(playerA, "Yes");
|
||||
addTarget(playerA, playerB);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertGraveyardCount(playerA, "Lightning Storm", 1);
|
||||
assertGraveyardCount(playerB, "Mountain", 1);
|
||||
assertGraveyardCount(playerA, "Mountain", 1);
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 13);
|
||||
assertLife(playerB, 20 - 3 - 2 - 2);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package org.mage.test.cards.asthough;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
|
@ -7,7 +6,6 @@ import org.junit.Test;
|
|||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class SpendOtherManaTest extends CardTestPlayerBase {
|
||||
|
@ -47,7 +45,7 @@ public class SpendOtherManaTest extends CardTestPlayerBase {
|
|||
/**
|
||||
* Tron mana doesn't work with Oath of Nissa. (e.g. can't cast Chandra,
|
||||
* Flamecaller with Urza's Tower, Power Plant, and Mine.)
|
||||
*
|
||||
* <p>
|
||||
* AI don't get the Planeswalker as playable card (probably because of the
|
||||
* as thought effect)
|
||||
*/
|
||||
|
@ -76,7 +74,7 @@ public class SpendOtherManaTest extends CardTestPlayerBase {
|
|||
* I was unable to cast Nissa, Voice of Zendikar using black mana with Oath
|
||||
* of Nissa in play. Pretty sure Oath is working usually, so here were the
|
||||
* conditions in my game:
|
||||
*
|
||||
* <p>
|
||||
* -Cast Dark Petition with spell mastery -Attempt to cast Nissa, Voice of
|
||||
* Zendikar using the triple black mana from Dark Petition
|
||||
*/
|
||||
|
@ -122,20 +120,84 @@ public class SpendOtherManaTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerA, "Hostage Taker"); // {2}{U}{B}
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Hostage Taker");
|
||||
setChoice(playerA, "Silvercoat Lion");
|
||||
addTarget(playerA, "Silvercoat Lion");
|
||||
|
||||
// red mana must be used as any mana
|
||||
activateManaAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Add {R}."); // red mana to pool
|
||||
activateManaAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Add {R}."); // red mana to pool
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Silvercoat Lion"); // cast it from exile with red mana from pool
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertPermanentCount(playerA, "Hostage Taker", 1);
|
||||
assertTappedCount("Mountain", true, 4);
|
||||
|
||||
assertPermanentCount(playerA, "Silvercoat Lion", 1);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_QuicksilverElemental_Normal() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
|
||||
|
||||
// {U}: Quicksilver Elemental gains all activated abilities of target creature until end of turn.
|
||||
// You may spend blue mana as though it were mana of any color to pay the activation costs of Quicksilver Elemental’s abilities.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Quicksilver Elemental"); // Creature {1}{W}
|
||||
// {R}, {T}: Anaba Shaman deals 1 damage to any target.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Anaba Shaman");
|
||||
|
||||
// gain abilities
|
||||
checkPlayableAbility("must not have", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}, {T}:", false);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}:", "Anaba Shaman");
|
||||
|
||||
// use ability
|
||||
checkPlayableAbility("must have new ability", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{R}, {T}:", true);
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{R}, {T}:", playerB);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20 - 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_QuicksilverElemental_Flicker() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
|
||||
|
||||
// {U}: Quicksilver Elemental gains all activated abilities of target creature until end of turn.
|
||||
// You may spend blue mana as though it were mana of any color to pay the activation costs of Quicksilver Elemental’s abilities.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Quicksilver Elemental"); // Creature {1}{W}
|
||||
// {R}, {T}: Anaba Shaman deals 1 damage to any target.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Anaba Shaman");
|
||||
// Exile target nontoken permanent, then return it to the battlefield under its owner’s control.
|
||||
addCard(Zone.HAND, playerA, "Flicker"); // {1}{W}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||
|
||||
// gain abilities
|
||||
checkPlayableAbility("must not have", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}, {T}:", false);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}:", "Anaba Shaman");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
checkPlayableAbility("must have new ability", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}, {T}:", true);
|
||||
|
||||
// renew target
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flicker", "Anaba Shaman");
|
||||
|
||||
// use ability
|
||||
checkPlayableAbility("must save ability", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{R}, {T}:", true);
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{R}, {T}:", playerB);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertGraveyardCount(playerA, "Flicker", 1);
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20 - 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import mage.constants.Zone;
|
|||
import mage.counters.CounterType;
|
||||
import mage.game.permanent.Permanent;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
@ -282,7 +281,8 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerB, "Curious Pair");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Psychic Intrusion", playerB);
|
||||
playerA.addChoice("Curious Pair");
|
||||
setChoice(playerA, "Curious Pair");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
||||
|
||||
|
@ -462,6 +462,7 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
|||
removeAllCardsFromLibrary(playerA);
|
||||
addCard(Zone.LIBRARY, playerA, "Curious Pair");
|
||||
|
||||
showAvaileableAbilities("abils", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
|
@ -473,7 +474,7 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Not yet working correctly.")
|
||||
//@Ignore("Not yet working correctly.")
|
||||
public void testCastTreatsToShareWithWrennAndSixEmblem() {
|
||||
/*
|
||||
* Wrenn and Six {R}{G}
|
||||
|
@ -487,11 +488,16 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Wrenn and Six");
|
||||
addCard(Zone.GRAVEYARD, playerA, "Curious Pair");
|
||||
addCard(Zone.HAND, playerA, "Forest");
|
||||
addCard(Zone.HAND, playerA, "Forest"); // pay for retrace
|
||||
|
||||
addCounters(1, PhaseStep.UPKEEP, playerA, "Wrenn and Six", CounterType.LOYALTY, 5);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-7: You get an emblem");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
showAvaileableAbilities("abils", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
|
||||
// retrace - You may cast this card from your graveyard by discarding a land card as an additional cost to cast it
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||
setChoice(playerA, "Forest");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
@ -523,6 +529,8 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerA, "Curious Pair");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Until your next");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
showAvaileableAbilities("abils", 1, PhaseStep.BEGIN_COMBAT, playerA);
|
||||
castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Treats to Share");
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
|
|
|
@ -6,7 +6,6 @@ import org.junit.Test;
|
|||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* also tests regenerate and tests that permanents with protection can be
|
||||
* sacrificed
|
||||
*
|
||||
|
@ -46,10 +45,13 @@ public class FiendOfTheShadowsTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerB, "Swamp");
|
||||
|
||||
attack(1, playerA, "Fiend of the Shadows");
|
||||
addTarget(playerB, "Swamp");
|
||||
playLand(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Swamp");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 17);
|
||||
|
|
|
@ -51,7 +51,7 @@ public class ExileAdventureSpellEffect extends OneShotEffect implements MageSing
|
|||
Spell spell = game.getStack().getSpell(source.getId());
|
||||
if (spell != null && !spell.isCopy()) {
|
||||
Card spellCard = spell.getCard();
|
||||
if (spellCard != null && spellCard instanceof AdventureCardSpell) {
|
||||
if (spellCard instanceof AdventureCardSpell) {
|
||||
UUID exileId = adventureExileId(controller.getId(), game);
|
||||
game.getExile().createZone(exileId, "On an Adventure");
|
||||
AdventureCardSpell adventureSpellCard = (AdventureCardSpell) spellCard;
|
||||
|
|
|
@ -100,6 +100,7 @@ class HideawayExileEffect extends OneShotEffect {
|
|||
cards.addAll(controller.getLibrary().getTopCards(game, 4));
|
||||
if (!cards.isEmpty()) {
|
||||
TargetCard target1 = new TargetCard(Zone.LIBRARY, filter1);
|
||||
target1.setNotTarget(true);
|
||||
if (controller.choose(Outcome.Detriment, cards, target1, game)) {
|
||||
Card card = cards.get(target1.getFirstTarget(), game);
|
||||
if (card != null) {
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import java.util.Iterator;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.StaticAbility;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.Costs;
|
||||
import mage.abilities.costs.OptionalAdditionalCost;
|
||||
import mage.abilities.costs.OptionalAdditionalCostImpl;
|
||||
import mage.abilities.costs.OptionalAdditionalSourceCosts;
|
||||
import mage.abilities.costs.*;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
|
@ -23,8 +17,9 @@ import mage.game.stack.Spell;
|
|||
import mage.game.stack.StackObject;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class ReplicateAbility extends StaticAbility implements OptionalAdditionalSourceCosts {
|
||||
|
@ -91,12 +86,12 @@ public class ReplicateAbility extends StaticAbility implements OptionalAdditiona
|
|||
String times = "";
|
||||
if (additionalCost.isRepeatable()) {
|
||||
int numActivations = additionalCost.getActivateCount();
|
||||
times = Integer.toString(numActivations + 1) + (numActivations == 0 ? " time " : " times ");
|
||||
times = (numActivations + 1) + (numActivations == 0 ? " time " : " times ");
|
||||
}
|
||||
if (additionalCost.canPay(ability, sourceId, controllerId, game)
|
||||
&& player.chooseUse(Outcome.Benefit, new StringBuilder("Pay ").append(times).append(additionalCost.getText(false)).append(" ?").toString(), ability, game)) {
|
||||
additionalCost.activate();
|
||||
for (Iterator it = ((Costs) additionalCost).iterator(); it.hasNext();) {
|
||||
for (Iterator it = ((Costs) additionalCost).iterator(); it.hasNext(); ) {
|
||||
Cost cost = (Cost) it.next();
|
||||
if (cost instanceof ManaCostsImpl) {
|
||||
ability.getManaCostsToPay().add((ManaCostsImpl) cost.copy());
|
||||
|
@ -170,7 +165,7 @@ class ReplicateTriggeredAbility extends TriggeredAbilityImpl {
|
|||
if (card != null) {
|
||||
for (Ability ability : card.getAbilities(game)) {
|
||||
if (ability instanceof ReplicateAbility) {
|
||||
if (((ReplicateAbility) ability).isActivated()) {
|
||||
if (ability.isActivated()) {
|
||||
for (Effect effect : this.getEffects()) {
|
||||
effect.setValue("ReplicateSpell", spell);
|
||||
effect.setValue("ReplicateCount", ((ReplicateAbility) ability).getActivateCount());
|
||||
|
@ -213,7 +208,7 @@ class ReplicateCopyEffect extends OneShotEffect {
|
|||
if (card != null) {
|
||||
for (Ability ability : card.getAbilities(game)) {
|
||||
if (ability instanceof ReplicateAbility) {
|
||||
if (((ReplicateAbility) ability).isActivated()) {
|
||||
if (ability.isActivated()) {
|
||||
((ReplicateAbility) ability).resetReplicate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.util.List;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author phulin
|
||||
*/
|
||||
public class AdventureCardSpellImpl extends CardImpl implements AdventureCardSpell {
|
||||
|
@ -112,7 +111,7 @@ class AdventureCardSpellAbility extends SpellAbility {
|
|||
public ActivationStatus canActivate(UUID playerId, Game game) {
|
||||
ExileZone adventureExileZone = game.getExile().getExileZone(ExileAdventureSpellEffect.adventureExileId(playerId, game));
|
||||
Card spellCard = game.getCard(this.getSourceId());
|
||||
if (spellCard != null && spellCard instanceof AdventureCardSpell) {
|
||||
if (spellCard instanceof AdventureCardSpell) {
|
||||
Card card = ((AdventureCardSpell) spellCard).getParentCard();
|
||||
if (adventureExileZone != null && adventureExileZone.contains(card.getId())) {
|
||||
return ActivationStatus.getFalse();
|
||||
|
|
Loading…
Add table
Reference in a new issue