forked from External/mage
Implement Mayhem mechanic (#13877)
This commit is contained in:
parent
e8cd6dbdad
commit
1700180455
3 changed files with 137 additions and 15 deletions
|
|
@ -4,15 +4,11 @@ import mage.cards.ExpansionSet;
|
||||||
import mage.constants.Rarity;
|
import mage.constants.Rarity;
|
||||||
import mage.constants.SetType;
|
import mage.constants.SetType;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
public final class MarvelsSpiderMan extends ExpansionSet {
|
public final class MarvelsSpiderMan extends ExpansionSet {
|
||||||
|
|
||||||
private static final List<String> unfinished = Arrays.asList("Electro's Bolt", "Spider-Islanders");
|
|
||||||
private static final MarvelsSpiderMan instance = new MarvelsSpiderMan();
|
private static final MarvelsSpiderMan instance = new MarvelsSpiderMan();
|
||||||
|
|
||||||
public static MarvelsSpiderMan getInstance() {
|
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("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("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.add(new SetCardInfo("Wild Pack Squad", 23, Rarity.COMMON, mage.cards.w.WildPackSquad.class));
|
||||||
|
|
||||||
cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,16 +1,19 @@
|
||||||
package mage.abilities.keyword;
|
package mage.abilities.keyword;
|
||||||
|
|
||||||
import mage.ApprovingObject;
|
|
||||||
import mage.MageIdentifier;
|
import mage.MageIdentifier;
|
||||||
|
import mage.MageObjectReference;
|
||||||
import mage.abilities.SpellAbility;
|
import mage.abilities.SpellAbility;
|
||||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.constants.SpellAbilityType;
|
import mage.constants.SpellAbilityType;
|
||||||
|
import mage.constants.WatcherScope;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.players.Player;
|
import mage.game.events.DiscardedCardsEvent;
|
||||||
import mage.watchers.common.CastSpellLastTurnWatcher;
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.watchers.Watcher;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -33,10 +36,10 @@ public class MayhemAbility extends SpellAbility {
|
||||||
this.clearManaCosts();
|
this.clearManaCosts();
|
||||||
this.clearManaCostsToPay();
|
this.clearManaCostsToPay();
|
||||||
this.addCost(new ManaCostsImpl<>(manaString));
|
this.addCost(new ManaCostsImpl<>(manaString));
|
||||||
|
this.addWatcher(new MayhemWatcher());
|
||||||
this.setRuleAtTheTop(true);
|
this.setRuleAtTheTop(true);
|
||||||
this.rule = "Surge " + manaString +
|
this.rule = "Mayhem " + manaString +
|
||||||
" <i>(You may cast this card from your graveyard for "+manaString+
|
" <i>(You may cast this card from your graveyard for " + manaString +
|
||||||
" if you discarded it this turn. Timing rules still apply.)</i>";
|
" if you discarded it this turn. Timing rules still apply.)</i>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,8 +50,11 @@ public class MayhemAbility extends SpellAbility {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActivationStatus canActivate(UUID playerId, Game game) {
|
public ActivationStatus canActivate(UUID playerId, Game game) {
|
||||||
// TODO: Implement this
|
if (!Zone.GRAVEYARD.match(game.getState().getZone(getSourceId()))
|
||||||
return super.canActivate(playerId,game);
|
|| !MayhemWatcher.checkCard(getSourceId(), game)) {
|
||||||
|
return ActivationStatus.getFalse();
|
||||||
|
}
|
||||||
|
return super.canActivate(playerId, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -69,5 +75,38 @@ public class MayhemAbility extends SpellAbility {
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MayhemWatcher extends Watcher {
|
||||||
|
|
||||||
|
private final Set<MageObjectReference> 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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue