mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 21:29:17 -08:00
implement [MH3] Strix Serenade ; refactor similar effects with Pongify effect
Slight refactor for Serenade, Swan Song and An Offer You Can't Refuse to use the shared class (formely for Permanents only) for Pongify kind of effects.
This commit is contained in:
parent
381104bd92
commit
e3e34dae33
27 changed files with 230 additions and 139 deletions
|
|
@ -1,6 +1,6 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -11,7 +11,6 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Backfir3
|
||||
*/
|
||||
public final class Afterlife extends CardImpl {
|
||||
|
|
@ -23,7 +22,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 CreateTokenControllerTargetPermanentEffect(new SpiritWhiteToken()));
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(new SpiritWhiteToken()));
|
||||
}
|
||||
|
||||
private Afterlife(final Afterlife card) {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,12 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CounterTargetEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.token.TreasureToken;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.target.TargetSpell;
|
||||
|
||||
import java.util.UUID;
|
||||
|
|
@ -23,7 +20,10 @@ public final class AnOfferYouCantRefuse extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}");
|
||||
|
||||
// Counter target noncreature spell. Its controller creates two Treasure tokens.
|
||||
this.getSpellAbility().addEffect(new AnOfferYouCantRefuseEffect());
|
||||
this.getSpellAbility().addEffect(new CounterTargetEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(
|
||||
new TreasureToken(), 2, false, CreateTokenControllerTargetEffect.TargetKind.SPELL
|
||||
));
|
||||
this.getSpellAbility().addTarget(new TargetSpell(StaticFilters.FILTER_SPELL_NON_CREATURE));
|
||||
}
|
||||
|
||||
|
|
@ -35,32 +35,4 @@ public final class AnOfferYouCantRefuse extends CardImpl {
|
|||
public AnOfferYouCantRefuse copy() {
|
||||
return new AnOfferYouCantRefuse(this);
|
||||
}
|
||||
}
|
||||
|
||||
class AnOfferYouCantRefuseEffect extends OneShotEffect {
|
||||
|
||||
AnOfferYouCantRefuseEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "counter target noncreature spell. Its controller creates two Treasure tokens";
|
||||
}
|
||||
|
||||
private AnOfferYouCantRefuseEffect(final AnOfferYouCantRefuseEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnOfferYouCantRefuseEffect copy() {
|
||||
return new AnOfferYouCantRefuseEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Spell spell = game.getSpell(getTargetPointer().getFirst(game, source));
|
||||
if (spell == null) {
|
||||
return false;
|
||||
}
|
||||
game.getStack().counter(spell.getId(), source, game);;
|
||||
new TreasureToken().putOntoBattlefield(2, game, source, spell.getControllerId());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -20,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 CreateTokenControllerTargetPermanentEffect(new AngelToken()));
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(new AngelToken()));
|
||||
this.getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -21,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 CreateTokenControllerTargetPermanentEffect(new BeastToken()));
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(new BeastToken()));
|
||||
}
|
||||
|
||||
private BeastWithin(final BeastWithin card) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -22,7 +22,7 @@ public final class BovineIntervention extends CardImpl {
|
|||
// Destroy target artifact or creature. Its controller creates a 2/2 white Ox creature token.
|
||||
this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE));
|
||||
this.getSpellAbility().addEffect(new DestroyTargetEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new Ox22Token()));
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(new Ox22Token()));
|
||||
}
|
||||
|
||||
private BovineIntervention(final BovineIntervention card) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -20,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 CreateTokenControllerTargetPermanentEffect(new TreasureToken()));
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(new TreasureToken()));
|
||||
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import mage.MageInt;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.DiesSourceTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
|
||||
import mage.abilities.keyword.VigilanceAbility;
|
||||
|
|
@ -41,7 +41,7 @@ public final class CavalierOfDawn extends CardImpl {
|
|||
|
||||
// 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 DestroyTargetEffect());
|
||||
ability.addEffect(new CreateTokenControllerTargetPermanentEffect(new GolemToken()));
|
||||
ability.addEffect(new CreateTokenControllerTargetEffect(new GolemToken()));
|
||||
ability.addTarget(new TargetNonlandPermanent(0, 1, false));
|
||||
this.addAbility(ability);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import mage.MageInt;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.abilities.keyword.UnearthAbility;
|
||||
|
|
@ -21,7 +21,6 @@ import mage.target.common.TargetNonlandPermanent;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author weirddan455
|
||||
*/
|
||||
public final class CityscapeLeveler extends CardImpl {
|
||||
|
|
@ -38,7 +37,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.addEffect(new CreateTokenControllerTargetEffect(new PowerstoneToken(), 1, true));
|
||||
ability.addTarget(new TargetNonlandPermanent(0, 1));
|
||||
this.addAbility(ability);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import java.util.UUID;
|
|||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
|
|
@ -43,7 +43,7 @@ public final class CommanderSofiaDaguerre extends CardImpl {
|
|||
// Crash Landing -- When Commander Sofia Daguerre enters the battlefield,
|
||||
// destroy up to one target legendary permanent. That permanent's controller creates a Junk token.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect());
|
||||
ability.addEffect(new CreateTokenControllerTargetPermanentEffect(new JunkToken())
|
||||
ability.addEffect(new CreateTokenControllerTargetEffect(new JunkToken())
|
||||
.setText("that permanent's controller creates a Junk token"));
|
||||
ability.addTarget(new TargetPermanent(0, 1, filter));
|
||||
this.addAbility(ability.withFlavorWord("Crash Landing"));
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.abilities.keyword.ChangelingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
|
@ -14,7 +14,6 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class CribSwap extends CardImpl {
|
||||
|
|
@ -27,7 +26,7 @@ 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().addEffect(new CreateTokenControllerTargetEffect(new CribSwapShapeshifterWhiteToken()));
|
||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ 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.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -38,7 +38,7 @@ public final class GallowsAtWillowHill extends CardImpl {
|
|||
|
||||
// {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 DestroyTargetEffect(), new GenericManaCost(3));
|
||||
ability.addEffect(new CreateTokenControllerTargetPermanentEffect(new SpiritWhiteToken()));
|
||||
ability.addEffect(new CreateTokenControllerTargetEffect(new SpiritWhiteToken()));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addCost(new TapTargetCost(new TargetControlledPermanent(3, 3, humanFilter, false)));
|
||||
ability.addTarget(new TargetCreaturePermanent());
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package mage.cards.g;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -20,7 +20,7 @@ public final class GenerousGift extends CardImpl {
|
|||
|
||||
// Destroy target permanent. Its controller creates a 3/3 green Elephant creature token.
|
||||
this.getSpellAbility().addEffect(new DestroyTargetEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new ElephantToken()));
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(new ElephantToken()));
|
||||
this.getSpellAbility().addTarget(new TargetPermanent());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package mage.cards.g;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -32,7 +32,7 @@ public final class GetLost extends CardImpl {
|
|||
|
||||
// Destroy target creature, enchantment, or planeswalker. Its controller creates two Map tokens.
|
||||
this.getSpellAbility().addEffect(new DestroyTargetEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new MapToken(), 2, false));
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(new MapToken(), 2, false));
|
||||
this.getSpellAbility().addTarget(new TargetPermanent(filter));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
package mage.cards.p;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -12,7 +12,6 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author dustinconrad
|
||||
*/
|
||||
public final class Pongify extends CardImpl {
|
||||
|
|
@ -22,7 +21,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 CreateTokenControllerTargetPermanentEffect(new ApeToken()));
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(new ApeToken()));
|
||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package mage.cards.r;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.abilities.keyword.ForetellAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
|
@ -22,7 +22,7 @@ public final class Ravenform extends CardImpl {
|
|||
|
||||
// Exile target artifact or creature. Its controller creates a 1/1 blue Bird creature token with flying.
|
||||
this.getSpellAbility().addEffect(new ExileTargetEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new BlueBirdToken()));
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(new BlueBirdToken()));
|
||||
this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE));
|
||||
|
||||
// Foretell {U}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package mage.cards.r;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -23,7 +23,7 @@ public final class ReduceToMemory extends CardImpl {
|
|||
|
||||
// Exile target nonland permanent. Its controller creates a 3/2 red and white spirit creature token.
|
||||
this.getSpellAbility().addEffect(new ExileTargetEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new Spirit32Token()));
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(new Spirit32Token()));
|
||||
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package mage.cards.r;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -21,7 +21,7 @@ public final class Resculpt extends CardImpl {
|
|||
|
||||
// Exile target artifact or creature. Its controller creates a 4/4 blue and red Elemental creature token.
|
||||
this.getSpellAbility().addEffect(new ExileTargetEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetPermanentEffect(new Elemental44Token()));
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(new Elemental44Token()));
|
||||
this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ 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.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.CreateTokenTargetEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.abilities.keyword.MutateAbility;
|
||||
|
|
@ -52,7 +52,7 @@ public final class SawtuskDemolisher extends CardImpl {
|
|||
|
||||
// Whenever this creature mutates, destroy target noncreature permanent. Its controller creates a 3/3 green Beast creature token.
|
||||
Ability ability = new MutatesSourceTriggeredAbility(new DestroyTargetEffect());
|
||||
ability.addEffect(new CreateTokenControllerTargetPermanentEffect(new BeastToken()));
|
||||
ability.addEffect(new CreateTokenControllerTargetEffect(new BeastToken()));
|
||||
ability.addTarget(new TargetPermanent(filter));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -20,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 CreateTokenControllerTargetPermanentEffect(new SoldierToken()));
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(new SoldierToken()));
|
||||
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
|
||||
}
|
||||
|
||||
|
|
|
|||
49
Mage.Sets/src/mage/cards/s/StrixSerenade.java
Normal file
49
Mage.Sets/src/mage/cards/s/StrixSerenade.java
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import mage.abilities.effects.common.CounterTargetEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.filter.FilterSpell;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.permanent.token.SwanSongBirdToken;
|
||||
import mage.target.TargetSpell;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author Susucr
|
||||
*/
|
||||
public final class StrixSerenade extends CardImpl {
|
||||
|
||||
private static final FilterSpell filter = new FilterSpell("artifact, creature, or planeswalker spell");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.or(
|
||||
CardType.ARTIFACT.getPredicate(),
|
||||
CardType.CREATURE.getPredicate(),
|
||||
CardType.PLANESWALKER.getPredicate()
|
||||
));
|
||||
}
|
||||
|
||||
public StrixSerenade(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}");
|
||||
|
||||
// Counter target artifact, creature, or planeswalker spell. Its controller creates a 2/2 blue Bird creature token with flying.
|
||||
this.getSpellAbility().addEffect(new CounterTargetEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(
|
||||
new SwanSongBirdToken(), CreateTokenControllerTargetEffect.TargetKind.SPELL
|
||||
));
|
||||
this.getSpellAbility().addTarget(new TargetSpell(filter));
|
||||
}
|
||||
|
||||
private StrixSerenade(final StrixSerenade card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StrixSerenade copy() {
|
||||
return new StrixSerenade(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -21,7 +21,7 @@ public final class StrokeOfMidnight extends CardImpl {
|
|||
|
||||
// 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().addEffect(new CreateTokenControllerTargetEffect(new HumanToken()));
|
||||
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,19 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CounterTargetEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.FilterSpell;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.token.SwanSongBirdToken;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.target.TargetSpell;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class SwanSong extends CardImpl {
|
||||
|
|
@ -25,16 +21,21 @@ public final class SwanSong extends CardImpl {
|
|||
private static final FilterSpell filter = new FilterSpell("enchantment, instant, or sorcery spell");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.or(CardType.ENCHANTMENT.getPredicate(),
|
||||
filter.add(Predicates.or(
|
||||
CardType.ENCHANTMENT.getPredicate(),
|
||||
CardType.INSTANT.getPredicate(),
|
||||
CardType.SORCERY.getPredicate()));
|
||||
CardType.SORCERY.getPredicate()
|
||||
));
|
||||
}
|
||||
|
||||
public SwanSong(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}");
|
||||
|
||||
// Counter target enchantment, instant or sorcery spell. Its controller creates a 2/2 blue Bird creature token with flying.
|
||||
this.getSpellAbility().addEffect(new SwanSongEffect());
|
||||
this.getSpellAbility().addEffect(new CounterTargetEffect());
|
||||
this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(
|
||||
new SwanSongBirdToken(), CreateTokenControllerTargetEffect.TargetKind.SPELL
|
||||
));
|
||||
this.getSpellAbility().addTarget(new TargetSpell(filter));
|
||||
}
|
||||
|
||||
|
|
@ -46,37 +47,4 @@ public final class SwanSong extends CardImpl {
|
|||
public SwanSong copy() {
|
||||
return new SwanSong(this);
|
||||
}
|
||||
}
|
||||
|
||||
class SwanSongEffect extends OneShotEffect {
|
||||
|
||||
SwanSongEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Counter target enchantment, instant, or sorcery spell. Its controller creates a 2/2 blue Bird creature token with flying";
|
||||
}
|
||||
|
||||
private SwanSongEffect(final SwanSongEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SwanSongEffect copy() {
|
||||
return new SwanSongEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
boolean countered = false;
|
||||
for (UUID targetId : getTargetPointer().getTargets(game, source)) {
|
||||
Spell spell = game.getStack().getSpell(targetId);
|
||||
if (game.getStack().counter(targetId, source, game)) {
|
||||
countered = true;
|
||||
}
|
||||
if (spell != null) {
|
||||
Token token = new SwanSongBirdToken();
|
||||
token.putOntoBattlefield(1, game, source, spell.getControllerId());
|
||||
}
|
||||
}
|
||||
return countered;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ 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.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
|
|
@ -20,7 +20,6 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class TransmogrifyingWand extends CardImpl {
|
||||
|
|
@ -40,7 +39,7 @@ public final class TransmogrifyingWand extends CardImpl {
|
|||
new DestroyTargetEffect(),
|
||||
new GenericManaCost(1)
|
||||
);
|
||||
ability.addEffect(new CreateTokenControllerTargetPermanentEffect(new OxToken()));
|
||||
ability.addEffect(new CreateTokenControllerTargetEffect(new OxToken()));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addCost(new RemoveCountersSourceCost(CounterType.CHARGE.createInstance()));
|
||||
ability.addTarget(new TargetCreaturePermanent());
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import mage.MageInt;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.TurnedFaceUpSourceTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetPermanentEffect;
|
||||
import mage.abilities.effects.common.CreateTokenControllerTargetEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.abilities.effects.common.ExileThenReturnTargetEffect;
|
||||
import mage.constants.Outcome;
|
||||
|
|
@ -89,7 +89,7 @@ class UnyieldingGatekeeperEffect extends OneShotEffect {
|
|||
false, false, PutCards.BATTLEFIELD_TAPPED).apply(game, source);
|
||||
} else {
|
||||
new ExileTargetEffect().apply(game, source);
|
||||
new CreateTokenControllerTargetPermanentEffect(new DetectiveToken()).apply(game, source);
|
||||
new CreateTokenControllerTargetEffect(new DetectiveToken()).apply(game, source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ public final class ModernHorizons3 extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Sorin, Ravenous Neonate", 245, Rarity.MYTHIC, mage.cards.s.SorinRavenousNeonate.class));
|
||||
cards.add(new SetCardInfo("Spawn-Gang Commander", 140, Rarity.UNCOMMON, mage.cards.s.SpawnGangCommander.class));
|
||||
cards.add(new SetCardInfo("Strength of the Harvest", 258, Rarity.UNCOMMON, mage.cards.s.StrengthOfTheHarvest.class));
|
||||
cards.add(new SetCardInfo("Strix Serenade", 71, Rarity.RARE, mage.cards.s.StrixSerenade.class));
|
||||
cards.add(new SetCardInfo("Stump Stomp", 259, Rarity.UNCOMMON, mage.cards.s.StumpStomp.class));
|
||||
cards.add(new SetCardInfo("Suppression Ray", 260, Rarity.UNCOMMON, mage.cards.s.SuppressionRay.class));
|
||||
cards.add(new SetCardInfo("Swamp", 306, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
package org.mage.test.cards.single.mh3;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author Susucr
|
||||
*/
|
||||
public class StrixSerenadeTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* {@link mage.cards.s.StrixSerenade Strix Serenade} {U}
|
||||
* Instant
|
||||
* Counter target artifact, creature, or planeswalker spell. Its controller creates a 2/2 blue Bird creature token with flying.
|
||||
*/
|
||||
private static final String serenade = "Strix Serenade";
|
||||
|
||||
@Test
|
||||
public void test_Simple() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||
addCard(Zone.HAND, playerA, serenade);
|
||||
addCard(Zone.HAND, playerB, "Mox Ruby");
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Mox Ruby");
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, serenade, "Mox Ruby", "Mox Ruby");
|
||||
|
||||
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, "Mox Ruby", 1);
|
||||
assertPermanentCount(playerB, "Bird Token", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_Simple_OwnSpellTargetted() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||
addCard(Zone.HAND, playerA, serenade);
|
||||
addCard(Zone.HAND, playerA, "Mox Ruby");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mox Ruby");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, serenade, "Mox Ruby", "Mox Ruby");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Mox Ruby", 1);
|
||||
assertPermanentCount(playerA, "Bird Token", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CantBeCountered_CreateToken() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||
addCard(Zone.HAND, playerA, serenade);
|
||||
addCard(Zone.HAND, playerB, "Chandra, Awakened Inferno"); // Can't be countered
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 6);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Chandra, Awakened Inferno");
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, serenade, "Chandra, Awakened Inferno", "Chandra, Awakened Inferno");
|
||||
|
||||
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerB, "Chandra, Awakened Inferno", 1);
|
||||
assertPermanentCount(playerB, "Bird Token", 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,8 +5,8 @@ import mage.abilities.dynamicvalue.DynamicValue;
|
|||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Controllable;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
|
@ -14,46 +14,78 @@ import mage.util.CardUtil;
|
|||
/**
|
||||
* @author Susucr
|
||||
* <p>
|
||||
* Have the Controller of target permanent (or LKI controller) create Tokens.
|
||||
* Have the Controller of target object (permanent, or spell) create Tokens.
|
||||
*/
|
||||
public class CreateTokenControllerTargetPermanentEffect extends OneShotEffect {
|
||||
public class CreateTokenControllerTargetEffect extends OneShotEffect {
|
||||
private final Token token;
|
||||
private final DynamicValue amount;
|
||||
private final boolean tapped;
|
||||
|
||||
public CreateTokenControllerTargetPermanentEffect(Token token) {
|
||||
/**
|
||||
* What the target is supposed to be, to retrieve its controller from
|
||||
*/
|
||||
public enum TargetKind {
|
||||
PERMANENT,
|
||||
SPELL
|
||||
}
|
||||
|
||||
private final TargetKind targetKind;
|
||||
|
||||
public CreateTokenControllerTargetEffect(Token token) {
|
||||
this(token, 1, false);
|
||||
}
|
||||
|
||||
public CreateTokenControllerTargetPermanentEffect(Token token, int amount, boolean tapped) {
|
||||
public CreateTokenControllerTargetEffect(Token token, TargetKind targetKind) {
|
||||
this(token, 1, false, targetKind);
|
||||
}
|
||||
|
||||
public CreateTokenControllerTargetEffect(Token token, int amount, boolean tapped) {
|
||||
this(token, StaticValue.get(amount), tapped);
|
||||
}
|
||||
|
||||
public CreateTokenControllerTargetPermanentEffect(Token token, DynamicValue amount, boolean tapped) {
|
||||
public CreateTokenControllerTargetEffect(Token token, int amount, boolean tapped, TargetKind targetKind) {
|
||||
this(token, StaticValue.get(amount), tapped, targetKind);
|
||||
}
|
||||
|
||||
public CreateTokenControllerTargetEffect(Token token, DynamicValue amount, boolean tapped) {
|
||||
this(token, amount, tapped, TargetKind.PERMANENT);
|
||||
}
|
||||
|
||||
public CreateTokenControllerTargetEffect(Token token, DynamicValue amount, boolean tapped, TargetKind targetKind) {
|
||||
super(Outcome.Neutral);
|
||||
this.token = token;
|
||||
this.amount = amount.copy();
|
||||
this.tapped = tapped;
|
||||
this.staticText = makeText();
|
||||
this.targetKind = targetKind;
|
||||
}
|
||||
|
||||
protected CreateTokenControllerTargetPermanentEffect(final CreateTokenControllerTargetPermanentEffect effect) {
|
||||
protected CreateTokenControllerTargetEffect(final CreateTokenControllerTargetEffect effect) {
|
||||
super(effect);
|
||||
this.token = effect.token.copy();
|
||||
this.amount = effect.amount.copy();
|
||||
this.tapped = effect.tapped;
|
||||
this.targetKind = effect.targetKind;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateTokenControllerTargetPermanentEffect copy() {
|
||||
return new CreateTokenControllerTargetPermanentEffect(this);
|
||||
public CreateTokenControllerTargetEffect copy() {
|
||||
return new CreateTokenControllerTargetEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
|
||||
if (permanent != null) {
|
||||
Player controllerOfTarget = game.getPlayer(permanent.getControllerId());
|
||||
Controllable controllable = null;
|
||||
switch (targetKind) {
|
||||
case PERMANENT:
|
||||
controllable = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
|
||||
break;
|
||||
case SPELL:
|
||||
controllable = game.getSpellOrLKIStack(getTargetPointer().getFirst(game, source));
|
||||
break;
|
||||
}
|
||||
if (controllable != null) {
|
||||
Player controllerOfTarget = game.getPlayer(controllable.getControllerId());
|
||||
if (controllerOfTarget != null) {
|
||||
int value = amount.calculate(game, source, this);
|
||||
return token.putOntoBattlefield(value, game, source, controllerOfTarget.getId(), tapped, false);
|
||||
Loading…
Add table
Add a link
Reference in a new issue