mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 21:29:17 -08:00
[WOE] Implement Stroke of midnight (refactor together similar effects) (#10834)
* [WOE] Implement Stroke of Midnight * refactor similar effects together. * add tests (and fix a bug) --------- Co-authored-by: Evan Kranzler <theelk801@gmail.com>
This commit is contained in:
parent
c6b49253c9
commit
43de68afe3
20 changed files with 324 additions and 582 deletions
|
|
@ -1,18 +1,15 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.SpiritWhiteToken;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Backfir3
|
||||
|
|
@ -26,7 +23,7 @@ public final class Afterlife extends CardImpl {
|
|||
// 1/1 white Spirit creature token with flying.
|
||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||
this.getSpellAbility().addEffect(new DestroyTargetEffect(true));
|
||||
this.getSpellAbility().addEffect(new AfterlifeEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new SpiritWhiteToken()));
|
||||
}
|
||||
|
||||
private Afterlife(final Afterlife card) {
|
||||
|
|
@ -37,32 +34,4 @@ public final class Afterlife extends CardImpl {
|
|||
public Afterlife copy() {
|
||||
return new Afterlife(this);
|
||||
}
|
||||
}
|
||||
|
||||
class AfterlifeEffect extends OneShotEffect {
|
||||
|
||||
public AfterlifeEffect() {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
staticText = "Its controller creates a 1/1 white Spirit creature token with flying";
|
||||
}
|
||||
|
||||
public AfterlifeEffect(final AfterlifeEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AfterlifeEffect copy() {
|
||||
return new AfterlifeEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
|
||||
if (permanent != null) {
|
||||
SpiritWhiteToken token = new SpiritWhiteToken();
|
||||
token.putOntoBattlefield(1, game, source, permanent.getControllerId());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +1,15 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.AngelToken;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.target.common.TargetCreatureOrPlaneswalker;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
|
|
@ -24,7 +20,7 @@ public final class AngelicAscension extends CardImpl {
|
|||
|
||||
// Exile target creature or planeswalker. Its controller creates a 4/4 white Angel creature token with flying.
|
||||
this.getSpellAbility().addEffect(new ExileTargetEffect());
|
||||
this.getSpellAbility().addEffect(new AngelicAscensionEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new AngelToken()));
|
||||
this.getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker());
|
||||
}
|
||||
|
||||
|
|
@ -36,32 +32,4 @@ public final class AngelicAscension extends CardImpl {
|
|||
public AngelicAscension copy() {
|
||||
return new AngelicAscension(this);
|
||||
}
|
||||
}
|
||||
|
||||
class AngelicAscensionEffect extends OneShotEffect {
|
||||
|
||||
private static final Token token = new AngelToken();
|
||||
|
||||
AngelicAscensionEffect() {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
this.staticText = "Its controller creates a 4/4 white Angel creature token with flying";
|
||||
}
|
||||
|
||||
private AngelicAscensionEffect(final AngelicAscensionEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AngelicAscensionEffect copy() {
|
||||
return new AngelicAscensionEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
return token.putOntoBattlefield(1, game, source, permanent.getControllerId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,10 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.BeastToken;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
|
|
@ -25,7 +21,7 @@ public final class BeastWithin extends CardImpl {
|
|||
// Destroy target permanent. Its controller creates a 3/3 green Beast creature token.
|
||||
this.getSpellAbility().addTarget(new TargetPermanent());
|
||||
this.getSpellAbility().addEffect(new DestroyTargetEffect());
|
||||
this.getSpellAbility().addEffect(new BeastWithinEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new BeastToken()));
|
||||
}
|
||||
|
||||
private BeastWithin(final BeastWithin card) {
|
||||
|
|
@ -36,34 +32,4 @@ public final class BeastWithin extends CardImpl {
|
|||
public BeastWithin copy() {
|
||||
return new BeastWithin(this);
|
||||
}
|
||||
}
|
||||
|
||||
class BeastWithinEffect extends OneShotEffect {
|
||||
|
||||
public BeastWithinEffect() {
|
||||
super(Outcome.Detriment);
|
||||
staticText = "Its controller creates a 3/3 green Beast creature token";
|
||||
}
|
||||
|
||||
public BeastWithinEffect(final BeastWithinEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeastWithinEffect copy() {
|
||||
return new BeastWithinEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
// If the permanent is an illegal target when Beast Within tries to resolve, the spell won’t resolve and none
|
||||
// of its effects will happen. The permanent’s controller won’t get a Beast token.
|
||||
// (2011-06-01)
|
||||
Permanent permanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source); // must use LKI
|
||||
if (permanent != null) {
|
||||
new BeastToken().putOntoBattlefield(1, game, source, permanent.getControllerId());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,10 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.TreasureToken;
|
||||
import mage.target.common.TargetNonlandPermanent;
|
||||
|
||||
|
|
@ -24,7 +20,7 @@ public final class BuyYourSilence extends CardImpl {
|
|||
|
||||
// Exile target nonland permanent. Its controller creates a Treasure token.
|
||||
this.getSpellAbility().addEffect(new ExileTargetEffect());
|
||||
this.getSpellAbility().addEffect(new BuyYourSilenceEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new TreasureToken()));
|
||||
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
|
||||
}
|
||||
|
||||
|
|
@ -36,30 +32,4 @@ public final class BuyYourSilence extends CardImpl {
|
|||
public BuyYourSilence copy() {
|
||||
return new BuyYourSilence(this);
|
||||
}
|
||||
}
|
||||
|
||||
class BuyYourSilenceEffect extends OneShotEffect {
|
||||
|
||||
BuyYourSilenceEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "Its controller creates a Treasure token";
|
||||
}
|
||||
|
||||
private BuyYourSilenceEffect(final BuyYourSilenceEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuyYourSilenceEffect copy() {
|
||||
return new BuyYourSilenceEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
return new TreasureToken().putOntoBattlefield(1, game, source, permanent.getControllerId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,25 +4,19 @@ import mage.MageInt;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.DiesSourceTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenTargetEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
|
||||
import mage.abilities.keyword.VigilanceAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.common.FilterArtifactOrEnchantmentCard;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.GolemToken;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
import mage.target.common.TargetNonlandPermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -46,7 +40,8 @@ public final class CavalierOfDawn extends CardImpl {
|
|||
this.addAbility(VigilanceAbility.getInstance());
|
||||
|
||||
// When Cavalier of Dawn enters the battlefield, destroy up to one target nonland permanent. Its controller creates a 3/3 colorless Golem artifact creature token.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new CavalierOfDawnEffect());
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect());
|
||||
ability.addEffect(new CreateTokenControllerTargetPermanentEffect(new GolemToken()));
|
||||
ability.addTarget(new TargetNonlandPermanent(0, 1, false));
|
||||
this.addAbility(ability);
|
||||
|
||||
|
|
@ -64,38 +59,4 @@ public final class CavalierOfDawn extends CardImpl {
|
|||
public CavalierOfDawn copy() {
|
||||
return new CavalierOfDawn(this);
|
||||
}
|
||||
}
|
||||
|
||||
class CavalierOfDawnEffect extends OneShotEffect {
|
||||
|
||||
CavalierOfDawnEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "destroy up to one target nonland permanent. " +
|
||||
"Its controller creates a 3/3 colorless Golem artifact creature token.";
|
||||
}
|
||||
|
||||
private CavalierOfDawnEffect(final CavalierOfDawnEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CavalierOfDawnEffect copy() {
|
||||
return new CavalierOfDawnEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
Player player = game.getPlayer(permanent.getControllerId());
|
||||
permanent.destroy(source, game, false);
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
Effect effect = new CreateTokenTargetEffect(new GolemToken());
|
||||
effect.setTargetPointer(new FixedTarget(player.getId(), game));
|
||||
return effect.apply(game, source);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +1,25 @@
|
|||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.abilities.keyword.UnearthAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.PowerstoneToken;
|
||||
import mage.target.common.TargetNonlandPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author weirddan455
|
||||
|
|
@ -38,6 +38,7 @@ public final class CityscapeLeveler extends CardImpl {
|
|||
|
||||
// When you cast this spell and whenever Cityscape Leveler attacks, destroy up to one target nonland permanent. Its controller creates a tapped Powerstone token.
|
||||
Ability ability = new CityscapeLevelerAbility();
|
||||
ability.addEffect(new CreateTokenControllerTargetPermanentEffect(new PowerstoneToken(), 1, true));
|
||||
ability.addTarget(new TargetNonlandPermanent(0, 1));
|
||||
this.addAbility(ability);
|
||||
|
||||
|
|
@ -58,7 +59,7 @@ public final class CityscapeLeveler extends CardImpl {
|
|||
class CityscapeLevelerAbility extends TriggeredAbilityImpl {
|
||||
|
||||
public CityscapeLevelerAbility() {
|
||||
super(Zone.ALL, new CityscapeLevelerEffect());
|
||||
super(Zone.ALL, new DestroyTargetEffect());
|
||||
setTriggerPhrase("When you cast this spell and whenever {this} attacks, ");
|
||||
}
|
||||
|
||||
|
|
@ -96,33 +97,4 @@ class CityscapeLevelerAbility extends TriggeredAbilityImpl {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CityscapeLevelerEffect extends OneShotEffect {
|
||||
|
||||
public CityscapeLevelerEffect() {
|
||||
super(Outcome.DestroyPermanent);
|
||||
this.staticText = "destroy up to one target nonland permanent. Its controller creates a tapped Powerstone token.";
|
||||
}
|
||||
|
||||
private CityscapeLevelerEffect(final CityscapeLevelerEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CityscapeLevelerEffect copy() {
|
||||
return new CityscapeLevelerEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
UUID controllerId = permanent.getControllerId();
|
||||
permanent.destroy(source, game);
|
||||
new PowerstoneToken().putOntoBattlefield(1, game, source, controllerId, true, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +1,18 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.abilities.keyword.ChangelingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.CribSwapShapeshifterWhiteToken;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
|
@ -31,8 +27,8 @@ public final class CribSwap extends CardImpl {
|
|||
this.addAbility(new ChangelingAbility());
|
||||
// Exile target creature. Its controller creates a 1/1 colorless Shapeshifter creature token with changeling.
|
||||
this.getSpellAbility().addEffect(new ExileTargetEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new CribSwapShapeshifterWhiteToken()));
|
||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||
this.getSpellAbility().addEffect(new CribSwapEffect());
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -44,34 +40,4 @@ public final class CribSwap extends CardImpl {
|
|||
public CribSwap copy() {
|
||||
return new CribSwap(this);
|
||||
}
|
||||
}
|
||||
|
||||
class CribSwapEffect extends OneShotEffect {
|
||||
|
||||
public CribSwapEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Its controller creates a 1/1 colorless Shapeshifter creature token with changeling";
|
||||
}
|
||||
|
||||
public CribSwapEffect(final CribSwapEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CribSwapEffect copy() {
|
||||
return new CribSwapEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
Permanent targetCreature = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
|
||||
if (targetCreature != null) {
|
||||
CribSwapShapeshifterWhiteToken token = new CribSwapShapeshifterWhiteToken();
|
||||
return token.putOntoBattlefield(1, game, source, targetCreature.getControllerId());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +1,25 @@
|
|||
|
||||
package mage.cards.g;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.common.TapTargetCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenTargetEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.predicate.permanent.TappedPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.SpiritWhiteToken;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author noxx
|
||||
|
|
@ -38,10 +34,11 @@ public final class GallowsAtWillowHill extends CardImpl {
|
|||
}
|
||||
|
||||
public GallowsAtWillowHill(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
|
||||
|
||||
// {3}, {tap}, Tap three untapped Humans you control: Destroy target creature. Its controller creates a 1/1 white Spirit creature token with flying.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GallowsAtWillowHillEffect(), new GenericManaCost(3));
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new GenericManaCost(3));
|
||||
ability.addEffect(new CreateTokenControllerTargetPermanentEffect(new SpiritWhiteToken()));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addCost(new TapTargetCost(new TargetControlledPermanent(3, 3, humanFilter, false)));
|
||||
ability.addTarget(new TargetCreaturePermanent());
|
||||
|
|
@ -56,37 +53,4 @@ public final class GallowsAtWillowHill extends CardImpl {
|
|||
public GallowsAtWillowHill copy() {
|
||||
return new GallowsAtWillowHill(this);
|
||||
}
|
||||
}
|
||||
|
||||
class GallowsAtWillowHillEffect extends OneShotEffect {
|
||||
|
||||
public GallowsAtWillowHillEffect() {
|
||||
super(Outcome.DestroyPermanent);
|
||||
staticText = "Destroy target creature. Its controller creates a 1/1 white Spirit creature token with flying";
|
||||
}
|
||||
|
||||
public GallowsAtWillowHillEffect(final GallowsAtWillowHillEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GallowsAtWillowHillEffect copy() {
|
||||
return new GallowsAtWillowHillEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
|
||||
if (permanent != null) {
|
||||
Player controller = game.getPlayer(permanent.getControllerId());
|
||||
permanent.destroy(source, game, false);
|
||||
if (controller != null) {
|
||||
CreateTokenTargetEffect effect = new CreateTokenTargetEffect(new SpiritWhiteToken());
|
||||
effect.setTargetPointer(new FixedTarget(controller.getId()));
|
||||
effect.apply(game, source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +1,12 @@
|
|||
package mage.cards.g;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenTargetEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.ElephantToken;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -26,7 +19,8 @@ public final class GenerousGift extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}");
|
||||
|
||||
// Destroy target permanent. Its controller creates a 3/3 green Elephant creature token.
|
||||
this.getSpellAbility().addEffect(new GenerousGiftEffect());
|
||||
this.getSpellAbility().addEffect(new DestroyTargetEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new ElephantToken()));
|
||||
this.getSpellAbility().addTarget(new TargetPermanent());
|
||||
}
|
||||
|
||||
|
|
@ -38,37 +32,4 @@ public final class GenerousGift extends CardImpl {
|
|||
public GenerousGift copy() {
|
||||
return new GenerousGift(this);
|
||||
}
|
||||
}
|
||||
|
||||
class GenerousGiftEffect extends OneShotEffect {
|
||||
|
||||
GenerousGiftEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "Destroy target permanent. Its controller creates a 3/3 green Elephant creature token.";
|
||||
}
|
||||
|
||||
private GenerousGiftEffect(final GenerousGiftEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenerousGiftEffect copy() {
|
||||
return new GenerousGiftEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
Player player = game.getPlayer(permanent.getControllerId());
|
||||
permanent.destroy(source, game, false);
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
Effect effect = new CreateTokenTargetEffect(new ElephantToken());
|
||||
effect.setTargetPointer(new FixedTarget(player.getId(), game));
|
||||
return effect.apply(game, source);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +1,16 @@
|
|||
|
||||
package mage.cards.p;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.ApeToken;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author dustinconrad
|
||||
|
|
@ -25,7 +22,7 @@ public final class Pongify extends CardImpl {
|
|||
|
||||
// Destroy target creature. It can't be regenerated. That creature's controller creates a 3/3 green Ape creature token.
|
||||
this.getSpellAbility().addEffect(new DestroyTargetEffect(true));
|
||||
this.getSpellAbility().addEffect(new PongifyEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new ApeToken()));
|
||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||
}
|
||||
|
||||
|
|
@ -37,37 +34,4 @@ public final class Pongify extends CardImpl {
|
|||
public Pongify copy() {
|
||||
return new Pongify(this);
|
||||
}
|
||||
}
|
||||
|
||||
class PongifyEffect extends OneShotEffect {
|
||||
|
||||
public PongifyEffect() {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
this.staticText = "Its controller creates a 3/3 green Ape creature token";
|
||||
}
|
||||
|
||||
public PongifyEffect(final PongifyEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PongifyEffect copy() {
|
||||
return new PongifyEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
UUID targetId = getTargetPointer().getFirst(game, source);
|
||||
if (targetId != null) {
|
||||
Permanent permanent = game.getPermanentOrLKIBattlefield(targetId);
|
||||
if (permanent != null) {
|
||||
UUID controllerId = permanent.getControllerId();
|
||||
if (controllerId != null) {
|
||||
new ApeToken().putOntoBattlefield(1, game, source, controllerId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,13 @@
|
|||
package mage.cards.r;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.abilities.keyword.ForetellAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.BlueBirdToken;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
|
@ -26,7 +21,8 @@ public final class Ravenform extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}");
|
||||
|
||||
// Exile target artifact or creature. Its controller creates a 1/1 blue Bird creature token with flying.
|
||||
this.getSpellAbility().addEffect(new RavenformEffect());
|
||||
this.getSpellAbility().addEffect(new ExileTargetEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new BlueBirdToken()));
|
||||
this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE));
|
||||
|
||||
// Foretell {U}
|
||||
|
|
@ -41,34 +37,4 @@ public final class Ravenform extends CardImpl {
|
|||
public Ravenform copy() {
|
||||
return new Ravenform(this);
|
||||
}
|
||||
}
|
||||
|
||||
class RavenformEffect extends OneShotEffect {
|
||||
|
||||
RavenformEffect() {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
staticText = "Exile target artifact or creature. " +
|
||||
"Its controller creates a 1/1 blue Bird creature token with flying.";
|
||||
}
|
||||
|
||||
private RavenformEffect(final RavenformEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RavenformEffect copy() {
|
||||
return new RavenformEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
Player player = game.getPlayer(permanent.getControllerId());
|
||||
player.moveCards(permanent, Zone.EXILED, source, game);
|
||||
new BlueBirdToken().putOntoBattlefield(1, game, source, player.getId());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +1,12 @@
|
|||
package mage.cards.r;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.Spirit32Token;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetNonlandPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
|
@ -27,7 +22,8 @@ public final class ReduceToMemory extends CardImpl {
|
|||
this.subtype.add(SubType.LESSON);
|
||||
|
||||
// Exile target nonland permanent. Its controller creates a 3/2 red and white spirit creature token.
|
||||
this.getSpellAbility().addEffect(new ReduceToMemoryEffect());
|
||||
this.getSpellAbility().addEffect(new ExileTargetEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new Spirit32Token()));
|
||||
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
|
||||
}
|
||||
|
||||
|
|
@ -39,33 +35,4 @@ public final class ReduceToMemory extends CardImpl {
|
|||
public ReduceToMemory copy() {
|
||||
return new ReduceToMemory(this);
|
||||
}
|
||||
}
|
||||
|
||||
class ReduceToMemoryEffect extends OneShotEffect {
|
||||
|
||||
ReduceToMemoryEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "exile target nonland permanent. Its controller creates a 3/2 red and white Spirit creature token";
|
||||
}
|
||||
|
||||
private ReduceToMemoryEffect(final ReduceToMemoryEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReduceToMemoryEffect copy() {
|
||||
return new ReduceToMemoryEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
Player player = game.getPlayer(permanent.getControllerId());
|
||||
player.moveCards(permanent, Zone.EXILED, source, game);
|
||||
new Spirit32Token().putOntoBattlefield(1, game, source, player.getId());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +1,12 @@
|
|||
package mage.cards.r;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.Elemental44Token;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
|
@ -25,7 +20,8 @@ public final class Resculpt extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
|
||||
|
||||
// Exile target artifact or creature. Its controller creates a 4/4 blue and red Elemental creature token.
|
||||
this.getSpellAbility().addEffect(new ResculptEffect());
|
||||
this.getSpellAbility().addEffect(new ExileTargetEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new Elemental44Token()));
|
||||
this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE));
|
||||
}
|
||||
|
||||
|
|
@ -37,34 +33,4 @@ public final class Resculpt extends CardImpl {
|
|||
public Resculpt copy() {
|
||||
return new Resculpt(this);
|
||||
}
|
||||
}
|
||||
|
||||
class ResculptEffect extends OneShotEffect {
|
||||
|
||||
ResculptEffect() {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
staticText = "Exile target artifact or creature. " +
|
||||
"Its controller creates a 4/4 blue and red Elemental creature token";
|
||||
}
|
||||
|
||||
private ResculptEffect(final ResculptEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResculptEffect copy() {
|
||||
return new ResculptEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getFirstTarget());
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
Player player = game.getPlayer(permanent.getControllerId());
|
||||
player.moveCards(permanent, Zone.EXILED, source, game);
|
||||
new Elemental44Token().putOntoBattlefield(1, game, source, player.getId());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,9 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.common.MutatesSourceTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenTargetEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.abilities.keyword.MutateAbility;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
|
@ -49,7 +51,8 @@ public final class SawtuskDemolisher extends CardImpl {
|
|||
this.addAbility(TrampleAbility.getInstance());
|
||||
|
||||
// Whenever this creature mutates, destroy target noncreature permanent. Its controller creates a 3/3 green Beast creature token.
|
||||
Ability ability = new MutatesSourceTriggeredAbility(new SawtuskDemolisherEffect());
|
||||
Ability ability = new MutatesSourceTriggeredAbility(new DestroyTargetEffect());
|
||||
ability.addEffect(new CreateTokenControllerTargetPermanentEffect(new BeastToken()));
|
||||
ability.addTarget(new TargetPermanent(filter));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,11 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.SoldierToken;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.target.common.TargetNonlandPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
|
@ -25,7 +20,7 @@ public final class SecureTheScene extends CardImpl {
|
|||
|
||||
// Exile target nonland permanent. Its controller creates a 1/1 white Soldier creature token.
|
||||
this.getSpellAbility().addEffect(new ExileTargetEffect());
|
||||
this.getSpellAbility().addEffect(new SecureTheSceneEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new SoldierToken()));
|
||||
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
|
||||
}
|
||||
|
||||
|
|
@ -37,32 +32,4 @@ public final class SecureTheScene extends CardImpl {
|
|||
public SecureTheScene copy() {
|
||||
return new SecureTheScene(this);
|
||||
}
|
||||
}
|
||||
|
||||
class SecureTheSceneEffect extends OneShotEffect {
|
||||
|
||||
private static final Token token = new SoldierToken();
|
||||
|
||||
SecureTheSceneEffect() {
|
||||
super(Outcome.PutCreatureInPlay);
|
||||
this.staticText = "Its controller creates a 1/1 white Soldier creature token";
|
||||
}
|
||||
|
||||
private SecureTheSceneEffect(final SecureTheSceneEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecureTheSceneEffect copy() {
|
||||
return new SecureTheSceneEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
return token.putOntoBattlefield(1, game, source, permanent.getControllerId());
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Mage.Sets/src/mage/cards/s/StrokeOfMidnight.java
Normal file
36
Mage.Sets/src/mage/cards/s/StrokeOfMidnight.java
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.game.permanent.token.HumanToken;
|
||||
import mage.target.common.TargetNonlandPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author Susucr
|
||||
*/
|
||||
public final class StrokeOfMidnight extends CardImpl {
|
||||
|
||||
public StrokeOfMidnight(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}");
|
||||
|
||||
|
||||
// Destroy target nonland permanent. Its controller creates a 1/1 white Human creature token.
|
||||
this.getSpellAbility().addEffect(new DestroyTargetEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new HumanToken()));
|
||||
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
|
||||
}
|
||||
|
||||
private StrokeOfMidnight(final StrokeOfMidnight card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StrokeOfMidnight copy() {
|
||||
return new StrokeOfMidnight(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +1,23 @@
|
|||
package mage.cards.t;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
|
||||
import mage.abilities.common.EntersBattlefieldAbility;
|
||||
import mage.abilities.costs.common.RemoveCountersSourceCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenTargetEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.OxToken;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -42,9 +37,10 @@ public final class TransmogrifyingWand extends CardImpl {
|
|||
// {1}, {T}, Remove a charge counter from Transmogrifying Wand: Destroy target creature. Its controller creates a 2/4 white Ox creature token. Activate this ability only any time you could cast a sorcery.
|
||||
Ability ability = new ActivateAsSorceryActivatedAbility(
|
||||
Zone.BATTLEFIELD,
|
||||
new TransmogrifyingWandEffect(),
|
||||
new DestroyTargetEffect(),
|
||||
new GenericManaCost(1)
|
||||
);
|
||||
ability.addEffect(new CreateTokenControllerTargetPermanentEffect(new OxToken()));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addCost(new RemoveCountersSourceCost(CounterType.CHARGE.createInstance()));
|
||||
ability.addTarget(new TargetCreaturePermanent());
|
||||
|
|
@ -59,33 +55,4 @@ public final class TransmogrifyingWand extends CardImpl {
|
|||
public TransmogrifyingWand copy() {
|
||||
return new TransmogrifyingWand(this);
|
||||
}
|
||||
}
|
||||
|
||||
class TransmogrifyingWandEffect extends OneShotEffect {
|
||||
|
||||
public TransmogrifyingWandEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Destroy target creature. Its controller creates a 2/4 white Ox creature token.";
|
||||
}
|
||||
|
||||
public TransmogrifyingWandEffect(final TransmogrifyingWandEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransmogrifyingWandEffect copy() {
|
||||
return new TransmogrifyingWandEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent creature = game.getPermanent(source.getFirstTarget());
|
||||
if (creature == null) {
|
||||
return false;
|
||||
}
|
||||
Effect effect = new CreateTokenTargetEffect(new OxToken());
|
||||
effect.setTargetPointer(new FixedTarget(creature.getControllerId(), game));
|
||||
new DestroyTargetEffect().apply(game, source);
|
||||
return effect.apply(game, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -88,6 +88,7 @@ public final class WildsOfEldraine extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Sharae of Numbing Depths", 213, Rarity.UNCOMMON, mage.cards.s.SharaeOfNumbingDepths.class));
|
||||
cards.add(new SetCardInfo("Skybeast Tracker", 185, Rarity.COMMON, mage.cards.s.SkybeastTracker.class));
|
||||
cards.add(new SetCardInfo("Sleight of Hand", 67, Rarity.COMMON, mage.cards.s.SleightOfHand.class));
|
||||
cards.add(new SetCardInfo("Stroke of Midnight", 33, Rarity.UNCOMMON, mage.cards.s.StrokeOfMidnight.class));
|
||||
cards.add(new SetCardInfo("Soul-Guide Lantern", 251, Rarity.UNCOMMON, mage.cards.s.SoulGuideLantern.class));
|
||||
cards.add(new SetCardInfo("Spellbook Vendor", 31, Rarity.RARE, mage.cards.s.SpellbookVendor.class));
|
||||
cards.add(new SetCardInfo("Spiteful Hexmage", 108, Rarity.RARE, mage.cards.s.SpitefulHexmage.class));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
package org.mage.test.cards.single.woe;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author Susucr
|
||||
*/
|
||||
public class StrokeOfMidnightTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* Stroke of Midnight
|
||||
* {2}{W}
|
||||
* Instant
|
||||
* <p>
|
||||
* Destroy target nonland permanent. Its controller creates a 1/1 white Human creature token.
|
||||
*/
|
||||
private static final String stroke = "Stroke of Midnight";
|
||||
|
||||
// Indestructible permanent. Should still give a token.
|
||||
private static final String relic = "Darksteel Relic";
|
||||
|
||||
// 2/1 creature
|
||||
private static final String piker = "Goblin Piker";
|
||||
|
||||
@Test
|
||||
public void destroyOpponentPermanent() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.HAND, playerA, stroke);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerB, piker);
|
||||
|
||||
castSpell(1, PhaseStep.UPKEEP, playerA, stroke, piker);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerB, piker, 0);
|
||||
assertGraveyardCount(playerB, piker, 1);
|
||||
assertTokenCount(playerB, "Human Token", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void destroyOwnPermanent() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.HAND, playerA, stroke);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, piker);
|
||||
|
||||
castSpell(1, PhaseStep.UPKEEP, playerA, stroke, piker);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, piker, 0);
|
||||
assertGraveyardCount(playerA, piker, 1);
|
||||
assertTokenCount(playerA, "Human Token", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void indestructiblePermanent() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.HAND, playerA, stroke);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerB, relic);
|
||||
|
||||
castSpell(1, PhaseStep.UPKEEP, playerA, stroke, relic);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerB, relic, 1);
|
||||
assertTokenCount(playerB, "Human Token", 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
package mage.abilities.effects.common;
|
||||
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
* @Author Susucr
|
||||
* <p>
|
||||
* Have the Controller of target permanent (or LKI controller) create Tokens.
|
||||
*/
|
||||
public class CreateTokenControllerTargetPermanentEffect extends OneShotEffect {
|
||||
private final Token token;
|
||||
private final DynamicValue amount;
|
||||
private final boolean tapped;
|
||||
private final boolean attacking;
|
||||
|
||||
public CreateTokenControllerTargetPermanentEffect(Token token) {
|
||||
this(token, StaticValue.get(1));
|
||||
}
|
||||
|
||||
public CreateTokenControllerTargetPermanentEffect(Token token, int amount) {
|
||||
this(token, StaticValue.get(amount));
|
||||
}
|
||||
|
||||
public CreateTokenControllerTargetPermanentEffect(Token token, DynamicValue amount) {
|
||||
this(token, amount, false, false);
|
||||
}
|
||||
|
||||
public CreateTokenControllerTargetPermanentEffect(Token token, int amount, boolean tapped) {
|
||||
this(token, amount, tapped, false);
|
||||
}
|
||||
|
||||
public CreateTokenControllerTargetPermanentEffect(Token token, int amount, boolean tapped, boolean attacking) {
|
||||
this(token, StaticValue.get(amount), tapped, attacking);
|
||||
}
|
||||
|
||||
public CreateTokenControllerTargetPermanentEffect(Token token, DynamicValue amount, boolean tapped, boolean attacking) {
|
||||
super(Outcome.Neutral);
|
||||
this.token = token;
|
||||
this.amount = amount.copy();
|
||||
this.tapped = tapped;
|
||||
this.attacking = attacking;
|
||||
this.staticText = setText();
|
||||
}
|
||||
|
||||
protected CreateTokenControllerTargetPermanentEffect(final CreateTokenControllerTargetPermanentEffect effect) {
|
||||
super(effect);
|
||||
this.token = effect.token.copy();
|
||||
this.amount = effect.amount.copy();
|
||||
this.tapped = effect.tapped;
|
||||
this.attacking = effect.attacking;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateTokenControllerTargetPermanentEffect copy() {
|
||||
return new CreateTokenControllerTargetPermanentEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent creature = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
|
||||
if (creature != null) {
|
||||
Player controllerOfTarget = game.getPlayer(creature.getControllerId());
|
||||
if (controllerOfTarget != null) {
|
||||
int value = amount.calculate(game, source, this);
|
||||
return token.putOntoBattlefield(value, game, source, controllerOfTarget.getId(), tapped, attacking);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String setText() {
|
||||
String text = "Its controller creates ";
|
||||
|
||||
if (token.getDescription().contains(", a legendary")) {
|
||||
text += token.getDescription();
|
||||
return text;
|
||||
}
|
||||
|
||||
if (amount.toString().equals("1")) {
|
||||
if (tapped && !attacking) {
|
||||
text += "a tapped " + token.getDescription();
|
||||
} else {
|
||||
text += CardUtil.addArticle(token.getDescription());
|
||||
}
|
||||
} else {
|
||||
text += CardUtil.numberToText(amount.toString()) + " ";
|
||||
if (tapped && !attacking) {
|
||||
text += "tapped ";
|
||||
}
|
||||
text += token.getDescription().replace("token. It has", "tokens. They have");
|
||||
if (token.getDescription().endsWith("token")) {
|
||||
text += "s";
|
||||
}
|
||||
text.replace("token ", "tokens ");
|
||||
}
|
||||
|
||||
if (attacking) {
|
||||
if (amount.toString().equals("1")) {
|
||||
text += " that's";
|
||||
} else {
|
||||
text += " that are";
|
||||
}
|
||||
if (tapped) {
|
||||
text += " tapped and";
|
||||
}
|
||||
text += " attacking";
|
||||
}
|
||||
|
||||
String message = amount.getMessage();
|
||||
if (!message.isEmpty()) {
|
||||
if (amount.toString().equals("X")) {
|
||||
text += ", where X is ";
|
||||
} else {
|
||||
text += " for each ";
|
||||
}
|
||||
}
|
||||
text += message;
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue