diff --git a/Mage.Sets/src/mage/cards/a/AkroanHorse.java b/Mage.Sets/src/mage/cards/a/AkroanHorse.java index dc8dd9b921..fd8b2a27fb 100644 --- a/Mage.Sets/src/mage/cards/a/AkroanHorse.java +++ b/Mage.Sets/src/mage/cards/a/AkroanHorse.java @@ -1,15 +1,13 @@ - package mage.cards.a; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenAllEffect; import mage.abilities.keyword.DefenderAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -17,14 +15,14 @@ import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.SoldierToken; -import mage.game.permanent.token.Token; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetOpponent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class AkroanHorse extends CardImpl { @@ -39,10 +37,15 @@ public final class AkroanHorse extends CardImpl { this.addAbility(DefenderAbility.getInstance()); // When Akroan Horse enters the battlefield, an opponent gains control of it. - this.addAbility(new EntersBattlefieldTriggeredAbility(new AkroanHorseChangeControlEffect(), false)); + this.addAbility(new EntersBattlefieldTriggeredAbility( + new AkroanHorseChangeControlEffect(), false + )); // At the beginning of your upkeep, each opponent create a 1/1 white Soldier creature token. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new AkroanHorseCreateTokenEffect(), TargetController.YOU, false)); + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + new CreateTokenAllEffect(new SoldierToken(), TargetController.OPPONENT), + TargetController.YOU, false + )); } private AkroanHorse(final AkroanHorse card) { @@ -73,18 +76,17 @@ class AkroanHorseChangeControlEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } Target target = new TargetOpponent(); target.setNotTarget(true); - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - if (controller.chooseTarget(outcome, target, source, game)) { - ContinuousEffect effect = new AkroanHorseGainControlEffect(Duration.Custom, target.getFirstTarget()); - effect.setTargetPointer(new FixedTarget(source.getSourceId(), game)); - game.addEffect(effect, source); - return true; - } - } - return false; + controller.chooseTarget(outcome, target, source, game); + ContinuousEffect effect = new AkroanHorseGainControlEffect(Duration.Custom, target.getFirstTarget()); + effect.setTargetPointer(new FixedTarget(source.getSourceId(), game)); + game.addEffect(effect, source); + return true; } } @@ -111,42 +113,14 @@ class AkroanHorseGainControlEffect extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { Permanent permanent; - if (targetPointer == null) { permanent = game.getPermanent(source.getFirstTarget()); } else { permanent = game.getPermanent(targetPointer.getFirst(game, source)); } - - if (permanent == null) { return false; } - - return permanent.changeControllerId(controller, game, source); - - } -} - -class AkroanHorseCreateTokenEffect extends OneShotEffect { - - public AkroanHorseCreateTokenEffect() { - super(Outcome.Detriment); - this.staticText = "each opponent creates a 1/1 white Soldier creature token"; - } - - private AkroanHorseCreateTokenEffect(final AkroanHorseCreateTokenEffect effect) { - super(effect); - } - - @Override - public AkroanHorseCreateTokenEffect copy() { - return new AkroanHorseCreateTokenEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - for (UUID opponentId : game.getOpponents(source.getControllerId())) { - Token token = new SoldierToken(); - token.putOntoBattlefield(1, game, source, opponentId); + if (permanent == null) { + return false; } - return true; + return permanent.changeControllerId(controller, game, source); } } diff --git a/Mage.Sets/src/mage/cards/c/CaptiveAudience.java b/Mage.Sets/src/mage/cards/c/CaptiveAudience.java index bde88a7f90..39e42a7502 100644 --- a/Mage.Sets/src/mage/cards/c/CaptiveAudience.java +++ b/Mage.Sets/src/mage/cards/c/CaptiveAudience.java @@ -4,16 +4,14 @@ import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenAllEffect; import mage.abilities.effects.common.EntersBattlefieldUnderControlOfOpponentOfChoiceEffect; import mage.abilities.effects.common.SetPlayerLifeSourceEffect; import mage.abilities.effects.common.discard.DiscardHandControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.TargetController; -import mage.game.Game; import mage.game.permanent.token.ZombieToken; import java.util.UUID; @@ -40,7 +38,7 @@ public final class CaptiveAudience extends CardImpl { ability.addMode(new Mode(new DiscardHandControllerEffect())); // • Each opponent creates five 2/2 black Zombie creature tokens. - ability.addMode(new Mode(new CaptiveAudienceCreateTokensEffect())); + ability.addMode(new Mode(new CreateTokenAllEffect(new ZombieToken(), 5, TargetController.OPPONENT))); this.addAbility(ability); } @@ -53,28 +51,3 @@ public final class CaptiveAudience extends CardImpl { return new CaptiveAudience(this); } } - -class CaptiveAudienceCreateTokensEffect extends OneShotEffect { - - CaptiveAudienceCreateTokensEffect() { - super(Outcome.Benefit); - staticText = "Each opponent creates five 2/2 black Zombie creature tokens."; - } - - private CaptiveAudienceCreateTokensEffect(final CaptiveAudienceCreateTokensEffect effect) { - super(effect); - } - - @Override - public CaptiveAudienceCreateTokensEffect copy() { - return new CaptiveAudienceCreateTokensEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - for (UUID playerId : game.getOpponents(source.getControllerId())) { - new ZombieToken().putOntoBattlefield(5, game, source, playerId); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/d/DescentIntoAvernus.java b/Mage.Sets/src/mage/cards/d/DescentIntoAvernus.java index a0865989c0..057b49de62 100644 --- a/Mage.Sets/src/mage/cards/d/DescentIntoAvernus.java +++ b/Mage.Sets/src/mage/cards/d/DescentIntoAvernus.java @@ -4,9 +4,7 @@ import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.CountersSourceCount; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateTokenTargetEffect; +import mage.abilities.effects.common.CreateTokenAllEffect; import mage.abilities.effects.common.DamagePlayersEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; @@ -15,11 +13,8 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.TargetController; import mage.counters.CounterType; -import mage.game.Game; import mage.game.permanent.token.TreasureToken; -import mage.target.targetpointer.FixedTarget; -import java.util.Optional; import java.util.UUID; /** @@ -37,7 +32,9 @@ public final class DescentIntoAvernus extends CardImpl { new AddCountersSourceEffect(CounterType.DESCENT.createInstance(2)), TargetController.YOU, false ); - ability.addEffect(new DescentIntoAvernusEffect()); + ability.addEffect(new CreateTokenAllEffect( + new TreasureToken(), xValue, TargetController.EACH_PLAYER + ).setText("then each player creates X Treasure tokens")); ability.addEffect(new DamagePlayersEffect( Outcome.Damage, xValue, TargetController.ANY ).setText("and {this} deals X damage to each player, where X is the number of descent counters on {this}")); @@ -53,38 +50,3 @@ public final class DescentIntoAvernus extends CardImpl { return new DescentIntoAvernus(this); } } - -class DescentIntoAvernusEffect extends OneShotEffect { - - DescentIntoAvernusEffect() { - super(Outcome.Benefit); - staticText = "Then each player creates X Treasure tokens"; - } - - private DescentIntoAvernusEffect(final DescentIntoAvernusEffect effect) { - super(effect); - } - - @Override - public DescentIntoAvernusEffect copy() { - return new DescentIntoAvernusEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - int count = Optional - .ofNullable(source.getSourcePermanentOrLKI(game)) - .map(permanent -> permanent.getCounters(game)) - .map(counters -> counters.getCount(CounterType.DESCENT)) - .orElse(0); - if (count < 1) { - return false; - } - for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { - Effect effect = new CreateTokenTargetEffect(new TreasureToken(), count); - effect.setTargetPointer(new FixedTarget(playerId)); - effect.apply(game, source); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/e/ElephantResurgence.java b/Mage.Sets/src/mage/cards/e/ElephantResurgence.java index 779abea6c2..6a9c49da75 100644 --- a/Mage.Sets/src/mage/cards/e/ElephantResurgence.java +++ b/Mage.Sets/src/mage/cards/e/ElephantResurgence.java @@ -1,22 +1,15 @@ - package mage.cards.e; -import java.util.UUID; -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.CreateTokenAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; -import mage.game.Game; +import mage.constants.TargetController; import mage.game.permanent.token.ElephantResurgenceToken; -import mage.players.Player; -import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; /** - * * @author TheElk801 */ public final class ElephantResurgence extends CardImpl { @@ -25,7 +18,9 @@ public final class ElephantResurgence extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}"); // Each player creates a green Elephant creature token. Those creatures have "This creature's power and toughness are each equal to the number of creature cards in its controller's graveyard." - this.getSpellAbility().addEffect(new ElephantResurgenceEffect()); + this.getSpellAbility().addEffect(new CreateTokenAllEffect( + new ElephantResurgenceToken(), TargetController.EACH_PLAYER + )); } private ElephantResurgence(final ElephantResurgence card) { @@ -37,35 +32,3 @@ public final class ElephantResurgence extends CardImpl { return new ElephantResurgence(this); } } - -class ElephantResurgenceEffect extends OneShotEffect { - - public ElephantResurgenceEffect() { - super(Outcome.Detriment); - this.staticText = "Each player creates a green Elephant creature token. Those creatures have " - + "\"This creature's power and toughness are each equal to the number of creature cards in its controller's graveyard.\""; - } - - public ElephantResurgenceEffect(final ElephantResurgenceEffect effect) { - super(effect); - } - - @Override - public ElephantResurgenceEffect copy() { - return new ElephantResurgenceEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Effect effect = new CreateTokenTargetEffect(new ElephantResurgenceToken(), 1); - effect.setTargetPointer(new FixedTarget(playerId)); - effect.apply(game, source); - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/g/GrismoldTheDreadsower.java b/Mage.Sets/src/mage/cards/g/GrismoldTheDreadsower.java index 48f322f38b..280177e6de 100644 --- a/Mage.Sets/src/mage/cards/g/GrismoldTheDreadsower.java +++ b/Mage.Sets/src/mage/cards/g/GrismoldTheDreadsower.java @@ -1,24 +1,22 @@ package mage.cards.g; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.DiesCreatureTriggeredAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateTokenTargetEffect; +import mage.abilities.effects.common.CreateTokenAllEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.TargetController; import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.TokenPredicate; -import mage.game.Game; import mage.game.permanent.token.GrismoldPlantToken; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -47,7 +45,8 @@ public final class GrismoldTheDreadsower extends CardImpl { // At the beginning of your end step, each player creates a 1/1 green Plant creature token. this.addAbility(new BeginningOfEndStepTriggeredAbility( - new GrismoldTheDreadsowerEffect(), TargetController.YOU, false + new CreateTokenAllEffect(new GrismoldPlantToken(), TargetController.EACH_PLAYER), + TargetController.YOU, false )); // Whenever a creature token dies, put a +1/+1 counter on Grismold, the Dreadsower. @@ -65,30 +64,3 @@ public final class GrismoldTheDreadsower extends CardImpl { return new GrismoldTheDreadsower(this); } } - -class GrismoldTheDreadsowerEffect extends OneShotEffect { - - GrismoldTheDreadsowerEffect() { - super(Outcome.Benefit); - staticText = "each player creates a 1/1 green Plant creature token"; - } - - private GrismoldTheDreadsowerEffect(final GrismoldTheDreadsowerEffect effect) { - super(effect); - } - - @Override - public GrismoldTheDreadsowerEffect copy() { - return new GrismoldTheDreadsowerEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - game.getState().getPlayersInRange(source.getControllerId(), game).stream().forEach(playerId -> { - Effect effect = new CreateTokenTargetEffect(new GrismoldPlantToken(), 1); - effect.setTargetPointer(new FixedTarget(playerId, game)); - effect.apply(game, source); - }); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/m/MarchingDuodrone.java b/Mage.Sets/src/mage/cards/m/MarchingDuodrone.java index 73830678a7..4a351a9aff 100644 --- a/Mage.Sets/src/mage/cards/m/MarchingDuodrone.java +++ b/Mage.Sets/src/mage/cards/m/MarchingDuodrone.java @@ -1,15 +1,13 @@ package mage.cards.m; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; -import mage.game.Game; +import mage.constants.TargetController; import mage.game.permanent.token.TreasureToken; import java.util.UUID; @@ -27,7 +25,9 @@ public final class MarchingDuodrone extends CardImpl { this.toughness = new MageInt(2); // Whenever Marching Duodrone attacks, each player creates a Treasure token. - this.addAbility(new AttacksTriggeredAbility(new MarchingDuodroneEffect())); + this.addAbility(new AttacksTriggeredAbility(new CreateTokenAllEffect( + new TreasureToken(), TargetController.EACH_PLAYER + ))); } private MarchingDuodrone(final MarchingDuodrone card) { @@ -39,28 +39,3 @@ public final class MarchingDuodrone extends CardImpl { return new MarchingDuodrone(this); } } - -class MarchingDuodroneEffect extends OneShotEffect { - - MarchingDuodroneEffect() { - super(Outcome.Benefit); - staticText = "each player creates a Treasure token"; - } - - private MarchingDuodroneEffect(final MarchingDuodroneEffect effect) { - super(effect); - } - - @Override - public MarchingDuodroneEffect copy() { - return new MarchingDuodroneEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { - new TreasureToken().putOntoBattlefield(1, game, source, playerId); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/p/PursuedWhale.java b/Mage.Sets/src/mage/cards/p/PursuedWhale.java index d3f76cff3e..f61557a009 100644 --- a/Mage.Sets/src/mage/cards/p/PursuedWhale.java +++ b/Mage.Sets/src/mage/cards/p/PursuedWhale.java @@ -1,18 +1,17 @@ package mage.cards.p; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenAllEffect; import mage.abilities.effects.common.cost.SpellsCostModificationThatTargetSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; import mage.filter.FilterCard; -import mage.game.Game; import mage.game.permanent.token.PursuedWhaleToken; -import mage.game.permanent.token.Token; import java.util.UUID; @@ -21,6 +20,8 @@ import java.util.UUID; */ public final class PursuedWhale extends CardImpl { + private static final FilterCard filter = new FilterCard("spells"); + public PursuedWhale(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}"); @@ -29,12 +30,14 @@ public final class PursuedWhale extends CardImpl { this.toughness = new MageInt(8); // When Pursued Whale enters the battlefield, each opponent creates a 1/1 red Pirate creature token with "This creature can't block" and "Creatures you control attack each combat if able." - this.addAbility(new EntersBattlefieldTriggeredAbility(new PursuedWhaleTokenEffect())); + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenAllEffect( + new PursuedWhaleToken(), TargetController.OPPONENT + ))); // Spells your opponents cast that target Pursued Whale cost {3} more to cast. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new SpellsCostModificationThatTargetSourceEffect(3, new FilterCard("Spells"), TargetController.OPPONENT)) - ); + this.addAbility(new SimpleStaticAbility( + new SpellsCostModificationThatTargetSourceEffect(3, filter, TargetController.OPPONENT) + )); } private PursuedWhale(final PursuedWhale card) { @@ -46,31 +49,3 @@ public final class PursuedWhale extends CardImpl { return new PursuedWhale(this); } } - -class PursuedWhaleTokenEffect extends OneShotEffect { - - private static final Token token = new PursuedWhaleToken(); - - PursuedWhaleTokenEffect() { - super(Outcome.Benefit); - staticText = "each opponent creates a 1/1 red Pirate creature token with " + - "\"This creature can't block\" and \"Creatures you control attack each combat if able.\""; - } - - private PursuedWhaleTokenEffect(final PursuedWhaleTokenEffect effect) { - super(effect); - } - - @Override - public PursuedWhaleTokenEffect copy() { - return new PursuedWhaleTokenEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - for (UUID playerId : game.getOpponents(source.getControllerId())) { - token.putOntoBattlefield(1, game, source, playerId); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/r/RasputinTheOneiromancer.java b/Mage.Sets/src/mage/cards/r/RasputinTheOneiromancer.java index 47ed97ac1a..57364e9146 100644 --- a/Mage.Sets/src/mage/cards/r/RasputinTheOneiromancer.java +++ b/Mage.Sets/src/mage/cards/r/RasputinTheOneiromancer.java @@ -11,21 +11,19 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.dynamicvalue.common.CountersSourceCount; import mage.abilities.dynamicvalue.common.OpponentsCount; import mage.abilities.dynamicvalue.common.RemovedCountersForCostValue; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenAllEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.mana.DynamicManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.SuperType; +import mage.constants.TargetController; import mage.counters.CounterType; -import mage.game.Game; import mage.game.permanent.token.GoblinToken; import mage.game.permanent.token.RasputinKnightToken; -import mage.game.permanent.token.Token; import java.util.UUID; @@ -48,7 +46,7 @@ public final class RasputinTheOneiromancer extends CardImpl { Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect( CounterType.DREAM.createInstance(), OpponentsCount.instance, false ).setText("put a dream counter on it for each opponent you have.")); - ability.addEffect(new RasputinCreateGoblinsEffect()); + ability.addEffect(new CreateTokenAllEffect(new GoblinToken(), TargetController.OPPONENT)); this.addAbility(ability); // {T}, Remove one or more dream counters from Rasputin: Add that much {C}. @@ -77,29 +75,3 @@ public final class RasputinTheOneiromancer extends CardImpl { return new RasputinTheOneiromancer(this); } } - -class RasputinCreateGoblinsEffect extends OneShotEffect { - - public RasputinCreateGoblinsEffect() { - super(Outcome.Detriment); - this.staticText = "each opponent creates a 1/1 red Goblin creature token"; - } - - private RasputinCreateGoblinsEffect(final RasputinCreateGoblinsEffect effect) { - super(effect); - } - - @Override - public RasputinCreateGoblinsEffect copy() { - return new RasputinCreateGoblinsEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - for (UUID opponentId : game.getOpponents(source.getControllerId())) { - Token token = new GoblinToken(); - token.putOntoBattlefield(1, game, source, opponentId); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/s/SlaughterSpecialist.java b/Mage.Sets/src/mage/cards/s/SlaughterSpecialist.java index 6987cc67ef..b91883b572 100644 --- a/Mage.Sets/src/mage/cards/s/SlaughterSpecialist.java +++ b/Mage.Sets/src/mage/cards/s/SlaughterSpecialist.java @@ -1,21 +1,18 @@ package mage.cards.s; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenAllEffect; 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.SubType; +import mage.constants.TargetController; import mage.counters.CounterType; import mage.filter.StaticFilters; -import mage.game.Game; import mage.game.permanent.token.HumanToken; -import mage.game.permanent.token.Token; import java.util.UUID; @@ -33,7 +30,9 @@ public final class SlaughterSpecialist extends CardImpl { this.toughness = new MageInt(3); // When Slaughter Specialist enters the battlefield, each opponent creates a 1/1 white Human creature token. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SlaughterSpecialistEffect())); + this.addAbility(new EntersBattlefieldTriggeredAbility( + new CreateTokenAllEffect(new HumanToken(), TargetController.OPPONENT) + )); // Whenever a creature an opponent controls dies, put a +1/+1 counter on Slaughter Specialist. this.addAbility(new DiesCreatureTriggeredAbility( @@ -51,29 +50,3 @@ public final class SlaughterSpecialist extends CardImpl { return new SlaughterSpecialist(this); } } - -class SlaughterSpecialistEffect extends OneShotEffect { - - SlaughterSpecialistEffect() { - super(Outcome.Benefit); - staticText = "each opponent creates a 1/1 white Human creature token"; - } - - private SlaughterSpecialistEffect(final SlaughterSpecialistEffect effect) { - super(effect); - } - - @Override - public SlaughterSpecialistEffect copy() { - return new SlaughterSpecialistEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Token token = new HumanToken(); - for (UUID opponentId : game.getOpponents(source.getControllerId())) { - token.putOntoBattlefield(1, game, source, opponentId); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/t/TributeToHorobi.java b/Mage.Sets/src/mage/cards/t/TributeToHorobi.java index d6379f3d6e..5ae827f0d1 100644 --- a/Mage.Sets/src/mage/cards/t/TributeToHorobi.java +++ b/Mage.Sets/src/mage/cards/t/TributeToHorobi.java @@ -1,23 +1,20 @@ package mage.cards.t; -import java.util.UUID; - -import mage.abilities.Ability; import mage.abilities.common.SagaAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenAllEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.keyword.TransformAbility; -import mage.constants.Outcome; -import mage.constants.SagaChapter; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.game.Game; +import mage.constants.SagaChapter; +import mage.constants.SubType; +import mage.constants.TargetController; import mage.game.permanent.token.RatRogueToken; +import java.util.UUID; + /** - * * @author weirddan455 */ public final class TributeToHorobi extends CardImpl { @@ -32,7 +29,10 @@ public final class TributeToHorobi extends CardImpl { SagaAbility sagaAbility = new SagaAbility(this); // I, II — Each opponent creates a 1/1 black Rat Rouge creature token. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, new TributeToHorobiTokenEffect()); + sagaAbility.addChapterEffect( + this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, + new CreateTokenAllEffect(new RatRogueToken(), TargetController.OPPONENT) + ); // III — Exile this Saga, then return it to the battlefield transformed under your control. this.addAbility(new TransformAbility()); @@ -50,31 +50,3 @@ public final class TributeToHorobi extends CardImpl { return new TributeToHorobi(this); } } - -class TributeToHorobiTokenEffect extends OneShotEffect { - - public TributeToHorobiTokenEffect() { - super(Outcome.PutCreatureInPlay); - this.staticText = "Each opponent creates a 1/1 black Rat Rogue creature token"; - } - - private TributeToHorobiTokenEffect(final TributeToHorobiTokenEffect effect) { - super(effect); - } - - @Override - public TributeToHorobiTokenEffect copy() { - return new TributeToHorobiTokenEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - boolean success = false; - for (UUID opponentId : game.getOpponents(source.getControllerId())) { - if (new RatRogueToken().putOntoBattlefield(1, game, source, opponentId)) { - success = true; - } - } - return success; - } -} diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenAllEffect.java new file mode 100644 index 0000000000..2f33f121c4 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenAllEffect.java @@ -0,0 +1,126 @@ +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.constants.TargetController; +import mage.game.Game; +import mage.game.permanent.token.Token; +import mage.util.CardUtil; + +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public class CreateTokenAllEffect extends OneShotEffect { + + private final Token token; + private final DynamicValue amount; + private final TargetController targetController; + private final boolean tapped; + + public CreateTokenAllEffect(Token token, TargetController targetController) { + this(token, 1, targetController); + } + + public CreateTokenAllEffect(Token token, int amount, TargetController targetController) { + this(token, StaticValue.get(amount), targetController); + } + + public CreateTokenAllEffect(Token token, DynamicValue amount, TargetController targetController) { + this(token, amount, targetController, false); + } + + public CreateTokenAllEffect(Token token, DynamicValue amount, TargetController targetController, boolean tapped) { + super(Outcome.Benefit); + this.token = token; + this.tapped = tapped; + this.amount = amount; + this.targetController = targetController; + this.setText(); + } + + private CreateTokenAllEffect(final CreateTokenAllEffect effect) { + super(effect); + this.token = effect.token; + this.tapped = effect.tapped; + this.amount = effect.amount; + this.targetController = effect.targetController; + } + + @Override + public CreateTokenAllEffect copy() { + return new CreateTokenAllEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + int amount = this.amount.calculate(game, source, this); + for (UUID playerId : getPlayers(game, source)) { + token.putOntoBattlefield(amount, game, source, playerId, tapped, false); + } + return true; + } + + private Collection getPlayers(Game game, Ability source) { + switch (targetController) { + case ANY: + case EACH_PLAYER: + return game.getState().getPlayersInRange(source.getControllerId(), game); + case OPPONENT: + return game.getOpponents(source.getControllerId()); + } + return Collections.emptyList(); + } + + private void setText() { + StringBuilder sb = new StringBuilder("each "); + switch (targetController) { + case ANY: + case EACH_PLAYER: + sb.append("player"); + break; + case OPPONENT: + sb.append("opponent"); + } + sb.append(" creates "); + if (amount.toString().equals("1")) { + if (tapped) { + sb.append("a tapped "); + sb.append(token.getDescription()); + } else { + sb.append(CardUtil.addArticle(token.getDescription())); + } + } else { + sb.append(CardUtil.numberToText(amount.toString())).append(' '); + if (tapped) { + sb.append("tapped "); + } + sb.append(token.getDescription().replace("token. It has", "tokens. They have")); + if (token.getDescription().endsWith("token")) { + sb.append("s"); + } + int tokenLocation = sb.indexOf("token "); + if (tokenLocation != -1) { + sb.replace(tokenLocation, tokenLocation + 6, "tokens "); + } + } + + String message = amount.getMessage(); + if (!message.isEmpty()) { + if (amount.toString().equals("X")) { + sb.append(", where X is "); + } else { + sb.append(" for each "); + } + } + sb.append(message); + + staticText = sb.toString(); + } +}