mirror of
https://github.com/correl/mage.git
synced 2025-03-13 01:09:53 -09:00
Merge pull request #4941 from magefree/fixSagas
Fixed implementation of sagas to sacrifice at the correct time
This commit is contained in:
commit
6fba02b2b0
14 changed files with 234 additions and 110 deletions
Mage.Sets/src/mage/cards
c
p
s
t
Mage/src/main/java/mage
abilities
cards
constants
game
target
|
@ -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());
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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}");
|
||||
|
||||
|
@ -63,15 +70,19 @@ 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));
|
||||
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.
|
||||
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));
|
||||
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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -28,11 +28,12 @@
|
|||
package mage.abilities.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
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.cards.CardImpl;
|
||||
import mage.constants.SagaChapter;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
|
@ -42,22 +43,24 @@ 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class SagaAbility extends TriggeredAbilityImpl {
|
||||
public class SagaAbility extends SimpleStaticAbility {
|
||||
|
||||
private SagaChapter maxChapter;
|
||||
|
||||
public SagaAbility(Card card, SagaChapter maxChapter) {
|
||||
super(Zone.ALL, new AddCountersSourceEffect(CounterType.LORE.createInstance()), false);
|
||||
this.usesStack = false;
|
||||
super(Zone.ALL, new AddCountersSourceEffect(CounterType.LORE.createInstance()));
|
||||
this.maxChapter = maxChapter;
|
||||
this.setRuleVisible(false);
|
||||
((CardImpl) card).addAbility(new SagaAddCounterAbility(maxChapter));
|
||||
|
||||
Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LORE.createInstance()));
|
||||
ability.setRuleVisible(false);
|
||||
card.addAbility(ability);
|
||||
}
|
||||
|
||||
public SagaAbility(final SagaAbility ability) {
|
||||
|
@ -65,38 +68,55 @@ public class SagaAbility extends TriggeredAbilityImpl {
|
|||
this.maxChapter = ability.maxChapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
|
||||
public void addChapterEffect(Card card, SagaChapter chapter, Effect effect) {
|
||||
addChapterEffect(card, chapter, chapter, effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
return event.getTargetId().equals(getSourceId());
|
||||
public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effect effect) {
|
||||
addChapterEffect(card, fromChapter, toChapter, new Effects(effect), (Target) null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "When {this} enters the battlefield, " + super.getRule();
|
||||
public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effects effects) {
|
||||
addChapterEffect(card, fromChapter, toChapter, effects, (Target) null);
|
||||
}
|
||||
|
||||
public Ability addChapterEffect(Card card, SagaChapter chapter, Effect effect) {
|
||||
return addChapterEffect(card, chapter, chapter, effect);
|
||||
public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effect effect, Target target) {
|
||||
addChapterEffect(card, fromChapter, toChapter, new Effects(effect), new Targets(target));
|
||||
}
|
||||
|
||||
public Ability addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effect effect) {
|
||||
ChapterTriggeredAbility ability = new ChapterTriggeredAbility(effect, fromChapter, toChapter);
|
||||
((CardImpl) card).addAbility(ability);
|
||||
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() {
|
||||
return maxChapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "<i>(As this Saga enters and after your draw step, add a lore counter. Sacrifice after " + maxChapter.toString() + ".)</i> ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SagaAbility copy() {
|
||||
return new SagaAbility(this);
|
||||
|
@ -108,6 +128,10 @@ public class SagaAbility extends TriggeredAbilityImpl {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isChapterAbility(TriggeredAbility ability) {
|
||||
return ability instanceof ChapterTriggeredAbility;
|
||||
}
|
||||
}
|
||||
|
||||
class ChapterTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
@ -115,7 +139,7 @@ class ChapterTriggeredAbility extends TriggeredAbilityImpl {
|
|||
SagaChapter chapterFrom, chapterTo;
|
||||
|
||||
public ChapterTriggeredAbility(Effect effect, SagaChapter chapterFrom, SagaChapter chapterTo) {
|
||||
super(Zone.BATTLEFIELD, effect, false);
|
||||
super(Zone.ALL, effect, false);
|
||||
this.chapterFrom = chapterFrom;
|
||||
this.chapterTo = chapterTo;
|
||||
}
|
||||
|
@ -134,12 +158,14 @@ 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();
|
||||
int loreCounters = amountAdded;
|
||||
Permanent sourceSaga = game.getPermanentOrLKIBattlefield(getSourceId());
|
||||
if (sourceSaga != null) {
|
||||
int loreCounters = sourceSaga.getCounters(game).getCount(CounterType.LORE);
|
||||
return chapterFrom.getNumber() <= loreCounters
|
||||
&& chapterTo.getNumber() >= loreCounters;
|
||||
if (sourceSaga != null) { // If it's entering the battlefield, it won't be found so we assume it had no counters
|
||||
loreCounters = sourceSaga.getCounters(game).getCount(CounterType.LORE);
|
||||
}
|
||||
return loreCounters - amountAdded < chapterFrom.getNumber()
|
||||
&& chapterFrom.getNumber() <= loreCounters;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -179,39 +205,39 @@ class ChapterTriggeredAbility extends TriggeredAbilityImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class SagaAddCounterAbility extends TriggeredAbilityImpl {
|
||||
|
||||
SagaChapter maxChapter;
|
||||
|
||||
SagaAddCounterAbility(SagaChapter maxChapter) {
|
||||
super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.LORE.createInstance()), false);
|
||||
this.usesStack = false;
|
||||
this.maxChapter = maxChapter;
|
||||
}
|
||||
|
||||
SagaAddCounterAbility(final SagaAddCounterAbility ability) {
|
||||
super(ability);
|
||||
this.maxChapter = ability.maxChapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SagaAddCounterAbility copy() {
|
||||
return new SagaAddCounterAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == EventType.PRECOMBAT_MAIN_PHASE_PRE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
return event.getPlayerId().equals(this.controllerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "<i>(As this Saga enters and after your draw step, add a lore counter. Sacrifice after " + maxChapter.toString() + ".)</i> ";
|
||||
}
|
||||
|
||||
}
|
||||
//class SagaAddCounterAbility extends TriggeredAbilityImpl {
|
||||
//
|
||||
// SagaChapter maxChapter;
|
||||
//
|
||||
// SagaAddCounterAbility(SagaChapter maxChapter) {
|
||||
// super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.LORE.createInstance()), false);
|
||||
// this.usesStack = false;
|
||||
// this.maxChapter = maxChapter;
|
||||
// }
|
||||
//
|
||||
// SagaAddCounterAbility(final SagaAddCounterAbility ability) {
|
||||
// super(ability);
|
||||
// this.maxChapter = ability.maxChapter;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public SagaAddCounterAbility copy() {
|
||||
// return new SagaAddCounterAbility(this);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean checkEventType(GameEvent event, Game game) {
|
||||
// return event.getType() == EventType.PRECOMBAT_MAIN_PHASE_PRE;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean checkTrigger(GameEvent event, Game game) {
|
||||
// return event.getPlayerId().equals(this.controllerId);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String getRule() {
|
||||
// return "<i>(As this Saga enters and after your draw step, add a lore counter. Sacrifice after " + maxChapter.toString() + ".)</i> ";
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -157,6 +157,8 @@ public interface Card extends MageObject {
|
|||
|
||||
Counters getCounters(GameState state);
|
||||
|
||||
void addAbility(Ability ability);
|
||||
|
||||
boolean addCounters(Counter counter, Ability source, Game game);
|
||||
|
||||
boolean addCounters(Counter counter, Ability source, Game game, List<UUID> appliedEffects);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2031,21 +2031,30 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
}
|
||||
}
|
||||
}
|
||||
// Remove Saga enchantment if last chapter is reached and chapter ability has left the stack
|
||||
// 704.5s If the number of lore counters on a Saga permanent is greater than or equal to its final chapter number
|
||||
// and it isn’t the source of a chapter ability that has triggered but not yet left the stack, that Saga’s controller sacrifices it.
|
||||
if (perm.hasSubtype(SubType.SAGA, this)) {
|
||||
for (Ability sagaAbility : perm.getAbilities()) {
|
||||
if (sagaAbility instanceof SagaAbility) {
|
||||
int maxChapter = ((SagaAbility) sagaAbility).getMaxChapter().getNumber();
|
||||
if (maxChapter <= perm.getCounters(this).getCount(CounterType.LORE)) {
|
||||
boolean noChapterAbilityOnStack = true;
|
||||
boolean noChapterAbilityTriggeredOrOnStack = true;
|
||||
// Check chapter abilities on stack
|
||||
for (StackObject stackObject : getStack()) {
|
||||
if (stackObject.getSourceId().equals(perm.getId()) && SagaAbility.isChapterAbility(stackObject)) {
|
||||
noChapterAbilityOnStack = false;
|
||||
noChapterAbilityTriggeredOrOnStack = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (noChapterAbilityOnStack) {
|
||||
if (noChapterAbilityTriggeredOrOnStack) {
|
||||
for (TriggeredAbility trigger : state.getTriggered(perm.getControllerId())) {
|
||||
if (SagaAbility.isChapterAbility(trigger) && trigger.getSourceId().equals(perm.getId())) {
|
||||
noChapterAbilityTriggeredOrOnStack = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (noChapterAbilityTriggeredOrOnStack) {
|
||||
// After the last chapter ability has left the stack, you'll sacrifice the Saga
|
||||
perm.sacrifice(perm.getId(), this);
|
||||
somethingHappened = true;
|
||||
|
|
|
@ -25,11 +25,17 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game.turn;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.SubType;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.mageobject.SubtypePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -37,6 +43,12 @@ import mage.game.events.GameEvent.EventType;
|
|||
*/
|
||||
public class PreCombatMainStep extends Step {
|
||||
|
||||
private static final FilterPermanent filter = new FilterPermanent("Saga");
|
||||
|
||||
static {
|
||||
filter.add(new SubtypePredicate(SubType.SAGA));
|
||||
}
|
||||
|
||||
public PreCombatMainStep() {
|
||||
super(PhaseStep.PRECOMBAT_MAIN, true);
|
||||
this.stepEvent = EventType.PRECOMBAT_MAIN_STEP;
|
||||
|
@ -48,6 +60,16 @@ public class PreCombatMainStep extends Step {
|
|||
super(step);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginStep(Game game, UUID activePlayerId) {
|
||||
super.beginStep(game, activePlayerId);
|
||||
for (Permanent saga : game.getBattlefield().getAllActivePermanents(filter, activePlayerId, game)) {
|
||||
if (saga != null) {
|
||||
saga.addCounters(CounterType.LORE.createInstance(), null, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreCombatMainStep copy() {
|
||||
return new PreCombatMainStep(this);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue