diff --git a/Mage.Sets/src/mage/cards/a/Afterlife.java b/Mage.Sets/src/mage/cards/a/Afterlife.java index 2278fda48a0..8a22501935e 100644 --- a/Mage.Sets/src/mage/cards/a/Afterlife.java +++ b/Mage.Sets/src/mage/cards/a/Afterlife.java @@ -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; - } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/a/AngelicAscension.java b/Mage.Sets/src/mage/cards/a/AngelicAscension.java index baacb62b570..d7daae4e405 100644 --- a/Mage.Sets/src/mage/cards/a/AngelicAscension.java +++ b/Mage.Sets/src/mage/cards/a/AngelicAscension.java @@ -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()); - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/b/BeastWithin.java b/Mage.Sets/src/mage/cards/b/BeastWithin.java index 2d4e771bd6b..375b0b29d48 100644 --- a/Mage.Sets/src/mage/cards/b/BeastWithin.java +++ b/Mage.Sets/src/mage/cards/b/BeastWithin.java @@ -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; - } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/b/BuyYourSilence.java b/Mage.Sets/src/mage/cards/b/BuyYourSilence.java index 8b56d346ba1..5a0d1b44a0b 100644 --- a/Mage.Sets/src/mage/cards/b/BuyYourSilence.java +++ b/Mage.Sets/src/mage/cards/b/BuyYourSilence.java @@ -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()); - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/c/CavalierOfDawn.java b/Mage.Sets/src/mage/cards/c/CavalierOfDawn.java index 943d249e3e1..4f0de762380 100644 --- a/Mage.Sets/src/mage/cards/c/CavalierOfDawn.java +++ b/Mage.Sets/src/mage/cards/c/CavalierOfDawn.java @@ -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); - } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/c/CityscapeLeveler.java b/Mage.Sets/src/mage/cards/c/CityscapeLeveler.java index d9b7e97aa1a..4bf871910d1 100644 --- a/Mage.Sets/src/mage/cards/c/CityscapeLeveler.java +++ b/Mage.Sets/src/mage/cards/c/CityscapeLeveler.java @@ -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; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/c/CribSwap.java b/Mage.Sets/src/mage/cards/c/CribSwap.java index 08a4d3b3bf8..3c8bfe176c4 100644 --- a/Mage.Sets/src/mage/cards/c/CribSwap.java +++ b/Mage.Sets/src/mage/cards/c/CribSwap.java @@ -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; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GallowsAtWillowHill.java b/Mage.Sets/src/mage/cards/g/GallowsAtWillowHill.java index e290d9637fd..68a6c79e46f 100644 --- a/Mage.Sets/src/mage/cards/g/GallowsAtWillowHill.java +++ b/Mage.Sets/src/mage/cards/g/GallowsAtWillowHill.java @@ -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; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GenerousGift.java b/Mage.Sets/src/mage/cards/g/GenerousGift.java index 52ee004c88a..2cc56d5068b 100644 --- a/Mage.Sets/src/mage/cards/g/GenerousGift.java +++ b/Mage.Sets/src/mage/cards/g/GenerousGift.java @@ -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); - } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/p/Pongify.java b/Mage.Sets/src/mage/cards/p/Pongify.java index 9b3a42d0b00..0517107f8cd 100644 --- a/Mage.Sets/src/mage/cards/p/Pongify.java +++ b/Mage.Sets/src/mage/cards/p/Pongify.java @@ -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; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/Ravenform.java b/Mage.Sets/src/mage/cards/r/Ravenform.java index 58db871b3a3..65628c3c304 100644 --- a/Mage.Sets/src/mage/cards/r/Ravenform.java +++ b/Mage.Sets/src/mage/cards/r/Ravenform.java @@ -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; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/ReduceToMemory.java b/Mage.Sets/src/mage/cards/r/ReduceToMemory.java index cc3e94bb8e7..58e2c2222f9 100644 --- a/Mage.Sets/src/mage/cards/r/ReduceToMemory.java +++ b/Mage.Sets/src/mage/cards/r/ReduceToMemory.java @@ -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; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/Resculpt.java b/Mage.Sets/src/mage/cards/r/Resculpt.java index c5e735ea932..bfe25cdf02d 100644 --- a/Mage.Sets/src/mage/cards/r/Resculpt.java +++ b/Mage.Sets/src/mage/cards/r/Resculpt.java @@ -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; - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SawtuskDemolisher.java b/Mage.Sets/src/mage/cards/s/SawtuskDemolisher.java index 0cc6b8e3ec5..e8c810d3d52 100644 --- a/Mage.Sets/src/mage/cards/s/SawtuskDemolisher.java +++ b/Mage.Sets/src/mage/cards/s/SawtuskDemolisher.java @@ -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); } diff --git a/Mage.Sets/src/mage/cards/s/SecureTheScene.java b/Mage.Sets/src/mage/cards/s/SecureTheScene.java index 77184c9dc44..3cd4fc6423d 100644 --- a/Mage.Sets/src/mage/cards/s/SecureTheScene.java +++ b/Mage.Sets/src/mage/cards/s/SecureTheScene.java @@ -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()); - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/StrokeOfMidnight.java b/Mage.Sets/src/mage/cards/s/StrokeOfMidnight.java new file mode 100644 index 00000000000..d7990ac218c --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StrokeOfMidnight.java @@ -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); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/t/TransmogrifyingWand.java b/Mage.Sets/src/mage/cards/t/TransmogrifyingWand.java index e69a9ee32b9..d3e045ff22f 100644 --- a/Mage.Sets/src/mage/cards/t/TransmogrifyingWand.java +++ b/Mage.Sets/src/mage/cards/t/TransmogrifyingWand.java @@ -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); - } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/WildsOfEldraine.java b/Mage.Sets/src/mage/sets/WildsOfEldraine.java index 5ada7313bf5..4a3f355e096 100644 --- a/Mage.Sets/src/mage/sets/WildsOfEldraine.java +++ b/Mage.Sets/src/mage/sets/WildsOfEldraine.java @@ -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)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/woe/StrokeOfMidnightTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/woe/StrokeOfMidnightTest.java new file mode 100644 index 00000000000..b64644a97ef --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/woe/StrokeOfMidnightTest.java @@ -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 + *
+ * 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); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenControllerTargetPermanentEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenControllerTargetPermanentEffect.java new file mode 100644 index 00000000000..a5ecba9c876 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenControllerTargetPermanentEffect.java @@ -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 + *
+ * 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; + } +}