diff --git a/Mage.Sets/src/mage/cards/k/KumanoFacesKakkazan.java b/Mage.Sets/src/mage/cards/k/KumanoFacesKakkazan.java index ae6783b04a5..b5008af8aa6 100644 --- a/Mage.Sets/src/mage/cards/k/KumanoFacesKakkazan.java +++ b/Mage.Sets/src/mage/cards/k/KumanoFacesKakkazan.java @@ -1,9 +1,7 @@ package mage.cards.k; -import mage.abilities.Ability; -import mage.abilities.DelayedTriggeredAbility; import mage.abilities.common.SagaAbility; -import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.common.delayed.AddCounterNextSpellDelayedTriggeredAbility; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DamageAllEffect; import mage.abilities.effects.common.DamagePlayersEffect; @@ -11,24 +9,22 @@ import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.counters.CounterType; +import mage.constants.CardType; +import mage.constants.SagaChapter; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; import mage.filter.common.FilterPlaneswalkerPermanent; -import mage.game.Game; -import mage.game.events.EntersTheBattlefieldEvent; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.game.stack.Spell; import java.util.UUID; /** - * * @author weirddan455 */ public final class KumanoFacesKakkazan extends CardImpl { - private static final FilterPlaneswalkerPermanent filter = new FilterPlaneswalkerPermanent(); + private static final FilterPermanent filter = new FilterPlaneswalkerPermanent(); + static { filter.add(TargetController.OPPONENT.getControllerPredicate()); } @@ -49,7 +45,10 @@ public final class KumanoFacesKakkazan extends CardImpl { ); // II — When you cast your next creature spell this turn, that creature enters the battlefield with an additional +1/+1 counter on it. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, new CreateDelayedTriggeredAbilityEffect(new KumanoFacesKakkazanTriggeredAbility())); + sagaAbility.addChapterEffect( + this, SagaChapter.CHAPTER_II, + new CreateDelayedTriggeredAbilityEffect(new AddCounterNextSpellDelayedTriggeredAbility()) + ); // III — Exile this Saga, then return it to the battlefield transformed under your control. this.addAbility(new TransformAbility()); @@ -67,81 +66,3 @@ public final class KumanoFacesKakkazan extends CardImpl { return new KumanoFacesKakkazan(this); } } - -class KumanoFacesKakkazanTriggeredAbility extends DelayedTriggeredAbility { - - KumanoFacesKakkazanTriggeredAbility() { - super(null, Duration.EndOfTurn); - } - - private KumanoFacesKakkazanTriggeredAbility(final KumanoFacesKakkazanTriggeredAbility ability) { - super(ability); - } - - @Override - public KumanoFacesKakkazanTriggeredAbility copy() { - return new KumanoFacesKakkazanTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.SPELL_CAST; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (this.isControlledBy(event.getPlayerId())) { - Spell spell = game.getSpell(event.getTargetId()); - if (spell != null && spell.isCreature(game)) { - this.getEffects().clear(); - this.getEffects().add(new KumanoFacesKakkazanCounterEffect(spell.getSourceId())); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "When you next cast a creature spell this turn, that creature enters the battlefield with an additional +1/+1 counter on it."; - } -} - -class KumanoFacesKakkazanCounterEffect extends ReplacementEffectImpl { - - private final UUID spellCastId; - - KumanoFacesKakkazanCounterEffect(UUID spellCastId) { - super(Duration.EndOfTurn, Outcome.BoostCreature); - this.spellCastId = spellCastId; - } - - private KumanoFacesKakkazanCounterEffect(final KumanoFacesKakkazanCounterEffect effect) { - super(effect); - this.spellCastId = effect.spellCastId; - } - - @Override - public KumanoFacesKakkazanCounterEffect copy() { - return new KumanoFacesKakkazanCounterEffect(this); - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - return spellCastId.equals(event.getTargetId()); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); - if (creature != null) { - creature.addCounters(CounterType.P1P1.createInstance(), source.getControllerId(), source, game, event.getAppliedEffects()); - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/l/LongListOfTheEnts.java b/Mage.Sets/src/mage/cards/l/LongListOfTheEnts.java index aa9b9f02c9e..95abf6d63d5 100644 --- a/Mage.Sets/src/mage/cards/l/LongListOfTheEnts.java +++ b/Mage.Sets/src/mage/cards/l/LongListOfTheEnts.java @@ -1,21 +1,20 @@ package mage.cards.l; import mage.abilities.Ability; -import mage.abilities.DelayedTriggeredAbility; import mage.abilities.common.SagaAbility; +import mage.abilities.common.delayed.AddCounterNextSpellDelayedTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.hint.Hint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.choices.ChoiceCreatureType; -import mage.constants.*; -import mage.counters.CounterType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SagaChapter; +import mage.constants.SubType; +import mage.filter.FilterSpell; +import mage.filter.common.FilterCreatureSpell; import mage.game.Game; -import mage.game.events.EntersTheBattlefieldEvent; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.game.stack.Spell; import mage.players.Player; import mage.util.CardUtil; @@ -134,91 +133,9 @@ class LongListOfTheEntsEffect extends OneShotEffect { game.informPlayers(player.getLogName() + " notes the creature type " + subType); newEntList.add(subType); game.getState().setValue(LongListOfTheEnts.getKey(game, source, offset), newEntList); - game.addDelayedTriggeredAbility(new LongListOfTheEntsTriggeredAbility(subType), source); + FilterSpell filter = new FilterCreatureSpell("a creature spell of that type"); + filter.add(subType.getPredicate()); + game.addDelayedTriggeredAbility(new AddCounterNextSpellDelayedTriggeredAbility(filter), source); return true; } - -} - -class LongListOfTheEntsTriggeredAbility extends DelayedTriggeredAbility { - - private final SubType subType; - - LongListOfTheEntsTriggeredAbility(SubType subType) { - super(new LongListOfTheEntsCounterEffect(), Duration.EndOfTurn, true, false); - this.subType = subType; - } - - private LongListOfTheEntsTriggeredAbility(final LongListOfTheEntsTriggeredAbility ability) { - super(ability); - this.subType = ability.subType; - } - - @Override - public LongListOfTheEntsTriggeredAbility copy() { - return new LongListOfTheEntsTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.SPELL_CAST; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (!isControlledBy(event.getPlayerId())) { - return false; - } - Spell spell = game.getSpell(event.getTargetId()); - if (spell == null || !spell.isCreature(game) || !spell.hasSubtype(subType, game)) { - return false; - } - this.getEffects().setValue("spellCast", spell); - return true; - } - - @Override - public String getRule() { - return "When you cast your next creature spell of that type this turn, that creature enters the battlefield with an additional +1/+1 counter on it."; - } -} - -class LongListOfTheEntsCounterEffect extends ReplacementEffectImpl { - - LongListOfTheEntsCounterEffect() { - super(Duration.EndOfStep, Outcome.BoostCreature); - } - - private LongListOfTheEntsCounterEffect(LongListOfTheEntsCounterEffect effect) { - super(effect); - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - Spell spell = (Spell) getValue("spellCast"); - return spell != null && event.getTargetId().equals(spell.getCard().getId()); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); - if (creature != null) { - creature.addCounters( - CounterType.P1P1.createInstance(), source.getControllerId(), - source, game, event.getAppliedEffects() - ); - discard(); - } - return false; - } - - @Override - public LongListOfTheEntsCounterEffect copy() { - return new LongListOfTheEntsCounterEffect(this); - } } diff --git a/Mage.Sets/src/mage/cards/s/SummonFenrir.java b/Mage.Sets/src/mage/cards/s/SummonFenrir.java new file mode 100644 index 00000000000..14f09cb5fd2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SummonFenrir.java @@ -0,0 +1,77 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.SagaAbility; +import mage.abilities.common.delayed.AddCounterNextSpellDelayedTriggeredAbility; +import mage.abilities.condition.common.ControlsCreatureGreatestPowerCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SagaChapter; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SummonFenrir extends CardImpl { + + private static final Hint hint = new ConditionHint( + ControlsCreatureGreatestPowerCondition.instance, + "You control a creature with the greatest power" + ); + + public SummonFenrir(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.SAGA); + this.subtype.add(SubType.WOLF); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.) + SagaAbility sagaAbility = new SagaAbility(this); + + // I -- Crescent Fang -- Search your library for a basic land card, put it onto the battlefield tapped, then shuffle. + sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, ability -> { + ability.addEffect(new SearchLibraryPutInPlayEffect( + new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true + )); + ability.withFlavorWord("Crescent Fang"); + }); + + // II -- Heavenward Howl -- When you next cast a creature spell this turn, that creature enters with an additional +1/+1 counter on it. + sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, ability -> { + ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new AddCounterNextSpellDelayedTriggeredAbility())); + ability.withFlavorWord("Heavenward Howl"); + }); + + // III -- Ecliptic Growl -- Draw a card if you control the creature with the greatest power or tied for the greatest power. + sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, ability -> { + ability.addEffect(new ConditionalOneShotEffect( + new DrawCardSourceControllerEffect(1), ControlsCreatureGreatestPowerCondition.instance, + "draw a card if you control the creature with the greatest power or tied for the greatest power" + )); + ability.withFlavorWord("Ecliptic Growl"); + }); + this.addAbility(sagaAbility.addHint(hint)); + } + + private SummonFenrir(final SummonFenrir card) { + super(card); + } + + @Override + public SummonFenrir copy() { + return new SummonFenrir(this); + } +} diff --git a/Mage.Sets/src/mage/sets/FinalFantasy.java b/Mage.Sets/src/mage/sets/FinalFantasy.java index 03ee56899e4..d4833ffd059 100644 --- a/Mage.Sets/src/mage/sets/FinalFantasy.java +++ b/Mage.Sets/src/mage/sets/FinalFantasy.java @@ -497,6 +497,8 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Summon: Esper Ramuh", 367, Rarity.UNCOMMON, mage.cards.s.SummonEsperRamuh.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Summon: Fat Chocobo", 202, Rarity.COMMON, mage.cards.s.SummonFatChocobo.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Summon: Fat Chocobo", 371, Rarity.COMMON, mage.cards.s.SummonFatChocobo.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Summon: Fenrir", 203, Rarity.UNCOMMON, mage.cards.s.SummonFenrir.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Summon: Fenrir", 372, Rarity.UNCOMMON, mage.cards.s.SummonFenrir.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Summon: G.F. Cerberus", 162, Rarity.RARE, mage.cards.s.SummonGFCerberus.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Summon: G.F. Cerberus", 368, Rarity.RARE, mage.cards.s.SummonGFCerberus.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Summon: Knights of Round", 359, Rarity.MYTHIC, mage.cards.s.SummonKnightsOfRound.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage/src/main/java/mage/abilities/common/delayed/AddCounterNextSpellDelayedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/delayed/AddCounterNextSpellDelayedTriggeredAbility.java new file mode 100644 index 00000000000..acf91114f15 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/delayed/AddCounterNextSpellDelayedTriggeredAbility.java @@ -0,0 +1,103 @@ +package mage.abilities.common.delayed; + +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.filter.FilterSpell; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; + +/** + * @author TheElk801 + */ +public class AddCounterNextSpellDelayedTriggeredAbility extends DelayedTriggeredAbility { + + private final FilterSpell filter; + + public AddCounterNextSpellDelayedTriggeredAbility() { + this(StaticFilters.FILTER_SPELL_A_CREATURE); + } + + public AddCounterNextSpellDelayedTriggeredAbility(FilterSpell filter) { + super(new AddCounterNextSpellEffect(), Duration.EndOfTurn, true, false); + this.filter = filter; + this.setTriggerPhrase("When you next cast " + " this turn, "); + } + + private AddCounterNextSpellDelayedTriggeredAbility(final AddCounterNextSpellDelayedTriggeredAbility ability) { + super(ability); + this.filter = ability.filter; + } + + @Override + public AddCounterNextSpellDelayedTriggeredAbility copy() { + return new AddCounterNextSpellDelayedTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.SPELL_CAST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (!isControlledBy(event.getPlayerId())) { + return false; + } + Spell spell = game.getSpell(event.getTargetId()); + if (spell == null || !filter.match(spell, getControllerId(), this, game)) { + return false; + } + this.getEffects().setValue("spellCast", spell); + return true; + } +} + +class AddCounterNextSpellEffect extends ReplacementEffectImpl { + + AddCounterNextSpellEffect() { + super(Duration.EndOfStep, Outcome.BoostCreature); + staticText = "that creature enters the battlefield with an additional +1/+1 counter on it"; + } + + private AddCounterNextSpellEffect(AddCounterNextSpellEffect effect) { + super(effect); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Spell spell = (Spell) getValue("spellCast"); + return spell != null && event.getTargetId().equals(spell.getCard().getId()); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); + if (creature == null) { + return false; + } + creature.addCounters( + CounterType.P1P1.createInstance(), source.getControllerId(), + source, game, event.getAppliedEffects() + ); + discard(); + return false; + } + + @Override + public AddCounterNextSpellEffect copy() { + return new AddCounterNextSpellEffect(this); + } +}