updated how Saga abilities are added

still need to fix sacrificing works (#4875)
This commit is contained in:
Evan Kranzler 2018-04-27 18:22:49 -04:00
parent 4ac6e7d86c
commit f2835685e9
11 changed files with 147 additions and 52 deletions

View file

@ -30,6 +30,7 @@ package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SagaAbility;
import mage.abilities.effects.Effects;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DamagePlayersEffect;
@ -61,8 +62,10 @@ public class ChainersTorment extends CardImpl {
SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_III);
// I, II Chainer's Torment deals 2 damage to each opponent and you gain 2 life.
Ability ability = sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, new DamagePlayersEffect(2, TargetController.OPPONENT));
ability.addEffect(new GainLifeEffect(2).setText("and you gain 2 life"));
Effects effects = new Effects();
effects.add(new DamagePlayersEffect(2, TargetController.OPPONENT));
effects.add(new GainLifeEffect(2).setText("and you gain 2 life"));
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, effects);
// III Create an X/X black Nightmare Horror creature token, where X is half your life total, rounded up. It deals X damage to you.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ChainersTormentEffect());

View file

@ -28,9 +28,8 @@
package mage.cards.p;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SagaAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects;
import mage.abilities.effects.common.DestroyAllEffect;
import mage.abilities.effects.common.ExileGraveyardAllPlayersEffect;
import mage.abilities.effects.common.continuous.AddCardTypeTargetEffect;
@ -74,11 +73,12 @@ public class PhyrexianScriptures extends CardImpl {
SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_III);
// I Put a +1/+1 counter on up to one target creature. That creature becomes an artifact in addition to its other types.
Ability ability = sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
ability.addTarget(new TargetCreaturePermanent(0, 1));
Effect effect = new AddCardTypeTargetEffect(Duration.WhileOnBattlefield, CardType.ARTIFACT);
effect.setText("That creature becomes an artifact in addition to its other types");
ability.addEffect(effect);
Effects effects = new Effects();
effects.add(new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
effects.add(new AddCardTypeTargetEffect(Duration.WhileOnBattlefield, CardType.ARTIFACT)
.setText("That creature becomes an artifact in addition to its other types")
);
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, effects, new TargetCreaturePermanent(0, 1));
// II Destroy all nonartifact creatures.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, new DestroyAllEffect(filter));

View file

@ -28,8 +28,8 @@
package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SagaAbility;
import mage.abilities.effects.Effects;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.counter.AddCountersAllEffect;
import mage.abilities.keyword.IndestructibleAbility;
@ -66,13 +66,15 @@ public class SongOfFreyalise extends CardImpl {
);
// III Put a +1/+1 counter on each creature you control. Those creatures gain vigilance, trample, and indestructible until end of turn.
Ability ability = sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new AddCountersAllEffect(CounterType.P1P1.createInstance(), FILTER_CONTROLLED_CREATURES));
ability.addEffect(new GainAbilityControlledEffect(VigilanceAbility.getInstance(), Duration.EndOfTurn, FILTER_CONTROLLED_CREATURES)
Effects effects = new Effects();
effects.add(new AddCountersAllEffect(CounterType.P1P1.createInstance(), FILTER_CONTROLLED_CREATURES));
effects.add(new GainAbilityControlledEffect(VigilanceAbility.getInstance(), Duration.EndOfTurn, FILTER_CONTROLLED_CREATURES)
.setText("Those creatures gain vigilance"));
ability.addEffect(new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, FILTER_CONTROLLED_CREATURES)
effects.add(new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, FILTER_CONTROLLED_CREATURES)
.setText(", trample"));
ability.addEffect(new GainAbilityControlledEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn, FILTER_CONTROLLED_CREATURES)
effects.add(new GainAbilityControlledEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn, FILTER_CONTROLLED_CREATURES)
.setText("and indestructible until end of turn"));
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, SagaChapter.CHAPTER_III, effects);
this.addAbility(sagaAbility);
}

View file

@ -28,7 +28,6 @@
package mage.cards.t;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SagaAbility;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.abilities.effects.common.SacrificeOpponentsEffect;
@ -51,6 +50,15 @@ import mage.target.common.TargetCardInGraveyard;
*/
public class TheEldestReborn extends CardImpl {
private static final FilterCard filter = new FilterCard("creature or planeswalker card from a graveyard");
static {
filter.add(Predicates.or(
new CardTypePredicate(CardType.CREATURE),
new CardTypePredicate(CardType.PLANESWALKER)
));
}
public TheEldestReborn(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}");
@ -60,19 +68,21 @@ public class TheEldestReborn extends CardImpl {
SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_III);
// I Each opponent sacrifices a creature or planeswalker.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I,
new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT_CREATURE_OR_PLANESWALKER_A));
new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT_CREATURE_OR_PLANESWALKER_A)
);
// II Each opponent discards a card.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II,
new DiscardEachPlayerEffect(TargetController.OPPONENT));
new DiscardEachPlayerEffect(TargetController.OPPONENT)
);
// III Put target creature or planeswalker card from a graveyard onto the battlefield under your control.
Ability ability = sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III,
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_III, SagaChapter.CHAPTER_III,
new ReturnFromGraveyardToBattlefieldTargetEffect()
.setText("Put target creature or planeswalker card from a graveyard onto the battlefield under your control"));
FilterCard filter = new FilterCard("creature or planeswalker card from a graveyard");
filter.add(Predicates.or(new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.PLANESWALKER)));
ability.addTarget(new TargetCardInGraveyard(filter));
.setText("Put target creature or planeswalker card from a graveyard onto the battlefield under your control"),
new TargetCardInGraveyard(filter)
);
this.addAbility(sagaAbility);
}

