mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
[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("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("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("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));
|
||||
|
|
|
|||
|
|
@ -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