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 81ffca8039b..13e7591b7d3 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 @@ -23,11 +23,26 @@ public class AdventureCardsTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); + assertAllCommandsUsed(); + assertHandCount(playerA, 0); + assertPermanentCount(playerA, "Food", 1); + assertExileCount(playerA, "Curious Pair", 1); + assertGraveyardCount(playerA,0); + } + + @Test + public void testCantCastTreatsToShareTwice() { + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); + addCard(Zone.HAND, playerA, "Curious Pair"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share"); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); assertHandCount(playerA, 0); assertPermanentCount(playerA, "Food", 1); assertExileCount(playerA, "Curious Pair", 1); assertGraveyardCount(playerA,0); - assertAllCommandsUsed(); } @Test @@ -39,12 +54,12 @@ public class AdventureCardsTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); + assertAllCommandsUsed(); assertHandCount(playerA, 0); assertPermanentCount(playerA, "Food", 0); assertPermanentCount(playerA, "Curious Pair", 1); assertExileCount(playerA, "Curious Pair", 0); assertGraveyardCount(playerA,0); - assertAllCommandsUsed(); } @Test @@ -58,12 +73,12 @@ public class AdventureCardsTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); + assertAllCommandsUsed(); assertHandCount(playerA, 0); assertPermanentCount(playerA, "Food", 1); assertPermanentCount(playerA, "Curious Pair", 1); assertExileCount(playerA, "Curious Pair", 0); assertGraveyardCount(playerA, 0); - assertAllCommandsUsed(); } @Test @@ -83,12 +98,12 @@ public class AdventureCardsTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); + assertAllCommandsUsed(); assertHandCount(playerA, 0); assertPermanentCount(playerA, "Food", 1); assertPermanentCount(playerA, "Curious Pair", 0); assertExileCount(playerA, "Curious Pair", 1); assertGraveyardCount(playerA, 0); - assertAllCommandsUsed(); } @Test @@ -106,7 +121,6 @@ public class AdventureCardsTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Curious Pair", 1); assertExileCount(playerA, "Curious Pair", 0); assertGraveyardCount(playerA,0); - assertAllCommandsUsed(); } @Test @@ -121,12 +135,12 @@ public class AdventureCardsTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); + assertAllCommandsUsed(); assertHandCount(playerA, 1); assertPermanentCount(playerA, "Food", 1); assertPermanentCount(playerA, "Curious Pair", 1); assertExileCount(playerA, "Curious Pair", 0); assertGraveyardCount(playerA, 0); - assertAllCommandsUsed(); } @Test @@ -153,11 +167,11 @@ public class AdventureCardsTest extends CardTestPlayerBase { setStopAt(2, PhaseStep.BEGIN_COMBAT); execute(); + assertAllCommandsUsed(); assertHandCount(playerA, 0); assertExileCount(playerA, "Curious Pair", 0); assertGraveyardCount(playerA, 2); - assertAllCommandsUsed(); } @Test @@ -175,13 +189,13 @@ public class AdventureCardsTest extends CardTestPlayerBase { setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); + assertAllCommandsUsed(); assertHandCount(playerA, 0); assertPermanentCount(playerA, "Food", 2); assertPermanentCount(playerA, "Curious Pair", 0); assertExileCount(playerA, "Curious Pair", 1); assertGraveyardCount(playerA, 0); - assertAllCommandsUsed(); } @Test @@ -202,6 +216,7 @@ public class AdventureCardsTest extends CardTestPlayerBase { setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); + assertAllCommandsUsed(); assertHandCount(playerA, 0); assertPermanentCount(playerA, "Food", 2); @@ -210,6 +225,70 @@ public class AdventureCardsTest extends CardTestPlayerBase { assertExileCount(playerA, 1); assertGraveyardCount(playerA, "Fork", 1); assertGraveyardCount(playerA, 1); + } + + @Test + public void testCastTreatsToShareAndCounter() { + /* + * Counterspell {U}{U} + * Instant + * Counter target spell. + */ + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, "Forest"); + addCard(Zone.BATTLEFIELD, playerB, "Island"); + addCard(Zone.BATTLEFIELD, playerB, "Island"); + addCard(Zone.HAND, playerA, "Curious Pair"); + addCard(Zone.HAND, playerB, "Counterspell"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Counterspell", "Treats to Share"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); assertAllCommandsUsed(); + + assertHandCount(playerA, 0); + assertPermanentCount(playerA, "Food", 0); + assertPermanentCount(playerA, 1); + assertExileCount(playerA, 0); + assertGraveyardCount(playerA, "Curious Pair", 1); + assertGraveyardCount(playerA, 1); + assertGraveyardCount(playerB, "Counterspell", 1); + assertGraveyardCount(playerB, 1); + } + + @Test + public void testCastOpponentsHandTreatsToShare() { + /* + * Psychic Intrusion {3}{U}{B} + * Sorcery + * Target opponent reveals their hand. You choose a nonland card from that player's graveyard or hand and exile it. + * You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell. + */ + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 3); + addCard(Zone.HAND, playerA, "Psychic Intrusion"); + addCard(Zone.HAND, playerB, "Curious Pair"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Psychic Intrusion", playerB); + playerA.addChoice("Curious Pair"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertAllCommandsUsed(); + assertHandCount(playerA, 0); + assertHandCount(playerB, 0); + assertPermanentCount(playerB, 0); + assertPermanentCount(playerA, "Food", 1); + assertPermanentCount(playerA, "Curious Pair", 1); + assertExileCount(playerA, 0); + assertExileCount(playerB, 0); + assertGraveyardCount(playerA, "Psychic Intrusion", 1); + assertGraveyardCount(playerA, 1); } } 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 a168ecb6307..9c1cb072055 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileAdventureSpellEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileAdventureSpellEffect.java @@ -5,17 +5,17 @@ import mage.abilities.MageSingleton; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; -import mage.cards.AdventureCard; import mage.cards.AdventureCardSpell; import mage.cards.Card; import mage.constants.AsThoughEffectType; import mage.constants.Duration; import mage.constants.Outcome; -import mage.constants.Zone; +import mage.game.ExileZone; import mage.game.Game; import mage.game.stack.Spell; import mage.players.Player; import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; import java.util.UUID; @@ -30,6 +30,10 @@ public class ExileAdventureSpellEffect extends OneShotEffect implements MageSing return instance; } + public static UUID adventureExileId(UUID controllerId, Game game) { + return CardUtil.getExileZoneId(controllerId.toString() + "- On an Adventure", game); + } + private ExileAdventureSpellEffect() { super(Outcome.Exile); staticText = ""; @@ -48,8 +52,10 @@ public class ExileAdventureSpellEffect extends OneShotEffect implements MageSing if (spell != null && !spell.isCopy()) { Card spellCard = spell.getCard(); if (spellCard != null && spellCard instanceof AdventureCardSpell) { + UUID exileId = adventureExileId(controller.getId(), game); + game.getExile().createZone(exileId, "On an Adventure"); AdventureCardSpell adventureSpellCard = (AdventureCardSpell) spellCard; - if (controller.moveCards(adventureSpellCard, Zone.EXILED, source, game)) { + if (controller.moveCardsToExile(adventureSpellCard, source, game, true, exileId, "On an Adventure")) { ContinuousEffect effect = new AdventureCastFromExileEffect(); effect.setTargetPointer(new FixedTarget(adventureSpellCard.getParentCard().getId(), game)); game.addEffect(effect, source); @@ -86,10 +92,12 @@ class AdventureCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { UUID targetId = getTargetPointer().getFirst(game, source); + ExileZone adventureExileZone = game.getExile().getExileZone(ExileAdventureSpellEffect.adventureExileId(affectedControllerId, game)); if (targetId == null) { this.discard(); } else if (objectId.equals(targetId) - && affectedControllerId.equals(source.getControllerId())) { + && affectedControllerId.equals(source.getControllerId()) + && adventureExileZone.contains(objectId)) { Card card = game.getCard(objectId); return card != null; } diff --git a/Mage/src/main/java/mage/cards/AdventureCardSpellImpl.java b/Mage/src/main/java/mage/cards/AdventureCardSpellImpl.java index d8a1b2212a4..88b1a794b37 100644 --- a/Mage/src/main/java/mage/cards/AdventureCardSpellImpl.java +++ b/Mage/src/main/java/mage/cards/AdventureCardSpellImpl.java @@ -5,10 +5,13 @@ */ package mage.cards; +import mage.abilities.SpellAbility; +import mage.abilities.effects.common.ExileAdventureSpellEffect; import mage.constants.CardType; import mage.constants.SpellAbilityType; import mage.constants.SubType; import mage.constants.Zone; +import mage.game.ExileZone; import mage.game.Game; import java.util.List; @@ -25,6 +28,7 @@ public class AdventureCardSpellImpl extends CardImpl implements AdventureCardSpe public AdventureCardSpellImpl(UUID ownerId, CardSetInfo setInfo, CardType[] cardTypes, String costs, AdventureCard adventureCardParent) { super(ownerId, setInfo, cardTypes, costs, SpellAbilityType.ADVENTURE_SPELL); this.subtype.add(SubType.ADVENTURE); + this.replaceSpellAbility(new AdventureCardSpellAbility(getSpellAbility())); this.adventureCardParent = adventureCardParent; } @@ -89,3 +93,19 @@ public class AdventureCardSpellImpl extends CardImpl implements AdventureCardSpe return this.adventureCardParent; } } + +class AdventureCardSpellAbility extends SpellAbility { + public AdventureCardSpellAbility(SpellAbility ability) { + super(ability); + } + + @Override + public ActivationStatus canActivate(UUID playerId, Game game) { + ExileZone adventureExileZone = game.getExile().getExileZone(ExileAdventureSpellEffect.adventureExileId(playerId, game)); + if (adventureExileZone != null && adventureExileZone.contains(this.getSourceId())) { + return ActivationStatus.getFalse(); + } else { + return super.canActivate(playerId, game); + } + } +} \ No newline at end of file