From aaf8f92db70d048beeac22a594ca71999b2913ea Mon Sep 17 00:00:00 2001 From: Vivian Greenslade Date: Sat, 9 Sep 2023 17:03:40 -0230 Subject: [PATCH] fix Gustha's Scepter; add test (#11141) --- .../src/mage/cards/g/GusthasScepter.java | 53 ++++++---------- .../cards/single/me2/GusthasScepterTest.java | 63 +++++++++++++++++++ 2 files changed, 82 insertions(+), 34 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/me2/GusthasScepterTest.java diff --git a/Mage.Sets/src/mage/cards/g/GusthasScepter.java b/Mage.Sets/src/mage/cards/g/GusthasScepter.java index a80c53291db..a9634988bf5 100644 --- a/Mage.Sets/src/mage/cards/g/GusthasScepter.java +++ b/Mage.Sets/src/mage/cards/g/GusthasScepter.java @@ -2,7 +2,7 @@ package mage.cards.g; import mage.MageObjectReference; import mage.abilities.Ability; -import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.AsThoughEffectImpl; @@ -15,7 +15,6 @@ import mage.filter.FilterCard; import mage.game.ExileZone; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; import mage.players.Player; import mage.target.TargetCard; import mage.target.common.TargetCardInExile; @@ -39,7 +38,7 @@ public final class GusthasScepter extends CardImpl { this.addAbility(new SimpleActivatedAbility(new GusthasScepterReturnEffect(), new TapSourceCost())); // When you lose control of Gustha’s Scepter, put all cards exiled with Gustha’s Scepter into their owner’s graveyard. - this.addAbility(new GusthasScepterLoseControlAbility()); + this.addAbility(new GusthasScepterTriggeredAbility()); } private GusthasScepter(final GusthasScepter card) { @@ -166,66 +165,52 @@ class GusthasScepterLookAtCardEffect extends AsThoughEffectImpl { } } -class GusthasScepterLoseControlAbility extends DelayedTriggeredAbility { +class GusthasScepterTriggeredAbility extends TriggeredAbilityImpl { - public GusthasScepterLoseControlAbility() { - super(new GusthasScepterPutExiledCardsInOwnersGraveyard(), Duration.EndOfGame, false); + public GusthasScepterTriggeredAbility() { + super(Zone.BATTLEFIELD, new GusthasScepterPutExiledCardsInOwnersGraveyardEffect()); + setTriggerPhrase("When you lose control of {this}, "); } - private GusthasScepterLoseControlAbility(final GusthasScepterLoseControlAbility ability) { + private GusthasScepterTriggeredAbility(final GusthasScepterTriggeredAbility ability) { super(ability); } @Override - public GusthasScepterLoseControlAbility copy() { - return new GusthasScepterLoseControlAbility(this); + public GusthasScepterTriggeredAbility copy() { + return new GusthasScepterTriggeredAbility(this); } @Override public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.LOST_CONTROL - || event.getType() == GameEvent.EventType.ZONE_CHANGE; + return event.getType() == GameEvent.EventType.LOST_CONTROL; } public boolean checkTrigger(GameEvent event, Game game) { - switch (event.getType()) { - case LOST_CONTROL: - return event.getPlayerId().equals(controllerId) - && event.getTargetId().equals(this.getSourceId()); - case ZONE_CHANGE: - return event.getTargetId().equals(this.getSourceId()) && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD; - } - return false; - } - - @Override - public String getRule() { - return "When you lose control of {this}, put all cards exiled with {this} into their owner's graveyard."; + return event.getTargetId().equals(sourceId); } } -class GusthasScepterPutExiledCardsInOwnersGraveyard extends OneShotEffect { +class GusthasScepterPutExiledCardsInOwnersGraveyardEffect extends OneShotEffect { - public GusthasScepterPutExiledCardsInOwnersGraveyard() { + public GusthasScepterPutExiledCardsInOwnersGraveyardEffect() { super(Outcome.Neutral); + this.staticText = "put all cards exiled with {this} into their owner's graveyard"; } - private GusthasScepterPutExiledCardsInOwnersGraveyard(final GusthasScepterPutExiledCardsInOwnersGraveyard effect) { + private GusthasScepterPutExiledCardsInOwnersGraveyardEffect(final GusthasScepterPutExiledCardsInOwnersGraveyardEffect effect) { super(effect); } @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source)); - return exileZone != null && controller.moveCards(exileZone.getCards(game), Zone.GRAVEYARD, source, game); + exileZone.getCards(game).stream().forEach(card -> card.moveToZone(Zone.GRAVEYARD, source, game, false)); + return true; } @Override - public GusthasScepterPutExiledCardsInOwnersGraveyard copy() { - return new GusthasScepterPutExiledCardsInOwnersGraveyard(this); + public GusthasScepterPutExiledCardsInOwnersGraveyardEffect copy() { + return new GusthasScepterPutExiledCardsInOwnersGraveyardEffect(this); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/me2/GusthasScepterTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/me2/GusthasScepterTest.java new file mode 100644 index 00000000000..435c1a1df54 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/me2/GusthasScepterTest.java @@ -0,0 +1,63 @@ +package org.mage.test.cards.single.me2; + +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +import mage.constants.PhaseStep; +import mage.constants.Zone; + +public class GusthasScepterTest extends CardTestPlayerBase { + + private static final String SCEPTER = "Gustha's Scepter"; + private static final String OFFERING = "Harmless Offering"; + private static final String LION = "Silvercoat Lion"; + + /** + * : Exile a card from your hand face down. You may look at it for as long as it remains exiled. + * {T}: Return a card you own exiled with Gustha’s Scepter to your hand. + * When you lose control of Gustha’s Scepter, put all cards exiled with Gustha’s Scepter into their owner’s graveyard. + */ + @Test + public void testEffect() { + addCard(Zone.HAND, playerA, LION); + addCard(Zone.BATTLEFIELD, playerA, SCEPTER); + + // Player A activates scepter turn 1, exiling Lion + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Exile"); + addTarget(playerA, LION); + + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Return"); + setChoice(playerA, LION); + + setStrictChooseMode(true); + setStopAt(3, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertHandCount(activePlayer, LION, 1); + } + + @Test + public void testLostControl() { + addCard(Zone.HAND, playerA, LION); + addCard(Zone.HAND, playerA, OFFERING); + addCard(Zone.BATTLEFIELD, playerA, SCEPTER); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); + + // Player A activates scepter turn 1, exiling Lion + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Exile"); + addTarget(playerA, LION); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + + // Player A casts Harmless Offering, giving control of Scepter to Player B and triggering its effect + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, OFFERING); + addTarget(playerA, playerB); + addTarget(playerA, SCEPTER); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertGraveyardCount(playerA, LION, 1); + } + +}