diff --git a/Mage.Sets/src/mage/sets/MarvelsSpiderMan.java b/Mage.Sets/src/mage/sets/MarvelsSpiderMan.java index 773dc33b9d0..746e298113e 100644 --- a/Mage.Sets/src/mage/sets/MarvelsSpiderMan.java +++ b/Mage.Sets/src/mage/sets/MarvelsSpiderMan.java @@ -4,15 +4,11 @@ import mage.cards.ExpansionSet; import mage.constants.Rarity; import mage.constants.SetType; -import java.util.Arrays; -import java.util.List; - /** * @author TheElk801 */ public final class MarvelsSpiderMan extends ExpansionSet { - private static final List unfinished = Arrays.asList("Electro's Bolt", "Spider-Islanders"); private static final MarvelsSpiderMan instance = new MarvelsSpiderMan(); public static MarvelsSpiderMan getInstance() { @@ -98,7 +94,5 @@ public final class MarvelsSpiderMan extends ExpansionSet { cards.add(new SetCardInfo("Web-Warriors", 203, Rarity.UNCOMMON, mage.cards.w.WebWarriors.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Whoosh!", 48, Rarity.COMMON, mage.cards.w.Whoosh.class)); cards.add(new SetCardInfo("Wild Pack Squad", 23, Rarity.COMMON, mage.cards.w.WildPackSquad.class)); - - cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName())); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MayhemTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MayhemTest.java new file mode 100644 index 00000000000..79bfd41042b --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/MayhemTest.java @@ -0,0 +1,89 @@ +package org.mage.test.cards.abilities.keywords; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Assert; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author TheElk801 + */ +public class MayhemTest extends CardTestPlayerBase { + + private static final String islanders = "Spider-Islanders"; + + @Test + public void testCastRegular() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4); + addCard(Zone.HAND, playerA, islanders); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, islanders); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, islanders, 1); + } + + private static final String imp = "Putrid Imp"; + + @Test + public void testCastDiscarded() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + addCard(Zone.BATTLEFIELD, playerA, imp); + addCard(Zone.HAND, playerA, islanders); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Discard"); + setChoice(playerA, islanders); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, islanders + " with Mayhem"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, islanders, 1); + } + + @Test + public void testCantCastGraveyard() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + addCard(Zone.GRAVEYARD, playerA, islanders); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, islanders + " with Mayhem"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + try { + execute(); + } catch (Throwable e) { + Assert.assertEquals( + "Should fail to be able to cast " + islanders + " with mayhem as it wasn't discarded this turn", + "Can't find ability to activate command: Cast " + islanders + " with Mayhem", e.getMessage() + ); + } + } + + @Test + public void testCantCastDiscardedPreviously() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + addCard(Zone.BATTLEFIELD, playerA, imp); + addCard(Zone.HAND, playerA, islanders); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Discard"); + setChoice(playerA, islanders); + castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerA, islanders + " with Mayhem"); + + setStrictChooseMode(true); + setStopAt(3, PhaseStep.END_TURN); + try { + execute(); + } catch (Throwable e) { + Assert.assertEquals( + "Should fail to be able to cast " + islanders + " with mayhem as it wasn't discarded this turn", + "Can't find ability to activate command: Cast " + islanders + " with Mayhem", e.getMessage() + ); + } + } +} diff --git a/Mage/src/main/java/mage/abilities/keyword/MayhemAbility.java b/Mage/src/main/java/mage/abilities/keyword/MayhemAbility.java index 4b0478a40ba..5563f9940dc 100644 --- a/Mage/src/main/java/mage/abilities/keyword/MayhemAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/MayhemAbility.java @@ -1,16 +1,19 @@ package mage.abilities.keyword; -import mage.ApprovingObject; import mage.MageIdentifier; +import mage.MageObjectReference; import mage.abilities.SpellAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.cards.Card; import mage.constants.SpellAbilityType; +import mage.constants.WatcherScope; import mage.constants.Zone; import mage.game.Game; -import mage.players.Player; -import mage.watchers.common.CastSpellLastTurnWatcher; +import mage.game.events.DiscardedCardsEvent; +import mage.game.events.GameEvent; +import mage.watchers.Watcher; +import java.util.HashSet; import java.util.Set; import java.util.UUID; @@ -33,10 +36,10 @@ public class MayhemAbility extends SpellAbility { this.clearManaCosts(); this.clearManaCostsToPay(); this.addCost(new ManaCostsImpl<>(manaString)); - + this.addWatcher(new MayhemWatcher()); this.setRuleAtTheTop(true); - this.rule = "Surge " + manaString + - " (You may cast this card from your graveyard for "+manaString+ + this.rule = "Mayhem " + manaString + + " (You may cast this card from your graveyard for " + manaString + " if you discarded it this turn. Timing rules still apply.)"; } @@ -47,8 +50,11 @@ public class MayhemAbility extends SpellAbility { @Override public ActivationStatus canActivate(UUID playerId, Game game) { - // TODO: Implement this - return super.canActivate(playerId,game); + if (!Zone.GRAVEYARD.match(game.getState().getZone(getSourceId())) + || !MayhemWatcher.checkCard(getSourceId(), game)) { + return ActivationStatus.getFalse(); + } + return super.canActivate(playerId, game); } @Override @@ -69,5 +75,38 @@ public class MayhemAbility extends SpellAbility { public String getRule() { return rule; } - +} + +class MayhemWatcher extends Watcher { + + private final Set set = new HashSet<>(); + + MayhemWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() != GameEvent.EventType.DISCARDED_CARDS) { + return; + } + for (Card card : ((DiscardedCardsEvent) event).getDiscardedCards().getCards(game)) { + set.add(new MageObjectReference(card, game)); + } + } + + @Override + public void reset() { + super.reset(); + set.clear(); + } + + static boolean checkCard(UUID cardId, Game game) { + return game + .getState() + .getWatcher(MayhemWatcher.class) + .set + .stream() + .anyMatch(mor -> mor.refersTo(cardId, game)); + } }