diff --git a/Mage.Sets/src/mage/cards/s/SaheeliTheGifted.java b/Mage.Sets/src/mage/cards/s/SaheeliTheGifted.java new file mode 100644 index 00000000000..4e31f691b7f --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SaheeliTheGifted.java @@ -0,0 +1,162 @@ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.SpellAbility; +import mage.abilities.common.CanBeYourCommanderAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.cost.CostModificationEffectImpl; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.CostModificationType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.ServoToken; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; +import mage.watchers.common.CastSpellLastTurnWatcher; + +/** + * + * @author TheElk801 + */ +public final class SaheeliTheGifted extends CardImpl { + + public SaheeliTheGifted(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{U}{R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.SAHEELI); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); + + // +1: Create a 1/1 colorless Servo artifact creature token. + this.addAbility(new LoyaltyAbility( + new CreateTokenEffect(new ServoToken()), 1 + )); + + // +1: The next spell you cast this turn costs {1} less to cast for each artifact you control as you cast it. + this.addAbility(new LoyaltyAbility( + new SaheeliTheGiftedCostReductionEffect(), 1 + )); + + // -7: For each artifact you control, create a token that's a copy of it. Those tokens gain haste. Exile those tokens at the beginning of the next end step. + this.addAbility(new LoyaltyAbility( + new SaheeliTheGiftedTokenEffect(), -7 + )); + + // Saheeli, the Gifted can be your commander. + this.addAbility(CanBeYourCommanderAbility.getInstance()); + } + + public SaheeliTheGifted(final SaheeliTheGifted card) { + super(card); + } + + @Override + public SaheeliTheGifted copy() { + return new SaheeliTheGifted(this); + } +} + +class SaheeliTheGiftedCostReductionEffect extends CostModificationEffectImpl { + + private int spellsCast; + + public SaheeliTheGiftedCostReductionEffect() { + super(Duration.EndOfTurn, Outcome.Benefit, CostModificationType.REDUCE_COST); + staticText = "the next spell you cast this turn costs {1} less to cast " + + "for each artifact you control as you cast it"; + } + + protected SaheeliTheGiftedCostReductionEffect(final SaheeliTheGiftedCostReductionEffect effect) { + super(effect); + this.spellsCast = effect.spellsCast; + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getSimpleName()); + if (watcher != null) { + spellsCast = watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(source.getControllerId()); + } + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + int artifactCount = game.getBattlefield().getAllActivePermanents( + StaticFilters.FILTER_PERMANENT_ARTIFACT_AN, + source.getControllerId(), game + ).size(); + CardUtil.reduceCost(abilityToModify, artifactCount); + return true; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getSimpleName()); + if (watcher != null) { + if (watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(source.getControllerId()) > spellsCast) { + discard(); // only one use + return false; + } + } + if (abilityToModify instanceof SpellAbility) { + return abilityToModify.isControlledBy(source.getControllerId()); + } + return false; + } + + @Override + public SaheeliTheGiftedCostReductionEffect copy() { + return new SaheeliTheGiftedCostReductionEffect(this); + } +} + +class SaheeliTheGiftedTokenEffect extends OneShotEffect { + + public SaheeliTheGiftedTokenEffect() { + super(Outcome.Benefit); + this.staticText = "for each artifact you control, " + + "create a token that's a copy of it. " + + "Those tokens gain haste. " + + "Exile those tokens at the beginning of the next end step."; + } + + public SaheeliTheGiftedTokenEffect(final SaheeliTheGiftedTokenEffect effect) { + super(effect); + } + + @Override + public SaheeliTheGiftedTokenEffect copy() { + return new SaheeliTheGiftedTokenEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents( + StaticFilters.FILTER_PERMANENT_ARTIFACT_AN, + source.getControllerId(), game + )) { + if (permanent != null) { + CreateTokenCopyTargetEffect effect + = new CreateTokenCopyTargetEffect(); + effect.setTargetPointer(new FixedTarget(permanent, game)); + effect.setHasHaste(true); + effect.apply(game, source); + effect.exileTokensCreatedAtNextEndStep(game, source); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Commander2018.java b/Mage.Sets/src/mage/sets/Commander2018.java index c608cc8c28e..1401860a88e 100644 --- a/Mage.Sets/src/mage/sets/Commander2018.java +++ b/Mage.Sets/src/mage/sets/Commander2018.java @@ -233,6 +233,7 @@ public final class Commander2018 extends ExpansionSet { cards.add(new SetCardInfo("Sage's Reverie", 72, Rarity.UNCOMMON, mage.cards.s.SagesReverie.class)); cards.add(new SetCardInfo("Saheeli's Artistry", 100, Rarity.RARE, mage.cards.s.SaheelisArtistry.class)); cards.add(new SetCardInfo("Saheeli's Directive", 26, Rarity.RARE, mage.cards.s.SaheelisDirective.class)); + cards.add(new SetCardInfo("Saheeli, the Gifted", 44, Rarity.MYTHIC, mage.cards.s.SaheeliTheGifted.class)); cards.add(new SetCardInfo("Sakura-Tribe Elder", 160, Rarity.COMMON, mage.cards.s.SakuraTribeElder.class)); cards.add(new SetCardInfo("Savage Lands", 275, Rarity.UNCOMMON, mage.cards.s.SavageLands.class)); cards.add(new SetCardInfo("Savage Twister", 190, Rarity.UNCOMMON, mage.cards.s.SavageTwister.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java index 40936884ef9..092c8ec92cb 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java @@ -1,4 +1,3 @@ - package mage.abilities.effects.common; import java.util.ArrayList; @@ -8,6 +7,8 @@ import mage.MageObject; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.Mode; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.FlyingAbility; @@ -17,6 +18,7 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.SuperType; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.EmptyToken; @@ -124,14 +126,6 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect { this.isntLegendary = effect.isntLegendary; } - public void setBecomesArtifact(boolean becomesArtifact) { - this.becomesArtifact = becomesArtifact; - } - - public void setIsntLegendary(boolean isntLegendary) { - this.isntLegendary = isntLegendary; - } - @Override public boolean apply(Game game, Ability source) { UUID targetId; @@ -282,4 +276,33 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect { public void setUseLKI(boolean useLKI) { this.useLKI = useLKI; } + + public void setBecomesArtifact(boolean becomesArtifact) { + this.becomesArtifact = becomesArtifact; + } + + public void setIsntLegendary(boolean isntLegendary) { + this.isntLegendary = isntLegendary; + } + + public void setHasHaste(boolean hasHaste) { + this.hasHaste = hasHaste; + } + + public void exileTokensCreatedAtNextEndStep(Game game, Ability source) { + for (Permanent tokenPermanent : addedTokenPermanents) { + ExileTargetEffect exileEffect = new ExileTargetEffect(null, "", Zone.BATTLEFIELD); + exileEffect.setTargetPointer(new FixedTarget(tokenPermanent, game)); + game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect), source); + } + } + + public void exileTokensCreatedAtEndOfCombat(Game game, Ability source) { + for (Permanent tokenPermanent : addedTokenPermanents) { + + ExileTargetEffect exileEffect = new ExileTargetEffect(null, "", Zone.BATTLEFIELD); + exileEffect.setTargetPointer(new FixedTarget(tokenPermanent, game)); + game.addDelayedTriggeredAbility(new AtTheEndOfCombatDelayedTriggeredAbility(exileEffect), source); + } + } }