forked from External/mage
[SPM] implement Shadow of the Goblin
This commit is contained in:
parent
f663f5e002
commit
b63660e022
3 changed files with 203 additions and 0 deletions
78
Mage.Sets/src/mage/cards/s/ShadowOfTheGoblin.java
Normal file
78
Mage.Sets/src/mage/cards/s/ShadowOfTheGoblin.java
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
package mage.cards.s;
|
||||||
|
|
||||||
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
|
import mage.abilities.costs.common.DiscardCardCost;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.common.DamagePlayersEffect;
|
||||||
|
import mage.abilities.effects.common.DoIfCostPaid;
|
||||||
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
|
import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.TargetController;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jmlundeen
|
||||||
|
*/
|
||||||
|
public final class ShadowOfTheGoblin extends CardImpl {
|
||||||
|
|
||||||
|
public ShadowOfTheGoblin(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}");
|
||||||
|
|
||||||
|
|
||||||
|
// Unreliable Visions -- At the beginning of your first main phase, discard a card. If you do, draw a card.
|
||||||
|
this.addAbility(new BeginningOfFirstMainTriggeredAbility(
|
||||||
|
new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new DiscardCardCost()), false)
|
||||||
|
.withFlavorWord("Unreliable Visions")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Undying Vengeance -- Whenever you play a land or cast a spell from anywhere other than your hand, this enchantment deals 1 damage to each opponent.
|
||||||
|
this.addAbility(new ShadowOfTheGoblinTriggeredAbility(new DamagePlayersEffect(1, TargetController.OPPONENT))
|
||||||
|
.withFlavorWord("Undying Vengeance"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ShadowOfTheGoblin(final ShadowOfTheGoblin card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShadowOfTheGoblin copy() {
|
||||||
|
return new ShadowOfTheGoblin(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ShadowOfTheGoblinTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
|
public ShadowOfTheGoblinTriggeredAbility(Effect effect) {
|
||||||
|
super(Zone.BATTLEFIELD, effect, false);
|
||||||
|
setTriggerPhrase("Whenever you play a land or cast a spell from anywhere other than your hand, ");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ShadowOfTheGoblinTriggeredAbility(final ShadowOfTheGoblinTriggeredAbility triggeredAbility) {
|
||||||
|
super(triggeredAbility);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShadowOfTheGoblinTriggeredAbility copy() {
|
||||||
|
return new ShadowOfTheGoblinTriggeredAbility(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkEventType(GameEvent event, Game game) {
|
||||||
|
return event.getType() == GameEvent.EventType.PLAY_LAND ||
|
||||||
|
event.getType() == GameEvent.EventType.SPELL_CAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
|
return isControlledBy(event.getPlayerId()) && event.getZone() != Zone.HAND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -189,6 +189,8 @@ public final class MarvelsSpiderMan extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Scout the City", 113, Rarity.COMMON, mage.cards.s.ScoutTheCity.class));
|
cards.add(new SetCardInfo("Scout the City", 113, Rarity.COMMON, mage.cards.s.ScoutTheCity.class));
|
||||||
cards.add(new SetCardInfo("Secret Identity", 43, Rarity.UNCOMMON, mage.cards.s.SecretIdentity.class));
|
cards.add(new SetCardInfo("Secret Identity", 43, Rarity.UNCOMMON, mage.cards.s.SecretIdentity.class));
|
||||||
cards.add(new SetCardInfo("Selfless Police Captain", 12, Rarity.COMMON, mage.cards.s.SelflessPoliceCaptain.class));
|
cards.add(new SetCardInfo("Selfless Police Captain", 12, Rarity.COMMON, mage.cards.s.SelflessPoliceCaptain.class));
|
||||||
|
cards.add(new SetCardInfo("Shadow of the Goblin", 262, Rarity.RARE, mage.cards.s.ShadowOfTheGoblin.class, NON_FULL_USE_VARIOUS));
|
||||||
|
cards.add(new SetCardInfo("Shadow of the Goblin", 87, Rarity.RARE, mage.cards.s.ShadowOfTheGoblin.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Shock", 88, Rarity.COMMON, mage.cards.s.Shock.class));
|
cards.add(new SetCardInfo("Shock", 88, Rarity.COMMON, mage.cards.s.Shock.class));
|
||||||
cards.add(new SetCardInfo("Shocker, Unshakable", 89, Rarity.UNCOMMON, mage.cards.s.ShockerUnshakable.class));
|
cards.add(new SetCardInfo("Shocker, Unshakable", 89, Rarity.UNCOMMON, mage.cards.s.ShockerUnshakable.class));
|
||||||
cards.add(new SetCardInfo("Silver Sable, Mercenary Leader", 13, Rarity.UNCOMMON, mage.cards.s.SilverSableMercenaryLeader.class));
|
cards.add(new SetCardInfo("Silver Sable, Mercenary Leader", 13, Rarity.UNCOMMON, mage.cards.s.SilverSableMercenaryLeader.class));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,123 @@
|
||||||
|
package org.mage.test.cards.single.spm;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jmlundeen
|
||||||
|
*/
|
||||||
|
public class ShadowOfTheGoblinTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Shadow of the Goblin
|
||||||
|
{1}{R}
|
||||||
|
Enchantment
|
||||||
|
Unreliable Visions -- At the beginning of your first main phase, discard a card. If you do, draw a card.
|
||||||
|
Undying Vengeance -- Whenever you play a land or cast a spell from anywhere other than your hand, this enchantment deals 1 damage to each opponent.
|
||||||
|
*/
|
||||||
|
private static final String shadowOfTheGoblin = "Shadow of the Goblin";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Party Thrasher
|
||||||
|
{1}{R}
|
||||||
|
Creature - Lizard Wizard
|
||||||
|
Noncreature spells you cast from exile have convoke.
|
||||||
|
At the beginning of your precombat main phase, you may discard a card. If you do, exile the top two cards of your library, then choose one of them. You may play that card this turn.
|
||||||
|
1/4
|
||||||
|
*/
|
||||||
|
private static final String partyThrasher = "Party Thrasher";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Misthollow Griffin
|
||||||
|
{2}{U}{U}
|
||||||
|
Creature - Griffin
|
||||||
|
Flying
|
||||||
|
You may cast Misthollow Griffin from exile.
|
||||||
|
3/3
|
||||||
|
*/
|
||||||
|
private static final String misthollowGriffin = "Misthollow Griffin";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Glarb, Calamity's Augur
|
||||||
|
{B}{G}{U}
|
||||||
|
Legendary Creature - Frog Wizard Noble
|
||||||
|
Deathtouch
|
||||||
|
You may look at the top card of your library any time.
|
||||||
|
You may play lands and cast spells with mana value 4 or greater from the top of your library.
|
||||||
|
{T}: Surveil 2.
|
||||||
|
2/4
|
||||||
|
*/
|
||||||
|
private static final String glarbCalamitysAugur = "Glarb, Calamity's Augur";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShadowOfTheGoblinFromHand() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, shadowOfTheGoblin);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||||
|
addCard(Zone.HAND, playerA, "Mountain");
|
||||||
|
addCard(Zone.HAND, playerA, partyThrasher);
|
||||||
|
|
||||||
|
setChoice(playerA, false); // shadow trigger
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
|
||||||
|
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mountain");
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, partyThrasher);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertLife(playerB, 20); // no trigger
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShadowOfTheGoblinFromExile() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, shadowOfTheGoblin);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, partyThrasher);
|
||||||
|
addCard(Zone.HAND, playerA, "Mountain");
|
||||||
|
addCard(Zone.EXILED, playerA, misthollowGriffin);
|
||||||
|
|
||||||
|
setChoice(playerA, "<i>Unreliable Visions</i>");
|
||||||
|
setChoice(playerA, true); // discard
|
||||||
|
setChoice(playerA, "Mountain", 2);
|
||||||
|
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mountain");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, misthollowGriffin);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertLife(playerB, 20 - 1 - 1); // land + spell from exile
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShadowOfTheGoblinFromLibrary() {
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
skipInitShuffling();
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, shadowOfTheGoblin);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, glarbCalamitysAugur);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||||
|
addCard(Zone.LIBRARY, playerA, misthollowGriffin);
|
||||||
|
addCard(Zone.LIBRARY, playerA, "Island");
|
||||||
|
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Island");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, misthollowGriffin);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertLife(playerB, 20 - 1 - 1); // land + spell from library
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue