From 732a48e93696fef9d12c68ba6e832769ba50aab0 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sat, 14 Dec 2019 19:13:12 +0400 Subject: [PATCH] Fixed and improved tests for latest changes like asThough and adventure cards; --- .../src/mage/cards/v/ViviensInvocation.java | 1 + .../mage/test/AI/basic/CastCreaturesTest.java | 7 +- .../activated/LightningStormTest.java | 23 ++++-- .../cards/asthough/SpendOtherManaTest.java | 74 +++++++++++++++++-- .../cost/adventure/AdventureCardsTest.java | 16 +++- .../cards/single/FiendOfTheShadowsTest.java | 4 +- .../common/ExileAdventureSpellEffect.java | 2 +- .../abilities/keyword/HideawayAbility.java | 1 + .../abilities/keyword/ReplicateAbility.java | 19 ++--- .../mage/cards/AdventureCardSpellImpl.java | 3 +- 10 files changed, 113 insertions(+), 37 deletions(-) diff --git a/Mage.Sets/src/mage/cards/v/ViviensInvocation.java b/Mage.Sets/src/mage/cards/v/ViviensInvocation.java index 7eacc7e747e..23d46f0a18d 100644 --- a/Mage.Sets/src/mage/cards/v/ViviensInvocation.java +++ b/Mage.Sets/src/mage/cards/v/ViviensInvocation.java @@ -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) { diff --git a/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastCreaturesTest.java b/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastCreaturesTest.java index 268b58f7ef2..db8796ba96f 100644 --- a/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastCreaturesTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/AI/basic/CastCreaturesTest.java @@ -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. - * + *

* 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); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/activated/LightningStormTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/activated/LightningStormTest.java index e1ddf99d6d1..8c900e619c0 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/activated/LightningStormTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/activated/LightningStormTest.java @@ -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. - * + *

* 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); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/asthough/SpendOtherManaTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/asthough/SpendOtherManaTest.java index 1d117fc88be..3176f1d128c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/asthough/SpendOtherManaTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/asthough/SpendOtherManaTest.java @@ -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.) - * + *

* 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: - * + *

* -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); + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java index 470ea3b23de..ac2e2d6fe62 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java @@ -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); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/FiendOfTheShadowsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/FiendOfTheShadowsTest.java index bdde801cd48..4b9330199d9 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/FiendOfTheShadowsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/FiendOfTheShadowsTest.java @@ -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); diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileAdventureSpellEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileAdventureSpellEffect.java index abc8b88b923..89ad63e0abb 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileAdventureSpellEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileAdventureSpellEffect.java @@ -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; diff --git a/Mage/src/main/java/mage/abilities/keyword/HideawayAbility.java b/Mage/src/main/java/mage/abilities/keyword/HideawayAbility.java index 8d1906594fc..4ecae766997 100644 --- a/Mage/src/main/java/mage/abilities/keyword/HideawayAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/HideawayAbility.java @@ -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) { diff --git a/Mage/src/main/java/mage/abilities/keyword/ReplicateAbility.java b/Mage/src/main/java/mage/abilities/keyword/ReplicateAbility.java index 3f0c3037ddc..48de601e55e 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ReplicateAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ReplicateAbility.java @@ -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(); } } diff --git a/Mage/src/main/java/mage/cards/AdventureCardSpellImpl.java b/Mage/src/main/java/mage/cards/AdventureCardSpellImpl.java index 16b94a10dbc..f14cc4bfb58 100644 --- a/Mage/src/main/java/mage/cards/AdventureCardSpellImpl.java +++ b/Mage/src/main/java/mage/cards/AdventureCardSpellImpl.java @@ -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();