From dd4b1684c8e6e90594623d6e82d5b0503ed1f9fd Mon Sep 17 00:00:00 2001
From: theelk801 <theelk801@gmail.com>
Date: Sat, 29 Apr 2023 19:31:27 -0400
Subject: [PATCH] some changes to how sagas are built

---
 .../src/mage/cards/a/ArniSlaysTheTroll.java   |  40 ++++---
 .../mage/cards/l/LifeOfToshiroUmezawa.java    |  16 +--
 .../src/mage/cards/t/TheTriumphOfAnax.java    |  17 +--
 .../src/mage/cards/t/TheTrueScriptures.java   |  13 +-
 .../src/mage/cards/t/TriumphOfGerrard.java    | 113 +++++-------------
 .../mage/abilities/common/SagaAbility.java    |  50 ++++----
 6 files changed, 96 insertions(+), 153 deletions(-)

diff --git a/Mage.Sets/src/mage/cards/a/ArniSlaysTheTroll.java b/Mage.Sets/src/mage/cards/a/ArniSlaysTheTroll.java
index 45b45565ce..975b30bef8 100644
--- a/Mage.Sets/src/mage/cards/a/ArniSlaysTheTroll.java
+++ b/Mage.Sets/src/mage/cards/a/ArniSlaysTheTroll.java
@@ -1,28 +1,25 @@
 package mage.cards.a;
 
-import java.util.UUID;
-
 import mage.Mana;
 import mage.abilities.common.SagaAbility;
 import mage.abilities.dynamicvalue.common.GreatestPowerAmongControlledCreaturesValue;
-import mage.abilities.effects.Effects;
 import mage.abilities.effects.common.FightTargetsEffect;
 import mage.abilities.effects.common.GainLifeEffect;
 import mage.abilities.effects.common.counter.AddCountersTargetEffect;
 import mage.abilities.effects.mana.BasicManaEffect;
-import mage.constants.SagaChapter;
-import mage.constants.SubType;
 import mage.cards.CardImpl;
 import mage.cards.CardSetInfo;
 import mage.constants.CardType;
+import mage.constants.SagaChapter;
+import mage.constants.SubType;
 import mage.counters.CounterType;
 import mage.filter.StaticFilters;
 import mage.target.TargetPermanent;
-import mage.target.Targets;
 import mage.target.common.TargetControlledCreaturePermanent;
 
+import java.util.UUID;
+
 /**
- *
  * @author weirddan455
  */
 public final class ArniSlaysTheTroll extends CardImpl {
@@ -36,20 +33,27 @@ public final class ArniSlaysTheTroll extends CardImpl {
         SagaAbility sagaAbility = new SagaAbility(this);
 
         // I — Target creature you control fights up to one target creature you don't control.
-        sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I,
-                new Effects(new FightTargetsEffect().setText(
-                        "Target creature you control fights up to one target creature you don't control"
-                )), new Targets(
-                        new TargetControlledCreaturePermanent(),
-                        new TargetPermanent(0, 1, StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL, false)
-                )
+        sagaAbility.addChapterEffect(
+                this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I,
+                ability -> {
+                    ability.addEffect(new FightTargetsEffect().setText(
+                            "Target creature you control fights up to one target creature you don't control"
+                    ));
+                    ability.addTarget(new TargetControlledCreaturePermanent());
+                    ability.addTarget(new TargetPermanent(
+                            0, 1, StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL
+                    ));
+                }
         );
 
         // II — Add {R}. Put two +1/+1 counters on up to one target creature you control.
-        sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II,
-                new Effects(new BasicManaEffect(Mana.RedMana(1)),
-                        new AddCountersTargetEffect(CounterType.P1P1.createInstance(2))
-                ), new Targets(new TargetControlledCreaturePermanent(0, 1))
+        sagaAbility.addChapterEffect(
+                this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II,
+                ability -> {
+                    ability.addEffect(new BasicManaEffect(Mana.RedMana(1)));
+                    ability.addEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)));
+                    ability.addTarget(new TargetControlledCreaturePermanent(0, 1));
+                }
         );
 
         // III — You gain life equal to the greatest power among creatures you control.
diff --git a/Mage.Sets/src/mage/cards/l/LifeOfToshiroUmezawa.java b/Mage.Sets/src/mage/cards/l/LifeOfToshiroUmezawa.java
index 8296d9ae0a..265927d627 100644
--- a/Mage.Sets/src/mage/cards/l/LifeOfToshiroUmezawa.java
+++ b/Mage.Sets/src/mage/cards/l/LifeOfToshiroUmezawa.java
@@ -2,7 +2,6 @@ package mage.cards.l;
 
 import mage.abilities.Mode;
 import mage.abilities.common.SagaAbility;