View file

@ -28,7 +28,6 @@
package mage.cards.t;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.SagaAbility;
import mage.abilities.effects.common.CopyTargetSpellEffect;
@ -55,6 +54,14 @@ import mage.target.targetpointer.FixedTarget;
*/
public class TheMirariConjecture extends CardImpl {
private static final FilterCard filterInstantCard = new FilterCard("instant card from your graveyard");
private static final FilterCard filterSorceryCard = new FilterCard("sorcery card from your graveyard");
static {
filterInstantCard.add(new CardTypePredicate(CardType.INSTANT));
filterSorceryCard.add(new CardTypePredicate(CardType.SORCERY));
}
public TheMirariConjecture(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{U}");
@ -62,16 +69,20 @@ public class TheMirariConjecture extends CardImpl {
// <i>(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)</i>
SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_III);
// I Return target instant card from your graveyard to your hand.
FilterCard filterInstantCard = new FilterCard("instant card from your graveyard");
filterInstantCard.add(new CardTypePredicate(CardType.INSTANT));
Ability ability = sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, new ReturnFromGraveyardToHandTargetEffect());
ability.addTarget(new TargetCardInYourGraveyard(filterInstantCard));
// II Return target sorcery card from your graveyard to your hand.
FilterCard filterSorceryCard = new FilterCard("sorcery card from your graveyard");
filterSorceryCard.add(new CardTypePredicate(CardType.SORCERY));
ability = sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, new ReturnFromGraveyardToHandTargetEffect());
ability.addTarget(new TargetCardInYourGraveyard(filterSorceryCard));
// I Return target instant card from your graveyard to your hand.
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I,
new ReturnFromGraveyardToHandTargetEffect(),
new TargetCardInYourGraveyard(filterInstantCard)
);
// II Return target sorcery card from your graveyard to your hand.
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II,
new ReturnFromGraveyardToHandTargetEffect(),
new TargetCardInYourGraveyard(filterSorceryCard)
);
// III Until end of turn, whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new CreateDelayedTriggeredAbilityEffect(new TheMirariConjectureDelayedTriggeredAbility()));
this.addAbility(sagaAbility);

View file

@ -32,6 +32,7 @@ import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SagaAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.Effects;
import mage.abilities.effects.common.ReturnToHandFromBattlefieldAllEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.constants.SubType;
@ -75,9 +76,13 @@ public class TimeOfIce extends CardImpl {
SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_III);
// I, II Tap target creature an opponent controls. It doesn't untap during its controller's untap step for as long as you control Time of Ice.
Ability ability = sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, new TapTargetEffect());
ability.addEffect(new TimeOfIceEffect());
ability.addTarget(new TargetCreaturePermanent(FILTER_OPPONENTS_PERMANENT_CREATURE));
Effects effects = new Effects();
effects.add(new TapTargetEffect());
effects.add(new TimeOfIceEffect());
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, effects,
new TargetCreaturePermanent(FILTER_OPPONENTS_PERMANENT_CREATURE)
);
// III Return all tapped creatures to their owners' hands.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ReturnToHandFromBattlefieldAllEffect(filter));

View file

@ -34,6 +34,7 @@ import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SagaAbility;
import mage.abilities.effects.Effects;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.FirstStrikeAbility;
@ -48,6 +49,7 @@ import mage.constants.SubType;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.Targets;
import mage.target.common.TargetControlledCreaturePermanent;
/**
@ -64,14 +66,25 @@ public class TriumphOfGerrard extends CardImpl {
// <i>(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)</i>
SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_III);
// I, II Put a +1/+1 counter on target creature you control with the greatest power.
Ability ability = sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
ability.addTarget(new TriumphOfGerrardTargetCreature());
sagaAbility.addChapterEffect(
this,
SagaChapter.CHAPTER_I,
SagaChapter.CHAPTER_II,
new AddCountersTargetEffect(CounterType.P1P1.createInstance()),
new TriumphOfGerrardTargetCreature()
);
// III Target creature you control with the greatest power gains flying, first strike, and lifelink until end of turn.
ability = sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III,
new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn).setText("Target creature you control with the greatest power gains flying"));
ability.addEffect(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn).setText(", first strike"));
ability.addEffect(new GainAbilityTargetEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn).setText(", and lifelink until end of turn"));
ability.addTarget(new TriumphOfGerrardTargetCreature());
Effects effects = new Effects();
effects.add(new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn)
.setText("Target creature you control with the greatest power gains flying"));
effects.add(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn)
.setText(", first strike"));
effects.add(new GainAbilityTargetEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn)
.setText(", and lifelink until end of turn"));
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_III, SagaChapter.CHAPTER_III,
effects, new Targets(new TriumphOfGerrardTargetCreature())
);
this.addAbility(sagaAbility);
}

View file

@ -30,6 +30,7 @@ package mage.abilities.common;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.Card;
import mage.constants.SagaChapter;
@ -41,6 +42,8 @@ import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.game.stack.StackAbility;
import mage.game.stack.StackObject;
import mage.target.Target;
import mage.target.Targets;
/**
*
@ -64,17 +67,44 @@ public class SagaAbility extends SimpleStaticAbility {
this.maxChapter = ability.maxChapter;
}
public Ability addChapterEffect(Card card, SagaChapter chapter, Effect effect) {
return addChapterEffect(card, chapter, chapter, effect);
public void addChapterEffect(Card card, SagaChapter chapter, Effect effect) {
addChapterEffect(card, chapter, chapter, effect);
}
public Ability addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effect effect) {
ChapterTriggeredAbility ability = new ChapterTriggeredAbility(effect, fromChapter, toChapter);
card.addAbility(ability);
public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effect effect) {
addChapterEffect(card, fromChapter, toChapter, new Effects(effect), (Target) null);
}
public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effects effects) {
addChapterEffect(card, fromChapter, toChapter, effects, (Target) null);
}
public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effect effect, Target target) {
addChapterEffect(card, fromChapter, toChapter, new Effects(effect), new Targets(target));
}
public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effects effects, Target target) {
addChapterEffect(card, fromChapter, toChapter, effects, new Targets(target));
}
public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effects effects, Targets targets) {
ChapterTriggeredAbility ability;
for (int i = fromChapter.getNumber(); i <= toChapter.getNumber(); i++) {
ability = new ChapterTriggeredAbility(null, SagaChapter.getChapter(i), toChapter);
for (Effect effect : effects) {
ability.addEffect(effect);
}
for (Target target : targets) {
ability.addTarget(target);
}
if (i > fromChapter.getNumber()) {
ability.setRuleVisible(false);
}
card.addAbility(ability);
}
if (maxChapter == null || toChapter.getNumber() > maxChapter.getNumber()) {
maxChapter = toChapter;
}
return ability;
}
public SagaChapter getMaxChapter() {
@ -106,7 +136,6 @@ class ChapterTriggeredAbility extends TriggeredAbilityImpl {
public ChapterTriggeredAbility(Effect effect, SagaChapter chapterFrom, SagaChapter chapterTo) {
super(Zone.BATTLEFIELD, effect, false);
this.chapterFrom = chapterFrom;
this.chapterTo = chapterTo;
}
public ChapterTriggeredAbility(final ChapterTriggeredAbility ability) {
@ -123,11 +152,12 @@ class ChapterTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getTargetId().equals(getSourceId()) && event.getData().equals(CounterType.LORE.getName())) {
int amountAdded = event.getAmount();
Permanent sourceSaga = game.getPermanentOrLKIBattlefield(getSourceId());
if (sourceSaga != null) {
int loreCounters = sourceSaga.getCounters(game).getCount(CounterType.LORE);
return chapterFrom.getNumber() <= loreCounters
&& chapterTo.getNumber() >= loreCounters;
return loreCounters - amountAdded < chapterFrom.getNumber()
&& chapterFrom.getNumber() <= loreCounters;
}
}
return false;

View file

@ -44,6 +44,10 @@ public class Effects extends ArrayList<Effect> {
public Effects() {
}
public Effects(Effect effect) {
this.add(effect);
}
public Effects(final Effects effects) {
for (Effect effect : effects) {
this.add(effect.copy());

View file

@ -53,4 +53,16 @@ public enum SagaChapter {
return number;
}
public static SagaChapter getChapter(int number) {
switch (number) {
case 1:
return CHAPTER_I;
case 2:
return CHAPTER_II;
case 3:
return CHAPTER_III;
default:
return null;
}
}
}

View file

@ -46,6 +46,10 @@ public class Targets extends ArrayList<Target> {
public Targets() {
}
public Targets(Target target) {
this.add(target);
}
public Targets(final Targets targets) {
for (Target target : targets) {
this.add(target.copy());
@ -151,6 +155,7 @@ public class Targets extends ArrayList<Target> {
}
return null;
}
public Targets copy() {
return new Targets(this);
}