-import mage.abilities.effects.Effects;
 import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect;
 import mage.abilities.effects.common.GainLifeEffect;
 import mage.abilities.effects.common.continuous.BoostTargetEffect;
@@ -12,7 +11,6 @@ import mage.cards.CardSetInfo;
 import mage.constants.CardType;
 import mage.constants.SagaChapter;
 import mage.constants.SubType;
-import mage.target.Targets;
 import mage.target.common.TargetCreaturePermanent;
 
 import java.util.UUID;
@@ -35,13 +33,15 @@ public final class LifeOfToshiroUmezawa extends CardImpl {
         // • Target creature gets +2/+2 until end of turn.
         // • Target creature gets -1/-1 until end of turn.
         // • You gain 2 life.
-        Mode mode = new Mode(new BoostTargetEffect(-1, -1));
-        mode.addTarget(new TargetCreaturePermanent());
         sagaAbility.addChapterEffect(
-                this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II,
-                new Effects(new BoostTargetEffect(2, 2)),
-                new Targets(new TargetCreaturePermanent()), false,
-                null, mode, new Mode(new GainLifeEffect(2))
+                this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, false,
+                ability -> {
+                    ability.addEffect(new BoostTargetEffect(2, 2));
+                    ability.addTarget(new TargetCreaturePermanent());
+                    ability.addMode(new Mode(new BoostTargetEffect(-1, -1))
+                            .addTarget(new TargetCreaturePermanent()));
+                    ability.addMode(new Mode(new GainLifeEffect(2)));
+                }
         );
 
         // III — Exile this Saga, then return it to the battlefield transformed under your control.
diff --git a/Mage.Sets/src/mage/cards/t/TheTriumphOfAnax.java b/Mage.Sets/src/mage/cards/t/TheTriumphOfAnax.java
index d7ad3daadb..162d570331 100644
--- a/Mage.Sets/src/mage/cards/t/TheTriumphOfAnax.java
+++ b/Mage.Sets/src/mage/cards/t/TheTriumphOfAnax.java
@@ -18,7 +18,6 @@ import mage.constants.SubType;
 import mage.counters.CounterType;
 import mage.filter.StaticFilters;
 import mage.target.TargetPermanent;
-import mage.target.Targets;
 import mage.target.common.TargetControlledCreaturePermanent;
 import mage.target.common.TargetCreaturePermanent;
 
@@ -54,13 +53,15 @@ public final class TheTriumphOfAnax extends CardImpl {
         // IV — Target creature you control fights up to one target creature you don't control.
         sagaAbility.addChapterEffect(
                 this, SagaChapter.CHAPTER_IV, SagaChapter.CHAPTER_IV,
-                new Effects(new FightTargetsEffect().setText(
-                        "Target creature you control fights up to one target creature you don't control. " +
-                                "<i>(Each deals damage equal to its power to the other.)</i>")),
-                new Targets(
-                        new TargetControlledCreaturePermanent(),
-                        new TargetPermanent(0, 1,
-                                StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL, false))
+                ability -> {
+                    ability.addEffect(new FightTargetsEffect().setText(
+                            "Target creature you control fights up to one target creature you don't control. " +
+                                    "<i>(Each deals damage equal to its power to the other.)</i>"));
+                    ability.addTarget(new TargetControlledCreaturePermanent());
+                    ability.addTarget(new TargetPermanent(
+                            0, 1, StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL
+                    ));
+                }
         );
         this.addAbility(sagaAbility);
     }
diff --git a/Mage.Sets/src/mage/cards/t/TheTrueScriptures.java b/Mage.Sets/src/mage/cards/t/TheTrueScriptures.java
index 322e4f9bef..6450e28728 100644
--- a/Mage.Sets/src/mage/cards/t/TheTrueScriptures.java
+++ b/Mage.Sets/src/mage/cards/t/TheTrueScriptures.java
@@ -3,7 +3,6 @@ package mage.cards.t;
 import mage.abilities.Ability;
 import mage.abilities.common.SagaAbility;
 import mage.abilities.dynamicvalue.common.StaticValue;
-import mage.abilities.effects.Effects;
 import mage.abilities.effects.OneShotEffect;
 import mage.abilities.effects.common.DestroyTargetEffect;
 import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect;
@@ -21,7 +20,6 @@ import mage.filter.predicate.permanent.ControllerIdPredicate;
 import mage.game.Game;
 import mage.players.Player;
 import mage.target.TargetPermanent;
-import mage.target.Targets;
 import mage.target.targetadjustment.TargetAdjuster;
 import mage.target.targetpointer.EachTargetPointer;
 
@@ -47,11 +45,12 @@ public final class TheTrueScriptures extends CardImpl {
 
         // I -- For each opponent, destroy up to one target creature or planeswalker that player controls.
         sagaAbility.addChapterEffect(
-                this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I,
-                new Effects(
-                        new DestroyTargetEffect().setTargetPointer(new EachTargetPointer())
-                                .setText("for each opponent, destroy up to one target creature or planeswalker that player controls")
-                ), new Targets(), false, TheTrueScripturesAdjuster.instance
+                this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, false,
+                ability -> {
+                    ability.addEffect(new DestroyTargetEffect().setTargetPointer(new EachTargetPointer())
+                            .setText("for each opponent, destroy up to one target creature or planeswalker that player controls"));
+                    ability.setTargetAdjuster(TheTrueScripturesAdjuster.instance);
+                }
         );
 
         // II -- Each opponent discards three cards, then mills three cards.
diff --git a/Mage.Sets/src/mage/cards/t/TriumphOfGerrard.java b/Mage.Sets/src/mage/cards/t/TriumphOfGerrard.java
index dd68b5f8b3..7f8b12be48 100644
--- a/Mage.Sets/src/mage/cards/t/TriumphOfGerrard.java
+++ b/Mage.Sets/src/mage/cards/t/TriumphOfGerrard.java
@@ -1,14 +1,6 @@
-
 package mage.cards.t;
 
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-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;
@@ -21,17 +13,25 @@ import mage.constants.Duration;
 import mage.constants.SagaChapter;
 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;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.predicate.permanent.GreatestPowerControlledPredicate;
+import mage.target.TargetPermanent;
+
+import java.util.UUID;
 
 /**
- *
  * @author LevelX2
  */
 public final class TriumphOfGerrard extends CardImpl {
 
+    private static final FilterPermanent filter
+            = new FilterControlledCreaturePermanent("creture you control with the greatest power");
+
+    static {
+        filter.add(GreatestPowerControlledPredicate.instance);
+    }
+
     public TriumphOfGerrard(UUID ownerId, CardSetInfo setInfo) {
         super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
 
@@ -39,28 +39,32 @@ public final 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);
+
         // I, II — Put a +1/+1 counter on target creature you control with the greatest power.
         sagaAbility.addChapterEffect(
                 this,
                 SagaChapter.CHAPTER_I,
                 SagaChapter.CHAPTER_II,
                 new AddCountersTargetEffect(CounterType.P1P1.createInstance()),
-                new TriumphOfGerrardTargetCreature()
+                new TargetPermanent(filter)
         );
         // III — Target creature you control with the greatest power gains flying, first strike, and lifelink until end of turn.
-        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())
+                ability -> {
+                    ability.addEffect(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 TargetPermanent(filter));
+                }
         );
         this.addAbility(sagaAbility);
-
     }
 
     private TriumphOfGerrard(final TriumphOfGerrard card) {
@@ -72,66 +76,3 @@ public final class TriumphOfGerrard extends CardImpl {
         return new TriumphOfGerrard(this);
     }
 }
-
-class TriumphOfGerrardTargetCreature extends TargetControlledCreaturePermanent {
-
-    public TriumphOfGerrardTargetCreature() {
-        super();
-        setTargetName("creature you control with the greatest power");
-    }
-
-    public TriumphOfGerrardTargetCreature(final TriumphOfGerrardTargetCreature target) {
-        super(target);
-    }
-
-    @Override
-    public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) {
-        if (super.canTarget(controllerId, id, source, game)) {
-            int maxPower = 0;
-            for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) {
-                if (permanent.getPower().getValue() > maxPower) {
-                    maxPower = permanent.getPower().getValue();
-                }
-            }
-            Permanent targetPermanent = game.getPermanent(id);
-            if (targetPermanent != null) {
-                return targetPermanent.getPower().getValue() == maxPower;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public Set<UUID> possibleTargets(UUID sourceControllerId, Ability source, Game game) {
-        int maxPower = 0;
-        List<Permanent> activePermanents = game.getBattlefield().getActivePermanents(filter, sourceControllerId, source, game);
-        Set<UUID> possibleTargets = new HashSet<>();
-        MageObject targetSource = game.getObject(source);
-        if(targetSource == null){
-            return possibleTargets;
-        }
-        for (Permanent permanent : activePermanents) {
-            if (permanent.getPower().getValue() > maxPower) {
-                maxPower = permanent.getPower().getValue();
-            }
-        }
-        for (Permanent permanent : activePermanents) {
-            if (!targets.containsKey(permanent.getId()) && permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) {
-                if (permanent.getPower().getValue() == maxPower) {
-                    possibleTargets.add(permanent.getId());
-                }
-            }
-        }
-        return possibleTargets;
-    }
-
-    @Override
-    public boolean canChoose(UUID sourceControllerId, Ability source, Game game) {
-        return !possibleTargets(sourceControllerId, source, game).isEmpty();
-    }
-
-    @Override
-    public TriumphOfGerrardTargetCreature copy() {
-        return new TriumphOfGerrardTargetCreature(this);
-    }
-}
diff --git a/Mage/src/main/java/mage/abilities/common/SagaAbility.java b/Mage/src/main/java/mage/abilities/common/SagaAbility.java
index 21a1a863bf..b707cff270 100644
--- a/Mage/src/main/java/mage/abilities/common/SagaAbility.java
+++ b/Mage/src/main/java/mage/abilities/common/SagaAbility.java
@@ -1,7 +1,6 @@
 package mage.abilities.common;
 
 import mage.abilities.Ability;
-import mage.abilities.Mode;
 import mage.abilities.TriggeredAbility;
 import mage.abilities.TriggeredAbilityImpl;
 import mage.abilities.effects.Effect;
@@ -19,11 +18,10 @@ import mage.game.stack.StackAbility;
 import mage.game.stack.StackObject;
 import mage.players.Player;
 import mage.target.Target;
-import mage.target.Targets;
-import mage.target.targetadjustment.TargetAdjuster;
 import mage.util.CardUtil;
 
 import java.util.Arrays;
+import java.util.function.Consumer;
 
 /**
  * @author LevelX2
@@ -89,40 +87,40 @@ public class SagaAbility extends SimpleStaticAbility {
         addChapterEffect(card, fromChapter, toChapter, effect, target, false);
     }
 
-    public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effect effect, Target target, boolean optional) {
-        addChapterEffect(card, fromChapter, toChapter, new Effects(effect), new Targets(target), optional, null);
-    }
-
     public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effects effects, Target target) {
-        addChapterEffect(card, fromChapter, toChapter, effects, new Targets(target));
+        addChapterEffect(card, fromChapter, toChapter, effects, target, false);
     }
 
-    public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effects effects, Targets targets) {
-        addChapterEffect(card, fromChapter, toChapter, effects, targets, false, null);
+    public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effect effect, Target target, boolean optional) {
+        addChapterEffect(card, fromChapter, toChapter, new Effects(effect), target, optional);
     }
 
-    public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effects effects, Targets targets, boolean optional, TargetAdjuster targetAdjuster, Mode... modes) {
-        for (int i = fromChapter.getNumber(); i <= toChapter.getNumber(); i++) {
-            ChapterTriggeredAbility ability = new ChapterTriggeredAbility(null, SagaChapter.getChapter(i), toChapter, optional, readAhead);
+    public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Consumer<TriggeredAbility> applier) {
+        addChapterEffect(card, fromChapter, toChapter, false, applier);
+    }
+
+    public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effects effects, Target target, boolean optional) {
+        addChapterEffect(card, fromChapter, toChapter, optional, ability -> {
             for (Effect effect : effects) {
                 if (effect != null) {
                     ability.addEffect(effect.copy());
                 }
             }
-            for (Target target : targets) {
-                if (target != null) {
-                    ability.addTarget(target.copy());
-                }
-            }
-            for (Mode mode : modes) {
-                ability.addMode(mode.copy());
+            if (target != null) {
+                ability.addTarget(target.copy());
             }
+        });
+    }
+
+    public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, boolean optional, Consumer<TriggeredAbility> applier) {
+        for (int i = fromChapter.getNumber(); i <= toChapter.getNumber(); i++) {
+            ChapterTriggeredAbility ability = new ChapterTriggeredAbility(
+                    SagaChapter.getChapter(i), toChapter, optional, readAhead
+            );
+            applier.accept(ability);
             if (i > fromChapter.getNumber()) {
                 ability.setRuleVisible(false);
             }
-            if (targetAdjuster != null) {
-                ability.setTargetAdjuster(targetAdjuster);
-            }
             card.addAbility(ability);
         }
     }
@@ -210,14 +208,14 @@ class ChapterTriggeredAbility extends TriggeredAbilityImpl {
     private final SagaChapter chapterFrom, chapterTo;
     private final boolean readAhead;
 
-    public ChapterTriggeredAbility(Effect effect, SagaChapter chapterFrom, SagaChapter chapterTo, boolean optional, boolean readAhead) {
-        super(Zone.ALL, effect, optional);
+    ChapterTriggeredAbility(SagaChapter chapterFrom, SagaChapter chapterTo, boolean optional, boolean readAhead) {
+        super(Zone.ALL, null, optional);
         this.chapterFrom = chapterFrom;
         this.chapterTo = chapterTo;
         this.readAhead = readAhead;
     }
 
-    public ChapterTriggeredAbility(final ChapterTriggeredAbility ability) {
+    private ChapterTriggeredAbility(final ChapterTriggeredAbility ability) {
         super(ability);
         this.chapterFrom = ability.chapterFrom;
         this.chapterTo = ability.chapterTo;