From c70fcbab792a2d2459d281d8fee95d21c14fa5a4 Mon Sep 17 00:00:00 2001 From: Steven Knipe Date: Fri, 15 Aug 2025 03:34:33 -0700 Subject: [PATCH 01/60] fix TopographyTracker applying to opponents' creatures --- Mage.Sets/src/mage/cards/t/TopographyTracker.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Mage.Sets/src/mage/cards/t/TopographyTracker.java b/Mage.Sets/src/mage/cards/t/TopographyTracker.java index d404986ae14..5a3d8128b50 100644 --- a/Mage.Sets/src/mage/cards/t/TopographyTracker.java +++ b/Mage.Sets/src/mage/cards/t/TopographyTracker.java @@ -1,26 +1,26 @@ package mage.cards.t; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.CreateTokenEffect; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; import mage.game.events.ExploreEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.game.permanent.token.MapToken; +import java.util.UUID; + /** - * * @author Grath */ public final class TopographyTracker extends CardImpl { @@ -74,7 +74,7 @@ class TopographyTrackerEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); - return permanent != null && permanent.isControlledBy(event.getPlayerId()); + return permanent != null && permanent.isControlledBy(source.getPlayerId()); } @Override @@ -83,4 +83,4 @@ class TopographyTrackerEffect extends ReplacementEffectImpl { exploreEvent.doubleExplores(); return false; } -} \ No newline at end of file +} From 0fc1eba02ce28368dce898ee9f96b3b0e33943fb Mon Sep 17 00:00:00 2001 From: Steven Knipe Date: Fri, 15 Aug 2025 04:01:18 -0700 Subject: [PATCH 02/60] Fix for my incorrect fix --- Mage.Sets/src/mage/cards/t/TopographyTracker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/t/TopographyTracker.java b/Mage.Sets/src/mage/cards/t/TopographyTracker.java index 5a3d8128b50..50d92e42044 100644 --- a/Mage.Sets/src/mage/cards/t/TopographyTracker.java +++ b/Mage.Sets/src/mage/cards/t/TopographyTracker.java @@ -74,7 +74,7 @@ class TopographyTrackerEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); - return permanent != null && permanent.isControlledBy(source.getPlayerId()); + return permanent != null && permanent.isControlledBy(source.getControllerId()); } @Override From 076dcf1cf93dd25a51ff14f86895783e4c72500c Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 07:51:55 -0400 Subject: [PATCH 03/60] [TLA] Implement Rebellious Captives --- Mage.Sets/src/mage/cards/b/Badgermole.java | 4 +- .../mage/cards/b/BumiEclecticEarthbender.java | 5 +- .../src/mage/cards/d/DaiLiIndoctrination.java | 5 +- Mage.Sets/src/mage/cards/e/EarthRumble.java | 5 +- .../mage/cards/e/EarthVillageRuffians.java | 5 +- .../src/mage/cards/e/EarthbendingLesson.java | 5 +- .../src/mage/cards/h/HaruHiddenTalent.java | 8 ++- .../src/mage/cards/r/RebelliousCaptives.java | 49 +++++++++++++++++++ .../mage/cards/t/TophTheFirstMetalbender.java | 5 +- .../src/mage/sets/AvatarTheLastAirbender.java | 1 + .../common/TargetControlledLandPermanent.java | 30 ++++++++++++ Utils/mtg-cards-data.txt | 2 +- 12 files changed, 98 insertions(+), 26 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/r/RebelliousCaptives.java create mode 100644 Mage/src/main/java/mage/target/common/TargetControlledLandPermanent.java diff --git a/Mage.Sets/src/mage/cards/b/Badgermole.java b/Mage.Sets/src/mage/cards/b/Badgermole.java index 0c6326da4e9..24d46635ab7 100644 --- a/Mage.Sets/src/mage/cards/b/Badgermole.java +++ b/Mage.Sets/src/mage/cards/b/Badgermole.java @@ -13,7 +13,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.target.TargetPermanent; +import mage.target.common.TargetControlledLandPermanent; import java.util.UUID; @@ -32,7 +32,7 @@ public final class Badgermole extends CardImpl { // When this creature enters, earthbend 2. Ability ability = new EntersBattlefieldTriggeredAbility(new EarthbendTargetEffect(2)); - ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND)); + ability.addTarget(new TargetControlledLandPermanent()); this.addAbility(ability); // Creatures you control with +1/+1 counters on them have trample. diff --git a/Mage.Sets/src/mage/cards/b/BumiEclecticEarthbender.java b/Mage.Sets/src/mage/cards/b/BumiEclecticEarthbender.java index f8ad29546ec..6fc1617a324 100644 --- a/Mage.Sets/src/mage/cards/b/BumiEclecticEarthbender.java +++ b/Mage.Sets/src/mage/cards/b/BumiEclecticEarthbender.java @@ -13,9 +13,8 @@ import mage.constants.SubType; import mage.constants.SuperType; import mage.counters.CounterType; import mage.filter.FilterPermanent; -import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; -import mage.target.TargetPermanent; +import mage.target.common.TargetControlledLandPermanent; import java.util.UUID; @@ -42,7 +41,7 @@ public final class BumiEclecticEarthbender extends CardImpl { // When Bumi enters, earthbend 1. Ability ability = new EntersBattlefieldTriggeredAbility(new EarthbendTargetEffect(1)); - ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND)); + ability.addTarget(new TargetControlledLandPermanent()); this.addAbility(ability); // Whenever Bumi attacks, put two +1/+1 counters on each land creature you control. diff --git a/Mage.Sets/src/mage/cards/d/DaiLiIndoctrination.java b/Mage.Sets/src/mage/cards/d/DaiLiIndoctrination.java index 7b5a7c24c06..04a7b59fc45 100644 --- a/Mage.Sets/src/mage/cards/d/DaiLiIndoctrination.java +++ b/Mage.Sets/src/mage/cards/d/DaiLiIndoctrination.java @@ -8,10 +8,9 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.filter.FilterCard; -import mage.filter.StaticFilters; import mage.filter.common.FilterPermanentCard; import mage.filter.predicate.Predicates; -import mage.target.TargetPermanent; +import mage.target.common.TargetControlledLandPermanent; import mage.target.common.TargetOpponent; import java.util.UUID; @@ -39,7 +38,7 @@ public final class DaiLiIndoctrination extends CardImpl { // * Earthbend 2. this.getSpellAbility().addMode(new Mode(new EarthbendTargetEffect(2)) - .addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND))); + .addTarget(new TargetControlledLandPermanent())); } private DaiLiIndoctrination(final DaiLiIndoctrination card) { diff --git a/Mage.Sets/src/mage/cards/e/EarthRumble.java b/Mage.Sets/src/mage/cards/e/EarthRumble.java index cda332c1739..9a90e31c967 100644 --- a/Mage.Sets/src/mage/cards/e/EarthRumble.java +++ b/Mage.Sets/src/mage/cards/e/EarthRumble.java @@ -9,10 +9,9 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; -import mage.filter.StaticFilters; import mage.game.Game; -import mage.target.TargetPermanent; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetControlledLandPermanent; import mage.target.common.TargetOpponentsCreaturePermanent; import java.util.UUID; @@ -27,7 +26,7 @@ public final class EarthRumble extends CardImpl { // Earthbend 2. When you do, up to one target creature you control fights target creature an opponent controls. this.getSpellAbility().addEffect(new EarthbendTargetEffect(2)); - this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND)); + this.getSpellAbility().addTarget(new TargetControlledLandPermanent()); this.getSpellAbility().addEffect(new EarthRumbleEffect()); } diff --git a/Mage.Sets/src/mage/cards/e/EarthVillageRuffians.java b/Mage.Sets/src/mage/cards/e/EarthVillageRuffians.java index 19a0aeb8634..25245ce79be 100644 --- a/Mage.Sets/src/mage/cards/e/EarthVillageRuffians.java +++ b/Mage.Sets/src/mage/cards/e/EarthVillageRuffians.java @@ -8,8 +8,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.filter.StaticFilters; -import mage.target.TargetPermanent; +import mage.target.common.TargetControlledLandPermanent; import java.util.UUID; @@ -29,7 +28,7 @@ public final class EarthVillageRuffians extends CardImpl { // When this creature dies, earthbend 2. Ability ability = new DiesSourceTriggeredAbility(new EarthbendTargetEffect(2)); - ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND)); + ability.addTarget(new TargetControlledLandPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/EarthbendingLesson.java b/Mage.Sets/src/mage/cards/e/EarthbendingLesson.java index 5a44f3d666c..61962ad7d52 100644 --- a/Mage.Sets/src/mage/cards/e/EarthbendingLesson.java +++ b/Mage.Sets/src/mage/cards/e/EarthbendingLesson.java @@ -5,8 +5,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.filter.StaticFilters; -import mage.target.TargetPermanent; +import mage.target.common.TargetControlledLandPermanent; import java.util.UUID; @@ -22,7 +21,7 @@ public final class EarthbendingLesson extends CardImpl { // Earthbend 4. this.getSpellAbility().addEffect(new EarthbendTargetEffect(4)); - this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND)); + this.getSpellAbility().addTarget(new TargetControlledLandPermanent()); } private EarthbendingLesson(final EarthbendingLesson card) { diff --git a/Mage.Sets/src/mage/cards/h/HaruHiddenTalent.java b/Mage.Sets/src/mage/cards/h/HaruHiddenTalent.java index 4c46979c96d..a7a1f7f82a5 100644 --- a/Mage.Sets/src/mage/cards/h/HaruHiddenTalent.java +++ b/Mage.Sets/src/mage/cards/h/HaruHiddenTalent.java @@ -10,15 +10,13 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.filter.FilterPermanent; -import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.AnotherPredicate; -import mage.target.TargetPermanent; +import mage.target.common.TargetControlledLandPermanent; import java.util.UUID; /** - * * @author Grath */ public final class HaruHiddenTalent extends CardImpl { @@ -30,7 +28,7 @@ public final class HaruHiddenTalent extends CardImpl { } public HaruHiddenTalent(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.PEASANT); this.subtype.add(SubType.ALLY); @@ -40,7 +38,7 @@ public final class HaruHiddenTalent extends CardImpl { // Whenever another Ally you control enters, earthbend 1. Ability ability = new EntersBattlefieldAllTriggeredAbility(new EarthbendTargetEffect(1), filter); - ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND)); + ability.addTarget(new TargetControlledLandPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RebelliousCaptives.java b/Mage.Sets/src/mage/cards/r/RebelliousCaptives.java new file mode 100644 index 00000000000..bfb736d6453 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RebelliousCaptives.java @@ -0,0 +1,49 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.keyword.EarthbendTargetEffect; +import mage.abilities.keyword.ExhaustAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.target.common.TargetControlledLandPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RebelliousCaptives extends CardImpl { + + public RebelliousCaptives(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.PEASANT); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Exhaust -- {6}: Put two +1/+1 counters on this creature, then earthbend 2. + Ability ability = new ExhaustAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), new GenericManaCost(6) + ); + ability.addEffect(new EarthbendTargetEffect(2).concatBy(", then")); + ability.addTarget(new TargetControlledLandPermanent()); + this.addAbility(ability); + } + + private RebelliousCaptives(final RebelliousCaptives card) { + super(card); + } + + @Override + public RebelliousCaptives copy() { + return new RebelliousCaptives(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TophTheFirstMetalbender.java b/Mage.Sets/src/mage/cards/t/TophTheFirstMetalbender.java index bb8cb053c15..480c7237efd 100644 --- a/Mage.Sets/src/mage/cards/t/TophTheFirstMetalbender.java +++ b/Mage.Sets/src/mage/cards/t/TophTheFirstMetalbender.java @@ -10,12 +10,11 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.FilterPermanent; -import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.filter.predicate.permanent.TokenPredicate; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.target.TargetPermanent; +import mage.target.common.TargetControlledLandPermanent; import java.util.UUID; @@ -39,7 +38,7 @@ public final class TophTheFirstMetalbender extends CardImpl { // At the beginning of your end step, earthbend 2. Ability ability = new BeginningOfEndStepTriggeredAbility(new EarthbendTargetEffect(2)); - ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND)); + ability.addTarget(new TargetControlledLandPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 2362c1b005b..eac1a3a824b 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -74,6 +74,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Ozai's Cruelty", 113, Rarity.UNCOMMON, mage.cards.o.OzaisCruelty.class)); cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Pretending Poxbearers", 237, Rarity.COMMON, mage.cards.p.PretendingPoxbearers.class)); + cards.add(new SetCardInfo("Rebellious Captives", 191, Rarity.COMMON, mage.cards.r.RebelliousCaptives.class)); cards.add(new SetCardInfo("Redirect Lightning", 151, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Redirect Lightning", 343, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Saber-Tooth Moose-Lion", 194, Rarity.COMMON, mage.cards.s.SaberToothMooseLion.class)); diff --git a/Mage/src/main/java/mage/target/common/TargetControlledLandPermanent.java b/Mage/src/main/java/mage/target/common/TargetControlledLandPermanent.java new file mode 100644 index 00000000000..6329c37bb9a --- /dev/null +++ b/Mage/src/main/java/mage/target/common/TargetControlledLandPermanent.java @@ -0,0 +1,30 @@ +package mage.target.common; + +import mage.filter.StaticFilters; + +/** + * @author TheElk801 + */ +public class TargetControlledLandPermanent extends TargetControlledPermanent { + + public TargetControlledLandPermanent() { + this(1); + } + + public TargetControlledLandPermanent(int numTargets) { + this(numTargets, numTargets); + } + + public TargetControlledLandPermanent(int minNumTargets, int maxNumTargets) { + super(minNumTargets, maxNumTargets, maxNumTargets > 1 ? StaticFilters.FILTER_CONTROLLED_PERMANENT_LANDS : StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND, false); + } + + protected TargetControlledLandPermanent(final TargetControlledLandPermanent target) { + super(target); + } + + @Override + public TargetControlledLandPermanent copy() { + return new TargetControlledLandPermanent(this); + } +} diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 902175316da..9c8920538a8 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -59780,7 +59780,7 @@ Haru, Hidden Talent|Avatar: The Last Airbender|182|U|{1}{G}|Legendary Creature - Ostrich-Horse|Avatar: The Last Airbender|188|C|{2}{G}|Creature - Bird Horse|3|1|When this creature enters, mill three cards. You may put a land card from among them into your hand. If you don't, put a +1/+1 counter on this creature.| Pillar Launch|Avatar: The Last Airbender|189|C|{G}|Instant|||Target creature gets +2/+2 and gains reach until end of turn. Untap it.| Raucous Audience|Avatar: The Last Airbender|190|C|{1}{G}|Creature - Human Citizen|2|1|{T}: Add {G}. If you control a creature with power 4 or greater, add {G}{G} instead.| -Rebellious Captives|Avatar: The Last Airbender|191|C|{1}{G}|Creature - Human Peasant Ally|2|2|Exhaust -- {G}: Put two +1/+1 counters on this creature, then earthbend 2.| +Rebellious Captives|Avatar: The Last Airbender|191|C|{1}{G}|Creature - Human Peasant Ally|2|2|Exhaust -- {6}: Put two +1/+1 counters on this creature, then earthbend 2.| Rocky Rebuke|Avatar: The Last Airbender|193|C|{1}{G}|Instant|||Target creature you control deals damage equal to its power to target creature an opponent controls.| Saber-Tooth Moose-Lion|Avatar: The Last Airbender|194|C|{4}{G}{G}|Creature - Elk Cat|7|7|Reach$Forestcycling {2}| Toph, the Blind Bandit|Avatar: The Last Airbender|198|U|{2}{G}|Legendary Creature - Human Warrior Ally|*|3|When Toph enters, earthbend 2.$Toph's power is equal to the number of +1/+1 counters on lands you control.| From 7f1c5c37a125c3be16082896515bc59b9c6bac8a Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 07:53:07 -0400 Subject: [PATCH 04/60] [TLA] Implement Fire Sages --- Mage.Sets/src/mage/cards/f/FireSages.java | 46 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FireSages.java diff --git a/Mage.Sets/src/mage/cards/f/FireSages.java b/Mage.Sets/src/mage/cards/f/FireSages.java new file mode 100644 index 00000000000..dd7794a3380 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FireSages.java @@ -0,0 +1,46 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.FirebendingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FireSages extends CardImpl { + + public FireSages(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Firebending 1 + this.addAbility(new FirebendingAbility(1)); + + // {1}{R}{R}: Put a +1/+1 counter on this creature. + this.addAbility(new SimpleActivatedAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl<>("{1}{R}{R}") + )); + } + + private FireSages(final FireSages card) { + super(card); + } + + @Override + public FireSages copy() { + return new FireSages(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index eac1a3a824b..dad80682a37 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -57,6 +57,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Fire Lord Zuko", 221, Rarity.RARE, mage.cards.f.FireLordZuko.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fire Lord Zuko", 360, Rarity.RARE, mage.cards.f.FireLordZuko.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fire Nation Attacks", 133, Rarity.UNCOMMON, mage.cards.f.FireNationAttacks.class)); + cards.add(new SetCardInfo("Fire Sages", 136, Rarity.UNCOMMON, mage.cards.f.FireSages.class)); cards.add(new SetCardInfo("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Glider Kids", 21, Rarity.COMMON, mage.cards.g.GliderKids.class)); cards.add(new SetCardInfo("Haru, Hidden Talent", 182, Rarity.UNCOMMON, mage.cards.h.HaruHiddenTalent.class)); From 4c4137ac79618152c404f4d8d63d52457d9c2b6c Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 07:55:56 -0400 Subject: [PATCH 05/60] [TLA] Implement First-Time Flyer --- .../src/mage/cards/f/FirstTimeFlyer.java | 56 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 57 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FirstTimeFlyer.java diff --git a/Mage.Sets/src/mage/cards/f/FirstTimeFlyer.java b/Mage.Sets/src/mage/cards/f/FirstTimeFlyer.java new file mode 100644 index 00000000000..945c34d9b2b --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FirstTimeFlyer.java @@ -0,0 +1,56 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.CardsInControllerGraveyardCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.FilterCard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FirstTimeFlyer extends CardImpl { + + private static final Condition condition = new CardsInControllerGraveyardCondition(1, new FilterCard(SubType.LESSON)); + private static final Hint hint = new ConditionHint(condition, "There's a Lesson card in your graveyard"); + + public FirstTimeFlyer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.PILOT); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // This creature gets +1/+1 as long as there's a Lesson card in your graveyard. + this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( + new BoostSourceEffect(1, 1, Duration.WhileOnBattlefield), + condition, "{this} gets +1/+1 as long as there's a Lesson card in your graveyard" + )).addHint(hint)); + } + + private FirstTimeFlyer(final FirstTimeFlyer card) { + super(card); + } + + @Override + public FirstTimeFlyer copy() { + return new FirstTimeFlyer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index dad80682a37..ee3638582d3 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -58,6 +58,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Fire Lord Zuko", 360, Rarity.RARE, mage.cards.f.FireLordZuko.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fire Nation Attacks", 133, Rarity.UNCOMMON, mage.cards.f.FireNationAttacks.class)); cards.add(new SetCardInfo("Fire Sages", 136, Rarity.UNCOMMON, mage.cards.f.FireSages.class)); + cards.add(new SetCardInfo("First-Time Flyer", 49, Rarity.COMMON, mage.cards.f.FirstTimeFlyer.class)); cards.add(new SetCardInfo("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Glider Kids", 21, Rarity.COMMON, mage.cards.g.GliderKids.class)); cards.add(new SetCardInfo("Haru, Hidden Talent", 182, Rarity.UNCOMMON, mage.cards.h.HaruHiddenTalent.class)); From 4b2ea25e9699199604cd99a1d09567b42925f937 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:03:17 -0400 Subject: [PATCH 06/60] [TLA] Implement Fire Nation Engineer --- .../src/mage/cards/f/FireNationEngineer.java | 63 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 64 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FireNationEngineer.java diff --git a/Mage.Sets/src/mage/cards/f/FireNationEngineer.java b/Mage.Sets/src/mage/cards/f/FireNationEngineer.java new file mode 100644 index 00000000000..93f4c6fd078 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FireNationEngineer.java @@ -0,0 +1,63 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.condition.common.RaidCondition; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.hint.common.RaidHint; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.target.TargetPermanent; +import mage.watchers.common.PlayerAttackedWatcher; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FireNationEngineer extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledPermanent("another target creature or Vehicle you control"); + + static { + filter.add(AnotherPredicate.instance); + filter.add(Predicates.or( + CardType.CREATURE.getPredicate(), + SubType.VEHICLE.getPredicate() + )); + } + + public FireNationEngineer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ARTIFICER); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Raid -- At the beginning of your end step, if you attacked this turn, put a +1/+1 counter on another target creature or Vehicle you control. + Ability ability = new BeginningOfEndStepTriggeredAbility( + new AddCountersTargetEffect(CounterType.P1P1.createInstance()) + ).withInterveningIf(RaidCondition.instance); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability.setAbilityWord(AbilityWord.RAID).addHint(RaidHint.instance), new PlayerAttackedWatcher()); + } + + private FireNationEngineer(final FireNationEngineer card) { + super(card); + } + + @Override + public FireNationEngineer copy() { + return new FireNationEngineer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index ee3638582d3..2406da2c7f0 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -57,6 +57,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Fire Lord Zuko", 221, Rarity.RARE, mage.cards.f.FireLordZuko.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fire Lord Zuko", 360, Rarity.RARE, mage.cards.f.FireLordZuko.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fire Nation Attacks", 133, Rarity.UNCOMMON, mage.cards.f.FireNationAttacks.class)); + cards.add(new SetCardInfo("Fire Nation Engineer", 99, Rarity.UNCOMMON, mage.cards.f.FireNationEngineer.class)); cards.add(new SetCardInfo("Fire Sages", 136, Rarity.UNCOMMON, mage.cards.f.FireSages.class)); cards.add(new SetCardInfo("First-Time Flyer", 49, Rarity.COMMON, mage.cards.f.FirstTimeFlyer.class)); cards.add(new SetCardInfo("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); From 23d7ba229307ef85c78aac3dd1147da8e2ed97c0 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:04:34 -0400 Subject: [PATCH 07/60] [TLA] Implement Flexible Waterbender --- .../src/mage/cards/f/FlexibleWaterbender.java | 47 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 48 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FlexibleWaterbender.java diff --git a/Mage.Sets/src/mage/cards/f/FlexibleWaterbender.java b/Mage.Sets/src/mage/cards/f/FlexibleWaterbender.java new file mode 100644 index 00000000000..c315c30d5e6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FlexibleWaterbender.java @@ -0,0 +1,47 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.WaterbendCost; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FlexibleWaterbender extends CardImpl { + + public FlexibleWaterbender(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(2); + this.toughness = new MageInt(5); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Waterbend {3}: This creature has base power and toughness 5/2 until end of turn. + this.addAbility(new SimpleActivatedAbility( + new SetBasePowerToughnessSourceEffect(3, 2, Duration.EndOfTurn), new WaterbendCost(3) + )); + } + + private FlexibleWaterbender(final FlexibleWaterbender card) { + super(card); + } + + @Override + public FlexibleWaterbender copy() { + return new FlexibleWaterbender(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 2406da2c7f0..ef7b1f4ff7f 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -60,6 +60,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Fire Nation Engineer", 99, Rarity.UNCOMMON, mage.cards.f.FireNationEngineer.class)); cards.add(new SetCardInfo("Fire Sages", 136, Rarity.UNCOMMON, mage.cards.f.FireSages.class)); cards.add(new SetCardInfo("First-Time Flyer", 49, Rarity.COMMON, mage.cards.f.FirstTimeFlyer.class)); + cards.add(new SetCardInfo("Flexible Waterbender", 50, Rarity.COMMON, mage.cards.f.FlexibleWaterbender.class)); cards.add(new SetCardInfo("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Glider Kids", 21, Rarity.COMMON, mage.cards.g.GliderKids.class)); cards.add(new SetCardInfo("Haru, Hidden Talent", 182, Rarity.UNCOMMON, mage.cards.h.HaruHiddenTalent.class)); From 6f05e94e5fbe6378f7f8dd9da808a4acdadc2e7a Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:05:22 -0400 Subject: [PATCH 08/60] [TLA] Implement Geyser Leaper --- Mage.Sets/src/mage/cards/g/GeyserLeaper.java | 46 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GeyserLeaper.java diff --git a/Mage.Sets/src/mage/cards/g/GeyserLeaper.java b/Mage.Sets/src/mage/cards/g/GeyserLeaper.java new file mode 100644 index 00000000000..ac92da1f133 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GeyserLeaper.java @@ -0,0 +1,46 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.WaterbendCost; +import mage.abilities.effects.common.DrawDiscardControllerEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GeyserLeaper extends CardImpl { + + public GeyserLeaper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Waterbend {4}: Draw a card, then discard a card. + this.addAbility(new SimpleActivatedAbility( + new DrawDiscardControllerEffect(1, 1), new WaterbendCost(4) + )); + } + + private GeyserLeaper(final GeyserLeaper card) { + super(card); + } + + @Override + public GeyserLeaper copy() { + return new GeyserLeaper(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index ef7b1f4ff7f..37a1994ff1d 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -62,6 +62,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("First-Time Flyer", 49, Rarity.COMMON, mage.cards.f.FirstTimeFlyer.class)); cards.add(new SetCardInfo("Flexible Waterbender", 50, Rarity.COMMON, mage.cards.f.FlexibleWaterbender.class)); cards.add(new SetCardInfo("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Geyser Leaper", 52, Rarity.COMMON, mage.cards.g.GeyserLeaper.class)); cards.add(new SetCardInfo("Glider Kids", 21, Rarity.COMMON, mage.cards.g.GliderKids.class)); cards.add(new SetCardInfo("Haru, Hidden Talent", 182, Rarity.UNCOMMON, mage.cards.h.HaruHiddenTalent.class)); cards.add(new SetCardInfo("Heartless Act", 103, Rarity.UNCOMMON, mage.cards.h.HeartlessAct.class)); From 3c25c1931c66e3f95aad2eb207648113783c5f9b Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:06:14 -0400 Subject: [PATCH 09/60] [TLA] Implement Giant Koi --- Mage.Sets/src/mage/cards/g/GiantKoi.java | 46 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GiantKoi.java diff --git a/Mage.Sets/src/mage/cards/g/GiantKoi.java b/Mage.Sets/src/mage/cards/g/GiantKoi.java new file mode 100644 index 00000000000..1ff553cbd44 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GiantKoi.java @@ -0,0 +1,46 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.WaterbendCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect; +import mage.abilities.keyword.IslandcyclingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GiantKoi extends CardImpl { + + public GiantKoi(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{U}"); + + this.subtype.add(SubType.FISH); + this.power = new MageInt(5); + this.toughness = new MageInt(7); + + // Waterbend {3}: This creature can't be blocked this turn. + this.addAbility(new SimpleActivatedAbility( + new CantBeBlockedSourceEffect(Duration.EndOfTurn), new WaterbendCost(3) + )); + + // Islandcycling {2} + this.addAbility(new IslandcyclingAbility(new ManaCostsImpl<>("{2}"))); + } + + private GiantKoi(final GiantKoi card) { + super(card); + } + + @Override + public GiantKoi copy() { + return new GiantKoi(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 37a1994ff1d..501b9554a70 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -63,6 +63,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Flexible Waterbender", 50, Rarity.COMMON, mage.cards.f.FlexibleWaterbender.class)); cards.add(new SetCardInfo("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Geyser Leaper", 52, Rarity.COMMON, mage.cards.g.GeyserLeaper.class)); + cards.add(new SetCardInfo("Giant Koi", 53, Rarity.COMMON, mage.cards.g.GiantKoi.class)); cards.add(new SetCardInfo("Glider Kids", 21, Rarity.COMMON, mage.cards.g.GliderKids.class)); cards.add(new SetCardInfo("Haru, Hidden Talent", 182, Rarity.UNCOMMON, mage.cards.h.HaruHiddenTalent.class)); cards.add(new SetCardInfo("Heartless Act", 103, Rarity.UNCOMMON, mage.cards.h.HeartlessAct.class)); From 790e938f4006a5b8763dfc408744570b0b9ce66d Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:08:00 -0400 Subject: [PATCH 10/60] [TLA] Implement Hog-Monkey --- Mage.Sets/src/mage/cards/h/HogMonkey.java | 53 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 54 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HogMonkey.java diff --git a/Mage.Sets/src/mage/cards/h/HogMonkey.java b/Mage.Sets/src/mage/cards/h/HogMonkey.java new file mode 100644 index 00000000000..07a53c05ff4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HogMonkey.java @@ -0,0 +1,53 @@ +package mage.cards.h; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.ExhaustAbility; +import mage.abilities.keyword.MenaceAbility; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class HogMonkey extends CardImpl { + + public HogMonkey(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.subtype.add(SubType.BOAR); + this.subtype.add(SubType.MONKEY); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // At the beginning of combat on your turn, target creature you control with a +1/+1 counter on it gains menace until end of turn. + Ability ability = new BeginningOfCombatTriggeredAbility(new GainAbilityTargetEffect(new MenaceAbility(false))); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_P1P1)); + this.addAbility(ability); + + // Exhaust -- {5}: Put two +1/+1 counters on this creature. + this.addAbility(new ExhaustAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), new GenericManaCost(5) + )); + } + + private HogMonkey(final HogMonkey card) { + super(card); + } + + @Override + public HogMonkey copy() { + return new HogMonkey(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 501b9554a70..adb56947d89 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -67,6 +67,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Glider Kids", 21, Rarity.COMMON, mage.cards.g.GliderKids.class)); cards.add(new SetCardInfo("Haru, Hidden Talent", 182, Rarity.UNCOMMON, mage.cards.h.HaruHiddenTalent.class)); cards.add(new SetCardInfo("Heartless Act", 103, Rarity.UNCOMMON, mage.cards.h.HeartlessAct.class)); + cards.add(new SetCardInfo("Hog-Monkey", 104, Rarity.COMMON, mage.cards.h.HogMonkey.class)); cards.add(new SetCardInfo("Iguana Parrot", 56, Rarity.COMMON, mage.cards.i.IguanaParrot.class)); cards.add(new SetCardInfo("Island", 288, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("It'll Quench Ya!", 58, Rarity.COMMON, mage.cards.i.ItllQuenchYa.class)); From 82c0aab35ab05e025e6d710c36b247c40f55891f Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:09:14 -0400 Subject: [PATCH 11/60] [TLA] Implement Jeong Jeong's Deserters --- .../mage/cards/j/JeongJeongsDeserters.java | 44 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 45 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/j/JeongJeongsDeserters.java diff --git a/Mage.Sets/src/mage/cards/j/JeongJeongsDeserters.java b/Mage.Sets/src/mage/cards/j/JeongJeongsDeserters.java new file mode 100644 index 00000000000..da65b8b4f03 --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JeongJeongsDeserters.java @@ -0,0 +1,44 @@ +package mage.cards.j; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class JeongJeongsDeserters extends CardImpl { + + public JeongJeongsDeserters(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.REBEL); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // When this creature enters, put a +1/+1 counter on target creature. + Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance())); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + private JeongJeongsDeserters(final JeongJeongsDeserters card) { + super(card); + } + + @Override + public JeongJeongsDeserters copy() { + return new JeongJeongsDeserters(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index adb56947d89..d821f568b83 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -71,6 +71,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Iguana Parrot", 56, Rarity.COMMON, mage.cards.i.IguanaParrot.class)); cards.add(new SetCardInfo("Island", 288, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("It'll Quench Ya!", 58, Rarity.COMMON, mage.cards.i.ItllQuenchYa.class)); + cards.add(new SetCardInfo("Jeong Jeong's Deserters", 25, Rarity.COMMON, mage.cards.j.JeongJeongsDeserters.class)); cards.add(new SetCardInfo("Katara, Water Tribe's Hope", 231, Rarity.RARE, mage.cards.k.KataraWaterTribesHope.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Katara, Water Tribe's Hope", 351, Rarity.RARE, mage.cards.k.KataraWaterTribesHope.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Katara, the Fearless", 230, Rarity.RARE, mage.cards.k.KataraTheFearless.class, NON_FULL_USE_VARIOUS)); From f1e588faa3b36eee2d2e687efe66d143af55dc4e Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:10:42 -0400 Subject: [PATCH 12/60] [TLA] Implement Katara, Bending Prodigy --- .../mage/cards/k/KataraBendingProdigy.java | 51 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 52 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KataraBendingProdigy.java diff --git a/Mage.Sets/src/mage/cards/k/KataraBendingProdigy.java b/Mage.Sets/src/mage/cards/k/KataraBendingProdigy.java new file mode 100644 index 00000000000..0a40304dd68 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KataraBendingProdigy.java @@ -0,0 +1,51 @@ +package mage.cards.k; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.SourceTappedCondition; +import mage.abilities.costs.common.WaterbendCost; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.counters.CounterType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class KataraBendingProdigy extends CardImpl { + + public KataraBendingProdigy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // At the beginning of your end step, if Katara is tapped, put a +1/+1 counter on her. + this.addAbility(new BeginningOfEndStepTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()).setText("put a +1/+1 counter on her") + ).withInterveningIf(SourceTappedCondition.TAPPED)); + + // Waterbend {6}: Draw a card. + this.addAbility(new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new WaterbendCost(6))); + } + + private KataraBendingProdigy(final KataraBendingProdigy card) { + super(card); + } + + @Override + public KataraBendingProdigy copy() { + return new KataraBendingProdigy(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index d821f568b83..467e2f2cd29 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -72,6 +72,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Island", 288, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("It'll Quench Ya!", 58, Rarity.COMMON, mage.cards.i.ItllQuenchYa.class)); cards.add(new SetCardInfo("Jeong Jeong's Deserters", 25, Rarity.COMMON, mage.cards.j.JeongJeongsDeserters.class)); + cards.add(new SetCardInfo("Katara, Bending Prodigy", 59, Rarity.UNCOMMON, mage.cards.k.KataraBendingProdigy.class)); cards.add(new SetCardInfo("Katara, Water Tribe's Hope", 231, Rarity.RARE, mage.cards.k.KataraWaterTribesHope.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Katara, Water Tribe's Hope", 351, Rarity.RARE, mage.cards.k.KataraWaterTribesHope.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Katara, the Fearless", 230, Rarity.RARE, mage.cards.k.KataraTheFearless.class, NON_FULL_USE_VARIOUS)); From 936c0b3a9c2ddfcb56797f671aec1d3eb565f80d Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:15:23 -0400 Subject: [PATCH 13/60] [TLA] Implement Master Pakku --- Mage.Sets/src/mage/cards/m/MasterPakku.java | 57 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 58 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MasterPakku.java diff --git a/Mage.Sets/src/mage/cards/m/MasterPakku.java b/Mage.Sets/src/mage/cards/m/MasterPakku.java new file mode 100644 index 00000000000..2ee107fed73 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MasterPakku.java @@ -0,0 +1,57 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BecomesTappedSourceTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount; +import mage.abilities.effects.common.MillCardsTargetEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.ProwessAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.FilterCard; +import mage.target.TargetPlayer; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MasterPakku extends CardImpl { + + private static final DynamicValue xValue = new CardsInControllerGraveyardCount(new FilterCard(SubType.LESSON, "Lesson cards"), null); + private static final Hint hint = new ValueHint("Lesson cards in your graveyard", xValue); + + public MasterPakku(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ADVISOR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Prowess + this.addAbility(new ProwessAbility()); + + // Whenever Master Pakku becomes tapped, target player mills X cards, where X is the number of Lesson cards in your graveyard. + Ability ability = new BecomesTappedSourceTriggeredAbility(new MillCardsTargetEffect(xValue)); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability.addHint(hint)); + } + + private MasterPakku(final MasterPakku card) { + super(card); + } + + @Override + public MasterPakku copy() { + return new MasterPakku(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 467e2f2cd29..a51338b181b 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -79,6 +79,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Katara, the Fearless", 350, Rarity.RARE, mage.cards.k.KataraTheFearless.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Katara, the Fearless", 361, Rarity.RARE, mage.cards.k.KataraTheFearless.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lightning Strike", 146, Rarity.COMMON, mage.cards.l.LightningStrike.class)); + cards.add(new SetCardInfo("Master Pakku", 63, Rarity.UNCOMMON, mage.cards.m.MasterPakku.class)); cards.add(new SetCardInfo("Mountain", 290, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Ozai's Cruelty", 113, Rarity.UNCOMMON, mage.cards.o.OzaisCruelty.class)); cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); From 6677bd17543147395e67684fb79ddd049155a7c7 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:17:15 -0400 Subject: [PATCH 14/60] [TLA] Implement Master Piandao --- Mage.Sets/src/mage/cards/m/MasterPiandao.java | 60 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 61 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MasterPiandao.java diff --git a/Mage.Sets/src/mage/cards/m/MasterPiandao.java b/Mage.Sets/src/mage/cards/m/MasterPiandao.java new file mode 100644 index 00000000000..3c9174dd44f --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MasterPiandao.java @@ -0,0 +1,60 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.PutCards; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MasterPiandao extends CardImpl { + + private static final FilterCard filter = new FilterCard("Ally, Equipment, or Lesson card"); + + static { + filter.add(Predicates.or( + SubType.ALLY.getPredicate(), + SubType.EQUIPMENT.getPredicate(), + SubType.LESSON.getPredicate() + )); + } + + public MasterPiandao(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + + // Whenever Master Piandao attacks, look at the top four cards of your library. You may reveal an Ally, Equipment, or Lesson card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. + this.addAbility(new AttacksTriggeredAbility(new LookLibraryAndPickControllerEffect( + 4, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM + ))); + } + + private MasterPiandao(final MasterPiandao card) { + super(card); + } + + @Override + public MasterPiandao copy() { + return new MasterPiandao(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index a51338b181b..275e63d1540 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -80,6 +80,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Katara, the Fearless", 361, Rarity.RARE, mage.cards.k.KataraTheFearless.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lightning Strike", 146, Rarity.COMMON, mage.cards.l.LightningStrike.class)); cards.add(new SetCardInfo("Master Pakku", 63, Rarity.UNCOMMON, mage.cards.m.MasterPakku.class)); + cards.add(new SetCardInfo("Master Piandao", 28, Rarity.UNCOMMON, mage.cards.m.MasterPiandao.class)); cards.add(new SetCardInfo("Mountain", 290, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Ozai's Cruelty", 113, Rarity.UNCOMMON, mage.cards.o.OzaisCruelty.class)); cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); From 31e9a2beb6bb5346e0b6d83ac7a4c7fbe939ae15 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:18:18 -0400 Subject: [PATCH 15/60] [TLA] Implement Merchant of Many Hats --- .../src/mage/cards/m/MerchantOfManyHats.java | 43 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 44 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MerchantOfManyHats.java diff --git a/Mage.Sets/src/mage/cards/m/MerchantOfManyHats.java b/Mage.Sets/src/mage/cards/m/MerchantOfManyHats.java new file mode 100644 index 00000000000..7e16cb253af --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MerchantOfManyHats.java @@ -0,0 +1,43 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MerchantOfManyHats extends CardImpl { + + public MerchantOfManyHats(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.PEASANT); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {2}{B}: Return this card from your graveyard to your hand. + this.addAbility(new SimpleActivatedAbility( + Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), new ManaCostsImpl<>("{2}{B}") + )); + } + + private MerchantOfManyHats(final MerchantOfManyHats card) { + super(card); + } + + @Override + public MerchantOfManyHats copy() { + return new MerchantOfManyHats(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 275e63d1540..4afc841f788 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -81,6 +81,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Lightning Strike", 146, Rarity.COMMON, mage.cards.l.LightningStrike.class)); cards.add(new SetCardInfo("Master Pakku", 63, Rarity.UNCOMMON, mage.cards.m.MasterPakku.class)); cards.add(new SetCardInfo("Master Piandao", 28, Rarity.UNCOMMON, mage.cards.m.MasterPiandao.class)); + cards.add(new SetCardInfo("Merchant of Many Hats", 110, Rarity.COMMON, mage.cards.m.MerchantOfManyHats.class)); cards.add(new SetCardInfo("Mountain", 290, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Ozai's Cruelty", 113, Rarity.UNCOMMON, mage.cards.o.OzaisCruelty.class)); cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); From e34613f11ef8683a4f971c9e01ba14b3400eceb3 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:19:07 -0400 Subject: [PATCH 16/60] [TLA] Implement Mongoose Lizard --- .../src/mage/cards/m/MongooseLizard.java | 51 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 52 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MongooseLizard.java diff --git a/Mage.Sets/src/mage/cards/m/MongooseLizard.java b/Mage.Sets/src/mage/cards/m/MongooseLizard.java new file mode 100644 index 00000000000..c11c6e6004d --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MongooseLizard.java @@ -0,0 +1,51 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.MenaceAbility; +import mage.abilities.keyword.MountaincyclingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.common.TargetAnyTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MongooseLizard extends CardImpl { + + public MongooseLizard(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); + + this.subtype.add(SubType.MONGOOSE); + this.subtype.add(SubType.LIZARD); + this.power = new MageInt(5); + this.toughness = new MageInt(6); + + // Menace + this.addAbility(new MenaceAbility()); + + // When this creature enters, it deals 1 damage to any target. + Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(1, "it")); + ability.addTarget(new TargetAnyTarget()); + this.addAbility(ability); + + // Mountaincycling {2} + this.addAbility(new MountaincyclingAbility(new ManaCostsImpl<>("{2}"))); + } + + private MongooseLizard(final MongooseLizard card) { + super(card); + } + + @Override + public MongooseLizard copy() { + return new MongooseLizard(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 4afc841f788..ba0ffdd225f 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -82,6 +82,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Master Pakku", 63, Rarity.UNCOMMON, mage.cards.m.MasterPakku.class)); cards.add(new SetCardInfo("Master Piandao", 28, Rarity.UNCOMMON, mage.cards.m.MasterPiandao.class)); cards.add(new SetCardInfo("Merchant of Many Hats", 110, Rarity.COMMON, mage.cards.m.MerchantOfManyHats.class)); + cards.add(new SetCardInfo("Mongoose Lizard", 148, Rarity.COMMON, mage.cards.m.MongooseLizard.class)); cards.add(new SetCardInfo("Mountain", 290, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Ozai's Cruelty", 113, Rarity.UNCOMMON, mage.cards.o.OzaisCruelty.class)); cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); From 366c038f6e0ae79b7cb1f283694906558af0238a Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:20:25 -0400 Subject: [PATCH 17/60] [TLA] Implement Ostrich Horse --- Mage.Sets/src/mage/cards/o/OstrichHorse.java | 43 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 44 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/o/OstrichHorse.java diff --git a/Mage.Sets/src/mage/cards/o/OstrichHorse.java b/Mage.Sets/src/mage/cards/o/OstrichHorse.java new file mode 100644 index 00000000000..4c4131db6f5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OstrichHorse.java @@ -0,0 +1,43 @@ +package mage.cards.o; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.MillThenPutInHandEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class OstrichHorse extends CardImpl { + + public OstrichHorse(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.BIRD); + this.subtype.add(SubType.HORSE); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // When this creature enters, mill three cards. You may put a land card from among them into your hand. If you don't, put a +1/+1 counter on this creature. + this.addAbility(new EntersBattlefieldTriggeredAbility(new MillThenPutInHandEffect( + 3, StaticFilters.FILTER_CARD_LAND, new AddCountersSourceEffect(CounterType.P1P1.createInstance()) + ))); + } + + private OstrichHorse(final OstrichHorse card) { + super(card); + } + + @Override + public OstrichHorse copy() { + return new OstrichHorse(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index ba0ffdd225f..307c1e157b8 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -84,6 +84,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Merchant of Many Hats", 110, Rarity.COMMON, mage.cards.m.MerchantOfManyHats.class)); cards.add(new SetCardInfo("Mongoose Lizard", 148, Rarity.COMMON, mage.cards.m.MongooseLizard.class)); cards.add(new SetCardInfo("Mountain", 290, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Ostrich-Horse", 188, Rarity.COMMON, mage.cards.o.OstrichHorse.class)); cards.add(new SetCardInfo("Ozai's Cruelty", 113, Rarity.UNCOMMON, mage.cards.o.OzaisCruelty.class)); cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Pretending Poxbearers", 237, Rarity.COMMON, mage.cards.p.PretendingPoxbearers.class)); From 60ed1b7e6d6563ab9dd5d4759e8e0675c756d12f Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:22:13 -0400 Subject: [PATCH 18/60] [TLA] Implement Otter-Penguin --- Mage.Sets/src/mage/cards/o/OtterPenguin.java | 43 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 44 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/o/OtterPenguin.java diff --git a/Mage.Sets/src/mage/cards/o/OtterPenguin.java b/Mage.Sets/src/mage/cards/o/OtterPenguin.java new file mode 100644 index 00000000000..8154ea837e1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OtterPenguin.java @@ -0,0 +1,43 @@ +package mage.cards.o; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DrawNthCardTriggeredAbility; +import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class OtterPenguin extends CardImpl { + + public OtterPenguin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.OTTER); + this.subtype.add(SubType.BIRD); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Whenever you draw your second card each turn, this creature gets +1/+2 until end of turn and can't be blocked this turn. + Ability ability = new DrawNthCardTriggeredAbility(new BoostSourceEffect(1, 2, Duration.EndOfTurn)); + ability.addEffect(new CantBeBlockedSourceEffect(Duration.EndOfTurn).setText("and can't be blocked this turn")); + this.addAbility(ability); + } + + private OtterPenguin(final OtterPenguin card) { + super(card); + } + + @Override + public OtterPenguin copy() { + return new OtterPenguin(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 307c1e157b8..97a39dc7b14 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -85,6 +85,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Mongoose Lizard", 148, Rarity.COMMON, mage.cards.m.MongooseLizard.class)); cards.add(new SetCardInfo("Mountain", 290, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Ostrich-Horse", 188, Rarity.COMMON, mage.cards.o.OstrichHorse.class)); + cards.add(new SetCardInfo("Otter-Penguin", 67, Rarity.COMMON, mage.cards.o.OtterPenguin.class)); cards.add(new SetCardInfo("Ozai's Cruelty", 113, Rarity.UNCOMMON, mage.cards.o.OzaisCruelty.class)); cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Pretending Poxbearers", 237, Rarity.COMMON, mage.cards.p.PretendingPoxbearers.class)); From e8c04a58960452ba104dc3deffadc781a393b666 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:23:53 -0400 Subject: [PATCH 19/60] [TLA] Implement Pillar Launch --- Mage.Sets/src/mage/cards/p/PillarLaunch.java | 37 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PillarLaunch.java diff --git a/Mage.Sets/src/mage/cards/p/PillarLaunch.java b/Mage.Sets/src/mage/cards/p/PillarLaunch.java new file mode 100644 index 00000000000..53beb87d8d7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PillarLaunch.java @@ -0,0 +1,37 @@ +package mage.cards.p; + +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PillarLaunch extends CardImpl { + + public PillarLaunch(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}"); + + // Target creature gets +2/+2 and gains reach until end of turn. Untap it. + this.getSpellAbility().addEffect(new BoostTargetEffect(2, 2).setText("target creature gets +2/+2")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(ReachAbility.getInstance()).setText("and gain reach until end of turn")); + this.getSpellAbility().addEffect(new UntapTargetEffect("Untap it")); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + private PillarLaunch(final PillarLaunch card) { + super(card); + } + + @Override + public PillarLaunch copy() { + return new PillarLaunch(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 97a39dc7b14..124e06d82ef 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -87,6 +87,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Ostrich-Horse", 188, Rarity.COMMON, mage.cards.o.OstrichHorse.class)); cards.add(new SetCardInfo("Otter-Penguin", 67, Rarity.COMMON, mage.cards.o.OtterPenguin.class)); cards.add(new SetCardInfo("Ozai's Cruelty", 113, Rarity.UNCOMMON, mage.cards.o.OzaisCruelty.class)); + cards.add(new SetCardInfo("Pillar Launch", 189, Rarity.COMMON, mage.cards.p.PillarLaunch.class)); cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Pretending Poxbearers", 237, Rarity.COMMON, mage.cards.p.PretendingPoxbearers.class)); cards.add(new SetCardInfo("Rebellious Captives", 191, Rarity.COMMON, mage.cards.r.RebelliousCaptives.class)); From c2893d89a2b2a68523bacbddc0410d3e45c3d8ff Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:25:29 -0400 Subject: [PATCH 20/60] [TLA] Implement Rabaroo Troop --- Mage.Sets/src/mage/cards/r/RabarooTroop.java | 49 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + .../src/main/java/mage/constants/SubType.java | 1 + 3 files changed, 51 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RabarooTroop.java diff --git a/Mage.Sets/src/mage/cards/r/RabarooTroop.java b/Mage.Sets/src/mage/cards/r/RabarooTroop.java new file mode 100644 index 00000000000..e62ca233ca2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RabarooTroop.java @@ -0,0 +1,49 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.LandfallAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.PlainscyclingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RabarooTroop extends CardImpl { + + public RabarooTroop(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}"); + + this.subtype.add(SubType.RABBIT); + this.subtype.add(SubType.KANGAROO); + this.power = new MageInt(3); + this.toughness = new MageInt(5); + + // Landfall -- Whenever a land you control enters, this creature gains flying until end of turn and you gain 1 life. + Ability ability = new LandfallAbility(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn)); + ability.addEffect(new GainLifeEffect(1).concatBy("and")); + this.addAbility(ability); + + // Plainscycling {2} + this.addAbility(new PlainscyclingAbility(new ManaCostsImpl<>("{2}"))); + } + + private RabarooTroop(final RabarooTroop card) { + super(card); + } + + @Override + public RabarooTroop copy() { + return new RabarooTroop(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 124e06d82ef..4285a131f64 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -90,6 +90,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Pillar Launch", 189, Rarity.COMMON, mage.cards.p.PillarLaunch.class)); cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Pretending Poxbearers", 237, Rarity.COMMON, mage.cards.p.PretendingPoxbearers.class)); + cards.add(new SetCardInfo("Rabaroo Troop", 32, Rarity.COMMON, mage.cards.r.RabarooTroop.class)); cards.add(new SetCardInfo("Rebellious Captives", 191, Rarity.COMMON, mage.cards.r.RebelliousCaptives.class)); cards.add(new SetCardInfo("Redirect Lightning", 151, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Redirect Lightning", 343, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index 53c9ecd2fe3..549383e2414 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -246,6 +246,7 @@ public enum SubType { JUGGERNAUT("Juggernaut", SubTypeSet.CreatureType), // K KALEESH("Kaleesh", SubTypeSet.CreatureType, true), // Star Wars + KANGAROO("Kangaroo", SubTypeSet.CreatureType), KAVU("Kavu", SubTypeSet.CreatureType), KELDOR("KelDor", SubTypeSet.CreatureType, true), KILLBOT("Killbot", SubTypeSet.CreatureType, true), // Unstable From 309d7415a0e67f832f05c98e81a50c5405f7ebdc Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:27:25 -0400 Subject: [PATCH 21/60] [TLA] Implement Raucous Audience --- .../src/mage/cards/r/RaucousAudience.java | 46 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RaucousAudience.java diff --git a/Mage.Sets/src/mage/cards/r/RaucousAudience.java b/Mage.Sets/src/mage/cards/r/RaucousAudience.java new file mode 100644 index 00000000000..70ea6650c62 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RaucousAudience.java @@ -0,0 +1,46 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.Mana; +import mage.abilities.condition.common.FerociousCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.decorator.ConditionalManaEffect; +import mage.abilities.effects.mana.BasicManaEffect; +import mage.abilities.hint.common.FerociousHint; +import mage.abilities.mana.SimpleManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RaucousAudience extends CardImpl { + + public RaucousAudience(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CITIZEN); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // {T}: Add {G}. If you control a creature with power 4 or greater, add {G}{G} instead. + this.addAbility(new SimpleManaAbility(new ConditionalManaEffect( + new BasicManaEffect(Mana.GreenMana(2)), new BasicManaEffect(Mana.GreenMana(1)), + FerociousCondition.instance, "Add {G}. If you control a creature with power 4 or greater, add {G}{G} instead." + ), new TapSourceCost()).addHint(FerociousHint.instance)); + } + + private RaucousAudience(final RaucousAudience card) { + super(card); + } + + @Override + public RaucousAudience copy() { + return new RaucousAudience(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 4285a131f64..c6aba0d507a 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -91,6 +91,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Pretending Poxbearers", 237, Rarity.COMMON, mage.cards.p.PretendingPoxbearers.class)); cards.add(new SetCardInfo("Rabaroo Troop", 32, Rarity.COMMON, mage.cards.r.RabarooTroop.class)); + cards.add(new SetCardInfo("Raucous Audience", 190, Rarity.COMMON, mage.cards.r.RaucousAudience.class)); cards.add(new SetCardInfo("Rebellious Captives", 191, Rarity.COMMON, mage.cards.r.RebelliousCaptives.class)); cards.add(new SetCardInfo("Redirect Lightning", 151, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Redirect Lightning", 343, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS)); From 4de08db7f558db513f45b08236f4fea370223125 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:29:16 -0400 Subject: [PATCH 22/60] [TLA] Implement Rocky Rebuke --- Mage.Sets/src/mage/cards/r/RockyRebuke.java | 34 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 35 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RockyRebuke.java diff --git a/Mage.Sets/src/mage/cards/r/RockyRebuke.java b/Mage.Sets/src/mage/cards/r/RockyRebuke.java new file mode 100644 index 00000000000..799d43f7b6c --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RockyRebuke.java @@ -0,0 +1,34 @@ +package mage.cards.r; + +import mage.abilities.effects.common.DamageWithPowerFromOneToAnotherTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetOpponentsCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RockyRebuke extends CardImpl { + + public RockyRebuke(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); + + // Target creature you control deals damage equal to its power to target creature an opponent controls. + this.getSpellAbility().addEffect(new DamageWithPowerFromOneToAnotherTargetEffect()); + this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + this.getSpellAbility().addTarget(new TargetOpponentsCreaturePermanent()); + } + + private RockyRebuke(final RockyRebuke card) { + super(card); + } + + @Override + public RockyRebuke copy() { + return new RockyRebuke(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index c6aba0d507a..731072b71aa 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -95,6 +95,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Rebellious Captives", 191, Rarity.COMMON, mage.cards.r.RebelliousCaptives.class)); cards.add(new SetCardInfo("Redirect Lightning", 151, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Redirect Lightning", 343, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Rocky Rebuke", 193, Rarity.COMMON, mage.cards.r.RockyRebuke.class)); cards.add(new SetCardInfo("Saber-Tooth Moose-Lion", 194, Rarity.COMMON, mage.cards.s.SaberToothMooseLion.class)); cards.add(new SetCardInfo("Sokka's Haiku", 71, Rarity.UNCOMMON, mage.cards.s.SokkasHaiku.class)); cards.add(new SetCardInfo("Sokka, Bold Boomeranger", 240, Rarity.RARE, mage.cards.s.SokkaBoldBoomeranger.class, NON_FULL_USE_VARIOUS)); From 1b396d68c6b0d1ecfd68dbf7ed1d7e92439a416a Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:30:31 -0400 Subject: [PATCH 23/60] [TLA] Implement Rough Rhino Cavalry --- .../src/mage/cards/r/RoughRhinoCavalry.java | 54 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 55 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RoughRhinoCavalry.java diff --git a/Mage.Sets/src/mage/cards/r/RoughRhinoCavalry.java b/Mage.Sets/src/mage/cards/r/RoughRhinoCavalry.java new file mode 100644 index 00000000000..77b3f745b3a --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RoughRhinoCavalry.java @@ -0,0 +1,54 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.ExhaustAbility; +import mage.abilities.keyword.FirebendingAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.counters.CounterType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RoughRhinoCavalry extends CardImpl { + + public RoughRhinoCavalry(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.MERCENARY); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Firebending 2 + this.addAbility(new FirebendingAbility(2)); + + // Exhaust -- {8}: Put two +1/+1 counters on this creature. It gains trample until end of turn. + Ability ability = new ExhaustAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), new GenericManaCost(8) + ); + ability.addEffect(new GainAbilitySourceEffect( + TrampleAbility.getInstance(), Duration.EndOfTurn + ).setText("It gains trample until end of turn")); + this.addAbility(ability); + } + + private RoughRhinoCavalry(final RoughRhinoCavalry card) { + super(card); + } + + @Override + public RoughRhinoCavalry copy() { + return new RoughRhinoCavalry(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 731072b71aa..35cb6be202f 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -96,6 +96,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Redirect Lightning", 151, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Redirect Lightning", 343, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Rocky Rebuke", 193, Rarity.COMMON, mage.cards.r.RockyRebuke.class)); + cards.add(new SetCardInfo("Rough Rhino Cavalry", 152, Rarity.COMMON, mage.cards.r.RoughRhinoCavalry.class)); cards.add(new SetCardInfo("Saber-Tooth Moose-Lion", 194, Rarity.COMMON, mage.cards.s.SaberToothMooseLion.class)); cards.add(new SetCardInfo("Sokka's Haiku", 71, Rarity.UNCOMMON, mage.cards.s.SokkasHaiku.class)); cards.add(new SetCardInfo("Sokka, Bold Boomeranger", 240, Rarity.RARE, mage.cards.s.SokkaBoldBoomeranger.class, NON_FULL_USE_VARIOUS)); From 7be8f9606394c14ac8e660cdd44829a310f32e58 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:31:41 -0400 Subject: [PATCH 24/60] [TLA] Implement Rowdy Snowballers --- .../src/mage/cards/r/RowdySnowballers.java | 46 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RowdySnowballers.java diff --git a/Mage.Sets/src/mage/cards/r/RowdySnowballers.java b/Mage.Sets/src/mage/cards/r/RowdySnowballers.java new file mode 100644 index 00000000000..c6651fc17c5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RowdySnowballers.java @@ -0,0 +1,46 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.target.common.TargetOpponentsCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RowdySnowballers extends CardImpl { + + public RowdySnowballers(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.PEASANT); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When this creature enters, tap target creature an opponent controls and put a stun counter on it. + Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect()); + ability.addEffect(new AddCountersTargetEffect(CounterType.STUN.createInstance()).setText("and put a stun counter on it")); + ability.addTarget(new TargetOpponentsCreaturePermanent()); + this.addAbility(ability); + } + + private RowdySnowballers(final RowdySnowballers card) { + super(card); + } + + @Override + public RowdySnowballers copy() { + return new RowdySnowballers(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 35cb6be202f..097633464e6 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -97,6 +97,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Redirect Lightning", 343, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Rocky Rebuke", 193, Rarity.COMMON, mage.cards.r.RockyRebuke.class)); cards.add(new SetCardInfo("Rough Rhino Cavalry", 152, Rarity.COMMON, mage.cards.r.RoughRhinoCavalry.class)); + cards.add(new SetCardInfo("Rowdy Snowballers", 68, Rarity.COMMON, mage.cards.r.RowdySnowballers.class)); cards.add(new SetCardInfo("Saber-Tooth Moose-Lion", 194, Rarity.COMMON, mage.cards.s.SaberToothMooseLion.class)); cards.add(new SetCardInfo("Sokka's Haiku", 71, Rarity.UNCOMMON, mage.cards.s.SokkasHaiku.class)); cards.add(new SetCardInfo("Sokka, Bold Boomeranger", 240, Rarity.RARE, mage.cards.s.SokkaBoldBoomeranger.class, NON_FULL_USE_VARIOUS)); From cb28ffb1ab0f7e6642501b98a80b156fd6987cf4 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:33:39 -0400 Subject: [PATCH 25/60] [TLA] Implement Suki, Kyoshi Warrior --- .../src/mage/cards/s/SukiKyoshiWarrior.java | 49 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 50 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SukiKyoshiWarrior.java diff --git a/Mage.Sets/src/mage/cards/s/SukiKyoshiWarrior.java b/Mage.Sets/src/mage/cards/s/SukiKyoshiWarrior.java new file mode 100644 index 00000000000..b5db8835d9b --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SukiKyoshiWarrior.java @@ -0,0 +1,49 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.CreaturesYouControlCount; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.game.permanent.token.AllyToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SukiKyoshiWarrior extends CardImpl { + + public SukiKyoshiWarrior(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G/W}{G/W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(0); + this.toughness = new MageInt(4); + + // Suki's power is equal to the number of creatures you control. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerSourceEffect(CreaturesYouControlCount.PLURAL))); + + // Whenever Suki attacks, create a 1/1 white Ally creature token that's tapped and attacking. + this.addAbility(new AttacksTriggeredAbility(new CreateTokenEffect(new AllyToken(), 1, true, true))); + } + + private SukiKyoshiWarrior(final SukiKyoshiWarrior card) { + super(card); + } + + @Override + public SukiKyoshiWarrior copy() { + return new SukiKyoshiWarrior(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 097633464e6..e7be9cbcf59 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -103,6 +103,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Sokka, Bold Boomeranger", 240, Rarity.RARE, mage.cards.s.SokkaBoldBoomeranger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sokka, Bold Boomeranger", 383, Rarity.RARE, mage.cards.s.SokkaBoldBoomeranger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Southern Air Temple", 36, Rarity.UNCOMMON, mage.cards.s.SouthernAirTemple.class)); + cards.add(new SetCardInfo("Suki, Kyoshi Warrior", 243, Rarity.UNCOMMON, mage.cards.s.SukiKyoshiWarrior.class)); cards.add(new SetCardInfo("Swamp", 289, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Toph, the First Metalbender", 247, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Toph, the First Metalbender", 353, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS)); From 93f1008170a231f9b5722a003b6d7c05d2bdd502 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:37:56 -0400 Subject: [PATCH 26/60] [TLA] Implement Toph, the Blind Bandit --- .../src/mage/cards/t/TophTheBlindBandit.java | 98 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 99 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TophTheBlindBandit.java diff --git a/Mage.Sets/src/mage/cards/t/TophTheBlindBandit.java b/Mage.Sets/src/mage/cards/t/TophTheBlindBandit.java new file mode 100644 index 00000000000..ccea918c260 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TophTheBlindBandit.java @@ -0,0 +1,98 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect; +import mage.abilities.effects.keyword.EarthbendTargetEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.target.common.TargetControlledLandPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TophTheBlindBandit extends CardImpl { + + public TophTheBlindBandit(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(0); + this.toughness = new MageInt(3); + + // When Toph enters, earthbend 2. + Ability ability = new EntersBattlefieldTriggeredAbility(new EarthbendTargetEffect(2)); + ability.addTarget(new TargetControlledLandPermanent()); + this.addAbility(ability); + + // Toph's power is equal to the number of +1/+1 counters on lands you control. + this.addAbility(new SimpleStaticAbility( + Zone.ALL, new SetBasePowerSourceEffect(TophTheBlindBanditValue.instance) + ).addHint(TophTheBlindBanditValue.getHint())); + } + + private TophTheBlindBandit(final TophTheBlindBandit card) { + super(card); + } + + @Override + public TophTheBlindBandit copy() { + return new TophTheBlindBandit(this); + } +} + +enum TophTheBlindBanditValue implements DynamicValue { + instance; + private static final Hint hint = new ValueHint("+1/+1 counters on lands you control", instance); + + public static Hint getHint() { + return hint; + } + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return game + .getBattlefield() + .getActivePermanents( + StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND, + sourceAbility.getControllerId(), sourceAbility, game + ) + .stream() + .map(permanent -> permanent.getCounters(game)) + .mapToInt(counters -> counters.getCount(CounterType.P1P1)) + .sum(); + } + + @Override + public TophTheBlindBanditValue copy() { + return this; + } + + @Override + public String getMessage() { + return "+1/+1 counters on lands you control"; + } + + @Override + public String toString() { + return "1"; + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index e7be9cbcf59..81a8e1257a0 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -105,6 +105,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Southern Air Temple", 36, Rarity.UNCOMMON, mage.cards.s.SouthernAirTemple.class)); cards.add(new SetCardInfo("Suki, Kyoshi Warrior", 243, Rarity.UNCOMMON, mage.cards.s.SukiKyoshiWarrior.class)); cards.add(new SetCardInfo("Swamp", 289, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Toph, the Blind Bandit", 198, Rarity.UNCOMMON, mage.cards.t.TophTheBlindBandit.class)); cards.add(new SetCardInfo("Toph, the First Metalbender", 247, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Toph, the First Metalbender", 353, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Toph, the First Metalbender", 362, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS)); From 935a389a05045a73e72da991c72c4faeb449082e Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:39:33 -0400 Subject: [PATCH 27/60] [TLA] Implement Turtle-Duck --- Mage.Sets/src/mage/cards/t/TurtleDuck.java | 48 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 49 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TurtleDuck.java diff --git a/Mage.Sets/src/mage/cards/t/TurtleDuck.java b/Mage.Sets/src/mage/cards/t/TurtleDuck.java new file mode 100644 index 00000000000..a111f047c40 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TurtleDuck.java @@ -0,0 +1,48 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TurtleDuck extends CardImpl { + + public TurtleDuck(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); + + this.subtype.add(SubType.TURTLE); + this.subtype.add(SubType.BIRD); + this.power = new MageInt(0); + this.toughness = new MageInt(4); + + // {3}: Until end of turn, this creature has base power 4 and gains trample. + Ability ability = new SimpleActivatedAbility(new SetBasePowerSourceEffect(4, Duration.EndOfTurn) + .setText("until end of turn, this creature has base power 4"), new GenericManaCost(3)); + ability.addEffect(new GainAbilitySourceEffect( + TrampleAbility.getInstance(), Duration.EndOfTurn + ).setText("and gains trample")); + this.addAbility(ability); + } + + private TurtleDuck(final TurtleDuck card) { + super(card); + } + + @Override + public TurtleDuck copy() { + return new TurtleDuck(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 81a8e1257a0..c415f6f8eb9 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -109,6 +109,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Toph, the First Metalbender", 247, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Toph, the First Metalbender", 353, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Toph, the First Metalbender", 362, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Turtle-Duck", 200, Rarity.COMMON, mage.cards.t.TurtleDuck.class)); cards.add(new SetCardInfo("Yue, the Moon Spirit", 338, Rarity.RARE, mage.cards.y.YueTheMoonSpirit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Yue, the Moon Spirit", 83, Rarity.RARE, mage.cards.y.YueTheMoonSpirit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Yuyan Archers", 161, Rarity.COMMON, mage.cards.y.YuyanArchers.class)); From e10b9fb7b9453b414cafa09cb11de56096d2b94a Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:40:18 -0400 Subject: [PATCH 28/60] [TLA] Implement Vindictive Warden --- .../src/mage/cards/v/VindictiveWarden.java | 50 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 51 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/v/VindictiveWarden.java diff --git a/Mage.Sets/src/mage/cards/v/VindictiveWarden.java b/Mage.Sets/src/mage/cards/v/VindictiveWarden.java new file mode 100644 index 00000000000..ac86ef51529 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VindictiveWarden.java @@ -0,0 +1,50 @@ +package mage.cards.v; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.DamagePlayersEffect; +import mage.abilities.keyword.FirebendingAbility; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class VindictiveWarden extends CardImpl { + + public VindictiveWarden(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B/R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Menace + this.addAbility(new MenaceAbility()); + + // Firebending 1 + this.addAbility(new FirebendingAbility(1)); + + // {3}: This creature deals 1 damage to each opponent. + this.addAbility(new SimpleActivatedAbility( + new DamagePlayersEffect(1, TargetController.OPPONENT), new GenericManaCost(3) + )); + } + + private VindictiveWarden(final VindictiveWarden card) { + super(card); + } + + @Override + public VindictiveWarden copy() { + return new VindictiveWarden(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index c415f6f8eb9..fc7084c5527 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -110,6 +110,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Toph, the First Metalbender", 353, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Toph, the First Metalbender", 362, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Turtle-Duck", 200, Rarity.COMMON, mage.cards.t.TurtleDuck.class)); + cards.add(new SetCardInfo("Vindictive Warden", 249, Rarity.COMMON, mage.cards.v.VindictiveWarden.class)); cards.add(new SetCardInfo("Yue, the Moon Spirit", 338, Rarity.RARE, mage.cards.y.YueTheMoonSpirit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Yue, the Moon Spirit", 83, Rarity.RARE, mage.cards.y.YueTheMoonSpirit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Yuyan Archers", 161, Rarity.COMMON, mage.cards.y.YuyanArchers.class)); From 78237b6b8b739a003138d8f7cec851cc3a3b5a44 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:43:55 -0400 Subject: [PATCH 29/60] [TLA] Implement Waterbending Lesson --- .../src/mage/cards/w/WaterbendingLesson.java | 40 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 41 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WaterbendingLesson.java diff --git a/Mage.Sets/src/mage/cards/w/WaterbendingLesson.java b/Mage.Sets/src/mage/cards/w/WaterbendingLesson.java new file mode 100644 index 00000000000..7d41f6b534e --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WaterbendingLesson.java @@ -0,0 +1,40 @@ +package mage.cards.w; + +import mage.abilities.costs.common.WaterbendCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.discard.DiscardControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class WaterbendingLesson extends CardImpl { + + public WaterbendingLesson(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}"); + + this.subtype.add(SubType.LESSON); + + // Draw three cards. Then discard a card unless you waterbend {2}. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(3)); + this.getSpellAbility().addEffect(new DoIfCostPaid( + null, new DiscardControllerEffect(1), + new WaterbendCost(2).setText("waterbend {2} instead of discarding a card") + ).setText("Then discard a card unless you waterbend {2}")); + } + + private WaterbendingLesson(final WaterbendingLesson card) { + super(card); + } + + @Override + public WaterbendingLesson copy() { + return new WaterbendingLesson(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index fc7084c5527..269977b7642 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -111,6 +111,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Toph, the First Metalbender", 362, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Turtle-Duck", 200, Rarity.COMMON, mage.cards.t.TurtleDuck.class)); cards.add(new SetCardInfo("Vindictive Warden", 249, Rarity.COMMON, mage.cards.v.VindictiveWarden.class)); + cards.add(new SetCardInfo("Waterbending Lesson", 80, Rarity.COMMON, mage.cards.w.WaterbendingLesson.class)); cards.add(new SetCardInfo("Yue, the Moon Spirit", 338, Rarity.RARE, mage.cards.y.YueTheMoonSpirit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Yue, the Moon Spirit", 83, Rarity.RARE, mage.cards.y.YueTheMoonSpirit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Yuyan Archers", 161, Rarity.COMMON, mage.cards.y.YuyanArchers.class)); From 505a0b66f7883df29a06f44b39ab0059ab265234 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:47:33 -0400 Subject: [PATCH 30/60] [TLA] Implement Watery Grasp --- Mage.Sets/src/mage/cards/w/WateryGrasp.java | 87 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 88 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WateryGrasp.java diff --git a/Mage.Sets/src/mage/cards/w/WateryGrasp.java b/Mage.Sets/src/mage/cards/w/WateryGrasp.java new file mode 100644 index 00000000000..288b5062f29 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WateryGrasp.java @@ -0,0 +1,87 @@ +package mage.cards.w; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.WaterbendCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.Optional; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class WateryGrasp extends CardImpl { + + public WateryGrasp(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + this.addAbility(new EnchantAbility(auraTarget)); + + // Enchanted creature doesn't untap during its controller's untap step. + this.addAbility(new SimpleStaticAbility(new DontUntapInControllersUntapStepEnchantedEffect())); + + // Waterbend {5}: Enchanted creature's owner shuffles it into their library. + this.addAbility(new SimpleActivatedAbility(new WateryGraspEffect(), new WaterbendCost(5))); + } + + private WateryGrasp(final WateryGrasp card) { + super(card); + } + + @Override + public WateryGrasp copy() { + return new WateryGrasp(this); + } +} + +class WateryGraspEffect extends OneShotEffect { + + WateryGraspEffect() { + super(Outcome.Benefit); + staticText = "enchanted creature's owner shuffles it into their library"; + } + + private WateryGraspEffect(final WateryGraspEffect effect) { + super(effect); + } + + @Override + public WateryGraspEffect copy() { + return new WateryGraspEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = Optional + .ofNullable(source.getSourcePermanentOrLKI(game)) + .map(Permanent::getAttachedTo) + .map(game::getPermanent) + .orElse(null); + if (permanent == null) { + return false; + } + Player player = game.getPlayer(permanent.getOwnerId()); + return player != null && player.shuffleCardsToLibrary(permanent, game, source); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 269977b7642..6d94efd8fff 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -112,6 +112,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Turtle-Duck", 200, Rarity.COMMON, mage.cards.t.TurtleDuck.class)); cards.add(new SetCardInfo("Vindictive Warden", 249, Rarity.COMMON, mage.cards.v.VindictiveWarden.class)); cards.add(new SetCardInfo("Waterbending Lesson", 80, Rarity.COMMON, mage.cards.w.WaterbendingLesson.class)); + cards.add(new SetCardInfo("Watery Grasp", 82, Rarity.COMMON, mage.cards.w.WateryGrasp.class)); cards.add(new SetCardInfo("Yue, the Moon Spirit", 338, Rarity.RARE, mage.cards.y.YueTheMoonSpirit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Yue, the Moon Spirit", 83, Rarity.RARE, mage.cards.y.YueTheMoonSpirit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Yuyan Archers", 161, Rarity.COMMON, mage.cards.y.YuyanArchers.class)); From a23d5f82e2fe04ef3a5b3642b908a1dbc9bda572 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:53:04 -0400 Subject: [PATCH 31/60] [TLE] Implement Earthbending Studen --- .../src/mage/cards/e/EarthbendingStudent.java | 60 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 61 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EarthbendingStudent.java diff --git a/Mage.Sets/src/mage/cards/e/EarthbendingStudent.java b/Mage.Sets/src/mage/cards/e/EarthbendingStudent.java new file mode 100644 index 00000000000..462f2ef3e18 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EarthbendingStudent.java @@ -0,0 +1,60 @@ +package mage.cards.e; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.keyword.EarthbendTargetEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.target.common.TargetControlledLandPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class EarthbendingStudent extends CardImpl { + + private static final FilterPermanent filter = new FilterCreaturePermanent("land creatures"); + + static { + filter.add(CardType.LAND.getPredicate()); + } + + public EarthbendingStudent(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // When this creature enters, earthbend 2. + Ability ability = new EntersBattlefieldTriggeredAbility(new EarthbendTargetEffect(2)); + ability.addTarget(new TargetControlledLandPermanent()); + this.addAbility(ability); + + // Land creatures you control have vigilance. + this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( + VigilanceAbility.getInstance(), Duration.WhileOnBattlefield, filter + ))); + } + + private EarthbendingStudent(final EarthbendingStudent card) { + super(card); + } + + @Override + public EarthbendingStudent copy() { + return new EarthbendingStudent(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index ad994b23881..740a8577c69 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -36,6 +36,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Capital Guard", 234, Rarity.COMMON, mage.cards.c.CapitalGuard.class)); cards.add(new SetCardInfo("Deny Entry", 222, Rarity.COMMON, mage.cards.d.DenyEntry.class)); cards.add(new SetCardInfo("Dragon Moose", 235, Rarity.COMMON, mage.cards.d.DragonMoose.class)); + cards.add(new SetCardInfo("Earthbending Student", 249, Rarity.UNCOMMON, mage.cards.e.EarthbendingStudent.class)); cards.add(new SetCardInfo("Eel-Hounds", 250, Rarity.UNCOMMON, mage.cards.e.EelHounds.class)); cards.add(new SetCardInfo("Elephant-Rat", 228, Rarity.COMMON, mage.cards.e.ElephantRat.class)); cards.add(new SetCardInfo("Explore", 259, Rarity.COMMON, mage.cards.e.Explore.class)); From 8474f739e2cbcb26fc14e28c39ad60c104713f1c Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:53:12 -0400 Subject: [PATCH 32/60] [TLE] Implement Fire Nation Archers --- .../src/mage/cards/f/FireNationArchers.java | 49 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + .../game/permanent/token/SoldierRedToken.java | 28 +++++++++++ 3 files changed, 78 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FireNationArchers.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/SoldierRedToken.java diff --git a/Mage.Sets/src/mage/cards/f/FireNationArchers.java b/Mage.Sets/src/mage/cards/f/FireNationArchers.java new file mode 100644 index 00000000000..bcced837911 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FireNationArchers.java @@ -0,0 +1,49 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DamagePlayersEffect; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.game.permanent.token.SoldierRedToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FireNationArchers extends CardImpl { + + public FireNationArchers(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ARCHER); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // {5}: This creature deals 2 damage to each opponent. Create a 2/2 red Soldier creature token. + Ability ability = new SimpleActivatedAbility(new DamagePlayersEffect(2, TargetController.OPPONENT), new GenericManaCost(5)); + ability.addEffect(new CreateTokenEffect(new SoldierRedToken())); + this.addAbility(ability); + } + + private FireNationArchers(final FireNationArchers card) { + super(card); + } + + @Override + public FireNationArchers copy() { + return new FireNationArchers(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 740a8577c69..85ea385423b 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -43,6 +43,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Explosive Shot", 236, Rarity.COMMON, mage.cards.e.ExplosiveShot.class)); cards.add(new SetCardInfo("Feed the Swarm", 257, Rarity.COMMON, mage.cards.f.FeedTheSwarm.class)); cards.add(new SetCardInfo("Fire Nation Ambushers", 229, Rarity.COMMON, mage.cards.f.FireNationAmbushers.class)); + cards.add(new SetCardInfo("Fire Nation Archers", 237, Rarity.RARE, mage.cards.f.FireNationArchers.class)); cards.add(new SetCardInfo("Fire Nation Soldier", 238, Rarity.COMMON, mage.cards.f.FireNationSoldier.class)); cards.add(new SetCardInfo("Force of Negation", 13, Rarity.MYTHIC, mage.cards.f.ForceOfNegation.class)); cards.add(new SetCardInfo("Katara, Waterbending Master", 93, Rarity.MYTHIC, mage.cards.k.KataraWaterbendingMaster.class)); diff --git a/Mage/src/main/java/mage/game/permanent/token/SoldierRedToken.java b/Mage/src/main/java/mage/game/permanent/token/SoldierRedToken.java new file mode 100644 index 00000000000..3d6b5d3b400 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/SoldierRedToken.java @@ -0,0 +1,28 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * @author TheElk801 + */ +public final class SoldierRedToken extends TokenImpl { + + public SoldierRedToken() { + super("Soldier Token", "2/2 red Soldier creature token"); + cardType.add(CardType.CREATURE); + color.setRed(true); + subtype.add(SubType.SOLDIER); + power = new MageInt(2); + toughness = new MageInt(2); + } + + private SoldierRedToken(final SoldierRedToken token) { + super(token); + } + + public SoldierRedToken copy() { + return new SoldierRedToken(this); + } +} From a9d728080ea808298348cd3d6f7dee2f6c0e1284 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:53:53 -0400 Subject: [PATCH 33/60] [TLE] Implement Fire Nation's Conquest --- .../src/mage/cards/f/FireNationsConquest.java | 32 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 33 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FireNationsConquest.java diff --git a/Mage.Sets/src/mage/cards/f/FireNationsConquest.java b/Mage.Sets/src/mage/cards/f/FireNationsConquest.java new file mode 100644 index 00000000000..c5f9fbc9084 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FireNationsConquest.java @@ -0,0 +1,32 @@ +package mage.cards.f; + +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FireNationsConquest extends CardImpl { + + public FireNationsConquest(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); + + // Creatures you control get +1/+0. + this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(1, 0, Duration.WhileOnBattlefield))); + } + + private FireNationsConquest(final FireNationsConquest card) { + super(card); + } + + @Override + public FireNationsConquest copy() { + return new FireNationsConquest(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 85ea385423b..e155f98bdc3 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -45,6 +45,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Fire Nation Ambushers", 229, Rarity.COMMON, mage.cards.f.FireNationAmbushers.class)); cards.add(new SetCardInfo("Fire Nation Archers", 237, Rarity.RARE, mage.cards.f.FireNationArchers.class)); cards.add(new SetCardInfo("Fire Nation Soldier", 238, Rarity.COMMON, mage.cards.f.FireNationSoldier.class)); + cards.add(new SetCardInfo("Fire Nation's Conquest", 239, Rarity.UNCOMMON, mage.cards.f.FireNationsConquest.class)); cards.add(new SetCardInfo("Force of Negation", 13, Rarity.MYTHIC, mage.cards.f.ForceOfNegation.class)); cards.add(new SetCardInfo("Katara, Waterbending Master", 93, Rarity.MYTHIC, mage.cards.k.KataraWaterbendingMaster.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); From 268a1c8339b0197759c66606d1a8e2437e13d80a Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 08:56:37 -0400 Subject: [PATCH 34/60] [TLE] Implement Fire Nation Sentinels --- .../src/mage/cards/f/FireNationSentinels.java | 51 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 52 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FireNationSentinels.java diff --git a/Mage.Sets/src/mage/cards/f/FireNationSentinels.java b/Mage.Sets/src/mage/cards/f/FireNationSentinels.java new file mode 100644 index 00000000000..3cb6c8653b7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FireNationSentinels.java @@ -0,0 +1,51 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterOpponentsCreaturePermanent; +import mage.filter.predicate.permanent.TokenPredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FireNationSentinels extends CardImpl { + + private static final FilterPermanent filter = new FilterOpponentsCreaturePermanent("nontoken creature an opponent controls"); + + static { + filter.add(TokenPredicate.FALSE); + } + + public FireNationSentinels(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Whenever a nontoken creature an opponent controls dies, put a +1/+1 counter on each creature you control. + this.addAbility(new DiesCreatureTriggeredAbility(new AddCountersAllEffect( + CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE + ), false, filter)); + } + + private FireNationSentinels(final FireNationSentinels card) { + super(card); + } + + @Override + public FireNationSentinels copy() { + return new FireNationSentinels(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index e155f98bdc3..4bb819d6206 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -44,6 +44,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Feed the Swarm", 257, Rarity.COMMON, mage.cards.f.FeedTheSwarm.class)); cards.add(new SetCardInfo("Fire Nation Ambushers", 229, Rarity.COMMON, mage.cards.f.FireNationAmbushers.class)); cards.add(new SetCardInfo("Fire Nation Archers", 237, Rarity.RARE, mage.cards.f.FireNationArchers.class)); + cards.add(new SetCardInfo("Fire Nation Sentinels", 230, Rarity.RARE, mage.cards.f.FireNationSentinels.class)); cards.add(new SetCardInfo("Fire Nation Soldier", 238, Rarity.COMMON, mage.cards.f.FireNationSoldier.class)); cards.add(new SetCardInfo("Fire Nation's Conquest", 239, Rarity.UNCOMMON, mage.cards.f.FireNationsConquest.class)); cards.add(new SetCardInfo("Force of Negation", 13, Rarity.MYTHIC, mage.cards.f.ForceOfNegation.class)); From c7f2bae792a8291dd36d7f9e8948b873396d1636 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:00:17 -0400 Subject: [PATCH 35/60] [TLE] Implement Flying Dolphin-Fish --- .../src/mage/cards/f/FlyingDolphinFish.java | 37 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FlyingDolphinFish.java diff --git a/Mage.Sets/src/mage/cards/f/FlyingDolphinFish.java b/Mage.Sets/src/mage/cards/f/FlyingDolphinFish.java new file mode 100644 index 00000000000..15f2ed50561 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FlyingDolphinFish.java @@ -0,0 +1,37 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FlyingDolphinFish extends CardImpl { + + public FlyingDolphinFish(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.WHALE); + this.subtype.add(SubType.FISH); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + } + + private FlyingDolphinFish(final FlyingDolphinFish card) { + super(card); + } + + @Override + public FlyingDolphinFish copy() { + return new FlyingDolphinFish(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 4bb819d6206..904b4054a25 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -47,6 +47,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Fire Nation Sentinels", 230, Rarity.RARE, mage.cards.f.FireNationSentinels.class)); cards.add(new SetCardInfo("Fire Nation Soldier", 238, Rarity.COMMON, mage.cards.f.FireNationSoldier.class)); cards.add(new SetCardInfo("Fire Nation's Conquest", 239, Rarity.UNCOMMON, mage.cards.f.FireNationsConquest.class)); + cards.add(new SetCardInfo("Flying Dolphin-Fish", 223, Rarity.COMMON, mage.cards.f.FlyingDolphinFish.class)); cards.add(new SetCardInfo("Force of Negation", 13, Rarity.MYTHIC, mage.cards.f.ForceOfNegation.class)); cards.add(new SetCardInfo("Katara, Waterbending Master", 93, Rarity.MYTHIC, mage.cards.k.KataraWaterbendingMaster.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); From f452640a719f5da25022ec1830257d85d5c0f83d Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:00:29 -0400 Subject: [PATCH 36/60] [TLE] Implement Frog-Squirrels --- Mage.Sets/src/mage/cards/f/FrogSquirrels.java | 37 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FrogSquirrels.java diff --git a/Mage.Sets/src/mage/cards/f/FrogSquirrels.java b/Mage.Sets/src/mage/cards/f/FrogSquirrels.java new file mode 100644 index 00000000000..b9696c43088 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FrogSquirrels.java @@ -0,0 +1,37 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FrogSquirrels extends CardImpl { + + public FrogSquirrels(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.FROG); + this.subtype.add(SubType.SQUIRREL); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Reach + this.addAbility(ReachAbility.getInstance()); + } + + private FrogSquirrels(final FrogSquirrels card) { + super(card); + } + + @Override + public FrogSquirrels copy() { + return new FrogSquirrels(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 904b4054a25..1c1965f32f3 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -49,6 +49,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Fire Nation's Conquest", 239, Rarity.UNCOMMON, mage.cards.f.FireNationsConquest.class)); cards.add(new SetCardInfo("Flying Dolphin-Fish", 223, Rarity.COMMON, mage.cards.f.FlyingDolphinFish.class)); cards.add(new SetCardInfo("Force of Negation", 13, Rarity.MYTHIC, mage.cards.f.ForceOfNegation.class)); + cards.add(new SetCardInfo("Frog-Squirrels", 251, Rarity.COMMON, mage.cards.f.FrogSquirrels.class)); cards.add(new SetCardInfo("Katara, Waterbending Master", 93, Rarity.MYTHIC, mage.cards.k.KataraWaterbendingMaster.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); From 8aceff16b0316c6016e2328279b508eedf10a43c Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:00:37 -0400 Subject: [PATCH 37/60] [TLE] Implement Gilacorn --- Mage.Sets/src/mage/cards/g/Gilacorn.java | 36 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 37 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/Gilacorn.java diff --git a/Mage.Sets/src/mage/cards/g/Gilacorn.java b/Mage.Sets/src/mage/cards/g/Gilacorn.java new file mode 100644 index 00000000000..b1ae6068c72 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/Gilacorn.java @@ -0,0 +1,36 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.keyword.DeathtouchAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Gilacorn extends CardImpl { + + public Gilacorn(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); + + this.subtype.add(SubType.LIZARD); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Deathtouch + this.addAbility(DeathtouchAbility.getInstance()); + } + + private Gilacorn(final Gilacorn card) { + super(card); + } + + @Override + public Gilacorn copy() { + return new Gilacorn(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 1c1965f32f3..baf084c3c0e 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -50,6 +50,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Flying Dolphin-Fish", 223, Rarity.COMMON, mage.cards.f.FlyingDolphinFish.class)); cards.add(new SetCardInfo("Force of Negation", 13, Rarity.MYTHIC, mage.cards.f.ForceOfNegation.class)); cards.add(new SetCardInfo("Frog-Squirrels", 251, Rarity.COMMON, mage.cards.f.FrogSquirrels.class)); + cards.add(new SetCardInfo("Gilacorn", 231, Rarity.COMMON, mage.cards.g.Gilacorn.class)); cards.add(new SetCardInfo("Katara, Waterbending Master", 93, Rarity.MYTHIC, mage.cards.k.KataraWaterbendingMaster.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); From 47c70bdc2d4a1b6b9605418aa6ff4e013369780a Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:00:46 -0400 Subject: [PATCH 38/60] [TLE] Implement Hippo-Cows --- Mage.Sets/src/mage/cards/h/HippoCows.java | 37 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HippoCows.java diff --git a/Mage.Sets/src/mage/cards/h/HippoCows.java b/Mage.Sets/src/mage/cards/h/HippoCows.java new file mode 100644 index 00000000000..057228b5452 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HippoCows.java @@ -0,0 +1,37 @@ +package mage.cards.h; + +import mage.MageInt; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class HippoCows extends CardImpl { + + public HippoCows(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}"); + + this.subtype.add(SubType.HIPPO); + this.subtype.add(SubType.OX); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + } + + private HippoCows(final HippoCows card) { + super(card); + } + + @Override + public HippoCows copy() { + return new HippoCows(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index baf084c3c0e..8945bfb8bee 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -51,6 +51,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Force of Negation", 13, Rarity.MYTHIC, mage.cards.f.ForceOfNegation.class)); cards.add(new SetCardInfo("Frog-Squirrels", 251, Rarity.COMMON, mage.cards.f.FrogSquirrels.class)); cards.add(new SetCardInfo("Gilacorn", 231, Rarity.COMMON, mage.cards.g.Gilacorn.class)); + cards.add(new SetCardInfo("Hippo-Cows", 252, Rarity.COMMON, mage.cards.h.HippoCows.class)); cards.add(new SetCardInfo("Katara, Waterbending Master", 93, Rarity.MYTHIC, mage.cards.k.KataraWaterbendingMaster.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); From ea09727e96303ed62856b5f30cb795f8265aec2e Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:02:07 -0400 Subject: [PATCH 39/60] [TLE] Implement Iroh, Firebending Instructor --- .../cards/i/IrohFirebendingInstructor.java | 45 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 46 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/IrohFirebendingInstructor.java diff --git a/Mage.Sets/src/mage/cards/i/IrohFirebendingInstructor.java b/Mage.Sets/src/mage/cards/i/IrohFirebendingInstructor.java new file mode 100644 index 00000000000..c42876393e6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IrohFirebendingInstructor.java @@ -0,0 +1,45 @@ +package mage.cards.i; + +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class IrohFirebendingInstructor extends CardImpl { + + public IrohFirebendingInstructor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.NOBLE); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever Iroh attacks, attacking creatures get +1/+1 until end of turn. + this.addAbility(new AttacksTriggeredAbility(new BoostAllEffect( + 1, 1, Duration.EndOfTurn, StaticFilters.FILTER_ATTACKING_CREATURES, false + ))); + } + + private IrohFirebendingInstructor(final IrohFirebendingInstructor card) { + super(card); + } + + @Override + public IrohFirebendingInstructor copy() { + return new IrohFirebendingInstructor(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 8945bfb8bee..c468df50acb 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -52,6 +52,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Frog-Squirrels", 251, Rarity.COMMON, mage.cards.f.FrogSquirrels.class)); cards.add(new SetCardInfo("Gilacorn", 231, Rarity.COMMON, mage.cards.g.Gilacorn.class)); cards.add(new SetCardInfo("Hippo-Cows", 252, Rarity.COMMON, mage.cards.h.HippoCows.class)); + cards.add(new SetCardInfo("Iroh, Firebending Instructor", 240, Rarity.UNCOMMON, mage.cards.i.IrohFirebendingInstructor.class)); cards.add(new SetCardInfo("Katara, Waterbending Master", 93, Rarity.MYTHIC, mage.cards.k.KataraWaterbendingMaster.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); From 6d295a1777f8f62ec90405ac030dac78ad40f35c Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:03:12 -0400 Subject: [PATCH 40/60] [TLE] Implement Katara, Heroic Healer --- .../src/mage/cards/k/KataraHeroicHealer.java | 49 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 50 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KataraHeroicHealer.java diff --git a/Mage.Sets/src/mage/cards/k/KataraHeroicHealer.java b/Mage.Sets/src/mage/cards/k/KataraHeroicHealer.java new file mode 100644 index 00000000000..3ffec0a09ed --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KataraHeroicHealer.java @@ -0,0 +1,49 @@ +package mage.cards.k; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.counters.CounterType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class KataraHeroicHealer extends CardImpl { + + public KataraHeroicHealer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // When Katara enters, put a +1/+1 counter on each other creature you control. + this.addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersAllEffect( + CounterType.P1P1.createInstance(), StaticFilters.FILTER_OTHER_CONTROLLED_CREATURE + ))); + } + + private KataraHeroicHealer(final KataraHeroicHealer card) { + super(card); + } + + @Override + public KataraHeroicHealer copy() { + return new KataraHeroicHealer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index c468df50acb..fe4f1dff64c 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -53,6 +53,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Gilacorn", 231, Rarity.COMMON, mage.cards.g.Gilacorn.class)); cards.add(new SetCardInfo("Hippo-Cows", 252, Rarity.COMMON, mage.cards.h.HippoCows.class)); cards.add(new SetCardInfo("Iroh, Firebending Instructor", 240, Rarity.UNCOMMON, mage.cards.i.IrohFirebendingInstructor.class)); + cards.add(new SetCardInfo("Katara, Heroic Healer", 215, Rarity.UNCOMMON, mage.cards.k.KataraHeroicHealer.class)); cards.add(new SetCardInfo("Katara, Waterbending Master", 93, Rarity.MYTHIC, mage.cards.k.KataraWaterbendingMaster.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); From 2cbae4a9ee24177852b8bed4fa2b8bca4e7ef3fe Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:03:40 -0400 Subject: [PATCH 41/60] [TLE] Implement Komodo Rhino --- Mage.Sets/src/mage/cards/k/KomodoRhino.java | 37 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KomodoRhino.java diff --git a/Mage.Sets/src/mage/cards/k/KomodoRhino.java b/Mage.Sets/src/mage/cards/k/KomodoRhino.java new file mode 100644 index 00000000000..a355f77936a --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KomodoRhino.java @@ -0,0 +1,37 @@ +package mage.cards.k; + +import mage.MageInt; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class KomodoRhino extends CardImpl { + + public KomodoRhino(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.LIZARD); + this.subtype.add(SubType.RHINO); + this.power = new MageInt(5); + this.toughness = new MageInt(2); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + } + + private KomodoRhino(final KomodoRhino card) { + super(card); + } + + @Override + public KomodoRhino copy() { + return new KomodoRhino(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index fe4f1dff64c..f04e4753078 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -55,6 +55,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Iroh, Firebending Instructor", 240, Rarity.UNCOMMON, mage.cards.i.IrohFirebendingInstructor.class)); cards.add(new SetCardInfo("Katara, Heroic Healer", 215, Rarity.UNCOMMON, mage.cards.k.KataraHeroicHealer.class)); cards.add(new SetCardInfo("Katara, Waterbending Master", 93, Rarity.MYTHIC, mage.cards.k.KataraWaterbendingMaster.class)); + cards.add(new SetCardInfo("Komodo Rhino", 241, Rarity.COMMON, mage.cards.k.KomodoRhino.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); cards.add(new SetCardInfo("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From ffa1ef10b7969015c729cbfd8144820dde7622fd Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:04:07 -0400 Subject: [PATCH 42/60] [TLE] Implement Kyoshi Warrior Guard --- .../src/mage/cards/k/KyoshiWarriorGuard.java | 34 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 35 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KyoshiWarriorGuard.java diff --git a/Mage.Sets/src/mage/cards/k/KyoshiWarriorGuard.java b/Mage.Sets/src/mage/cards/k/KyoshiWarriorGuard.java new file mode 100644 index 00000000000..d34844caece --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KyoshiWarriorGuard.java @@ -0,0 +1,34 @@ +package mage.cards.k; + +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class KyoshiWarriorGuard extends CardImpl { + + public KyoshiWarriorGuard(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + } + + private KyoshiWarriorGuard(final KyoshiWarriorGuard card) { + super(card); + } + + @Override + public KyoshiWarriorGuard copy() { + return new KyoshiWarriorGuard(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index f04e4753078..db82701cedf 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -56,6 +56,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Katara, Heroic Healer", 215, Rarity.UNCOMMON, mage.cards.k.KataraHeroicHealer.class)); cards.add(new SetCardInfo("Katara, Waterbending Master", 93, Rarity.MYTHIC, mage.cards.k.KataraWaterbendingMaster.class)); cards.add(new SetCardInfo("Komodo Rhino", 241, Rarity.COMMON, mage.cards.k.KomodoRhino.class)); + cards.add(new SetCardInfo("Kyoshi Warrior Guard", 216, Rarity.COMMON, mage.cards.k.KyoshiWarriorGuard.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); cards.add(new SetCardInfo("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From 416e64f3a04084610dd95f62aaa0d71d16278e82 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:05:02 -0400 Subject: [PATCH 43/60] [TLE] Implement Loyal Fire Sage --- Mage.Sets/src/mage/cards/l/LoyalFireSage.java | 45 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 46 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LoyalFireSage.java diff --git a/Mage.Sets/src/mage/cards/l/LoyalFireSage.java b/Mage.Sets/src/mage/cards/l/LoyalFireSage.java new file mode 100644 index 00000000000..112d79e8089 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LoyalFireSage.java @@ -0,0 +1,45 @@ +package mage.cards.l; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.FirebendingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.AllyToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class LoyalFireSage extends CardImpl { + + public LoyalFireSage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CLERIC); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Firebending 1 + this.addAbility(new FirebendingAbility(1)); + + // {5}: Create a 1/1 white Ally creature token. + this.addAbility(new SimpleActivatedAbility(new CreateTokenEffect(new AllyToken()), new GenericManaCost(5))); + } + + private LoyalFireSage(final LoyalFireSage card) { + super(card); + } + + @Override + public LoyalFireSage copy() { + return new LoyalFireSage(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index db82701cedf..57d34329c97 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -57,6 +57,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Katara, Waterbending Master", 93, Rarity.MYTHIC, mage.cards.k.KataraWaterbendingMaster.class)); cards.add(new SetCardInfo("Komodo Rhino", 241, Rarity.COMMON, mage.cards.k.KomodoRhino.class)); cards.add(new SetCardInfo("Kyoshi Warrior Guard", 216, Rarity.COMMON, mage.cards.k.KyoshiWarriorGuard.class)); + cards.add(new SetCardInfo("Loyal Fire Sage", 242, Rarity.UNCOMMON, mage.cards.l.LoyalFireSage.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); cards.add(new SetCardInfo("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From 66d0a81264c543e4a1537bfaf452fdc4da855bfe Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:08:59 -0400 Subject: [PATCH 44/60] [TLE] Implement Match the Odds --- Mage.Sets/src/mage/cards/m/MatchTheOdds.java | 86 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 87 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MatchTheOdds.java diff --git a/Mage.Sets/src/mage/cards/m/MatchTheOdds.java b/Mage.Sets/src/mage/cards/m/MatchTheOdds.java new file mode 100644 index 00000000000..259b9e62c1a --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MatchTheOdds.java @@ -0,0 +1,86 @@ +package mage.cards.m; + +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.token.AllyToken; +import mage.game.permanent.token.Token; + +import java.util.Optional; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MatchTheOdds extends CardImpl { + + private static final Hint hint = new ValueHint( + "Creatures your opponents control", + new PermanentsOnBattlefieldCount(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE) + ); + + public MatchTheOdds(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}"); + + this.subtype.add(SubType.LESSON); + + // Create a 1/1 white Ally creature token. Put a +1/+1 counter on it for each creature your opponents control. + this.getSpellAbility().addEffect(new MatchTheOddsEffect()); + this.getSpellAbility().addHint(hint); + } + + private MatchTheOdds(final MatchTheOdds card) { + super(card); + } + + @Override + public MatchTheOdds copy() { + return new MatchTheOdds(this); + } +} + +class MatchTheOddsEffect extends OneShotEffect { + + MatchTheOddsEffect() { + super(Outcome.Benefit); + staticText = "create a 1/1 white Ally creature token. " + + "Put a +1/+1 counter on it for each creature your opponents control"; + } + + private MatchTheOddsEffect(final MatchTheOddsEffect effect) { + super(effect); + } + + @Override + public MatchTheOddsEffect copy() { + return new MatchTheOddsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Token token = new AllyToken(); + token.putOntoBattlefield(1, game, source); + int count = game + .getBattlefield() + .count(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE, source.getControllerId(), source, game); + if (count < 1) { + return true; + } + for (UUID tokenId : token.getLastAddedTokenIds()) { + Optional.ofNullable(tokenId) + .map(game::getPermanent) + .ifPresent(permanent -> permanent.addCounters(CounterType.P1P1.createInstance(count), source, game)); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 57d34329c97..01f84e60dcb 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -58,6 +58,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Komodo Rhino", 241, Rarity.COMMON, mage.cards.k.KomodoRhino.class)); cards.add(new SetCardInfo("Kyoshi Warrior Guard", 216, Rarity.COMMON, mage.cards.k.KyoshiWarriorGuard.class)); cards.add(new SetCardInfo("Loyal Fire Sage", 242, Rarity.UNCOMMON, mage.cards.l.LoyalFireSage.class)); + cards.add(new SetCardInfo("Match the Odds", 253, Rarity.UNCOMMON, mage.cards.m.MatchTheOdds.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); cards.add(new SetCardInfo("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From 10989bc86c80c9b2e4fbbb8c1ea827d264740b4c Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:09:53 -0400 Subject: [PATCH 45/60] [TLE] Implement Mechanical Glider --- .../src/mage/cards/m/MechanicalGlider.java | 46 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MechanicalGlider.java diff --git a/Mage.Sets/src/mage/cards/m/MechanicalGlider.java b/Mage.Sets/src/mage/cards/m/MechanicalGlider.java new file mode 100644 index 00000000000..a827a9ab0a8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MechanicalGlider.java @@ -0,0 +1,46 @@ +package mage.cards.m; + +import mage.abilities.common.EntersBattlefieldAttachToTarget; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MechanicalGlider extends CardImpl { + + public MechanicalGlider(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); + + this.subtype.add(SubType.EQUIPMENT); + + // When this Equipment enters, attach it to target creature you control. + this.addAbility(new EntersBattlefieldAttachToTarget()); + + // Equipped creature has flying. + this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( + FlyingAbility.getInstance(), AttachmentType.EQUIPMENT + ))); + + // Equip {2} + this.addAbility(new EquipAbility(2)); + } + + private MechanicalGlider(final MechanicalGlider card) { + super(card); + } + + @Override + public MechanicalGlider copy() { + return new MechanicalGlider(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 01f84e60dcb..b6667e4f816 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -59,6 +59,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Kyoshi Warrior Guard", 216, Rarity.COMMON, mage.cards.k.KyoshiWarriorGuard.class)); cards.add(new SetCardInfo("Loyal Fire Sage", 242, Rarity.UNCOMMON, mage.cards.l.LoyalFireSage.class)); cards.add(new SetCardInfo("Match the Odds", 253, Rarity.UNCOMMON, mage.cards.m.MatchTheOdds.class)); + cards.add(new SetCardInfo("Mechanical Glider", 256, Rarity.COMMON, mage.cards.m.MechanicalGlider.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); cards.add(new SetCardInfo("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From d7e5dee77ebce77cbf91628dcafb898e7371a1db Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:11:36 -0400 Subject: [PATCH 46/60] [TLE] Implement Momo, Rambunctious Rascal --- .../mage/cards/m/MomoRambunctiousRascal.java | 58 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + .../src/main/java/mage/constants/SubType.java | 1 + 3 files changed, 60 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MomoRambunctiousRascal.java diff --git a/Mage.Sets/src/mage/cards/m/MomoRambunctiousRascal.java b/Mage.Sets/src/mage/cards/m/MomoRambunctiousRascal.java new file mode 100644 index 00000000000..9a5c1f20eac --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MomoRambunctiousRascal.java @@ -0,0 +1,58 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterOpponentsCreaturePermanent; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MomoRambunctiousRascal extends CardImpl { + + private static final FilterPermanent filter = new FilterOpponentsCreaturePermanent("tapped creature an opponent controls"); + + static { + filter.add(TappedPredicate.TAPPED); + } + + public MomoRambunctiousRascal(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.LEMUR); + this.subtype.add(SubType.BAT); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Momo enters, he deals 4 damage to target tapped creature an opponent controls. + Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(4, "he")); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + private MomoRambunctiousRascal(final MomoRambunctiousRascal card) { + super(card); + } + + @Override + public MomoRambunctiousRascal copy() { + return new MomoRambunctiousRascal(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index b6667e4f816..430d47a10a1 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -60,6 +60,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Loyal Fire Sage", 242, Rarity.UNCOMMON, mage.cards.l.LoyalFireSage.class)); cards.add(new SetCardInfo("Match the Odds", 253, Rarity.UNCOMMON, mage.cards.m.MatchTheOdds.class)); cards.add(new SetCardInfo("Mechanical Glider", 256, Rarity.COMMON, mage.cards.m.MechanicalGlider.class)); + cards.add(new SetCardInfo("Momo, Rambunctious Rascal", 217, Rarity.UNCOMMON, mage.cards.m.MomoRambunctiousRascal.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); cards.add(new SetCardInfo("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index 549383e2414..4e6b7ca361d 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -262,6 +262,7 @@ public enum SubType { LAMIA("Lamia", SubTypeSet.CreatureType), LAMMASU("Lammasu", SubTypeSet.CreatureType), LEECH("Leech", SubTypeSet.CreatureType), + LEMUR("Lemur", SubTypeSet.CreatureType), LEVIATHAN("Leviathan", SubTypeSet.CreatureType), LHURGOYF("Lhurgoyf", SubTypeSet.CreatureType), LICID("Licid", SubTypeSet.CreatureType), From ee7ce743e49d6d841b59b52306876747b02035ac Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:13:08 -0400 Subject: [PATCH 47/60] [TLE] Implement Purple Pentapus --- .../src/mage/cards/p/PurplePentapus.java | 52 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 53 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PurplePentapus.java diff --git a/Mage.Sets/src/mage/cards/p/PurplePentapus.java b/Mage.Sets/src/mage/cards/p/PurplePentapus.java new file mode 100644 index 00000000000..54cbd6152fd --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PurplePentapus.java @@ -0,0 +1,52 @@ +package mage.cards.p; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapTargetCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect; +import mage.abilities.effects.keyword.SurveilEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PurplePentapus extends CardImpl { + + public PurplePentapus(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); + + this.subtype.add(SubType.OCTOPUS); + this.subtype.add(SubType.STARFISH); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // When this creature enters, surveil 1. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SurveilEffect(1))); + + // {2}{B}, Tap an untapped creature you control: Return this card from your graveyard to the battlefield tapped. + Ability ability = new SimpleActivatedAbility( + Zone.GRAVEYARD, new ReturnSourceFromGraveyardToBattlefieldEffect(true), new ManaCostsImpl<>("{2}{B}") + ); + ability.addCost(new TapTargetCost(StaticFilters.FILTER_CONTROLLED_UNTAPPED_CREATURE)); + this.addAbility(ability); + } + + private PurplePentapus(final PurplePentapus card) { + super(card); + } + + @Override + public PurplePentapus copy() { + return new PurplePentapus(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 430d47a10a1..d81e5167f7e 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -61,6 +61,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Match the Odds", 253, Rarity.UNCOMMON, mage.cards.m.MatchTheOdds.class)); cards.add(new SetCardInfo("Mechanical Glider", 256, Rarity.COMMON, mage.cards.m.MechanicalGlider.class)); cards.add(new SetCardInfo("Momo, Rambunctious Rascal", 217, Rarity.UNCOMMON, mage.cards.m.MomoRambunctiousRascal.class)); + cards.add(new SetCardInfo("Purple Pentapus", 233, Rarity.COMMON, mage.cards.p.PurplePentapus.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); cards.add(new SetCardInfo("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From 654936841725a85fc2e50364d14db5070f1e137d Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:15:29 -0400 Subject: [PATCH 48/60] [TLE] Implement Roku's Mastery --- Mage.Sets/src/mage/cards/r/RokusMastery.java | 50 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 51 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RokusMastery.java diff --git a/Mage.Sets/src/mage/cards/r/RokusMastery.java b/Mage.Sets/src/mage/cards/r/RokusMastery.java new file mode 100644 index 00000000000..628368354f8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RokusMastery.java @@ -0,0 +1,50 @@ +package mage.cards.r; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.dynamicvalue.common.GetXValue; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.keyword.ScryEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.Game; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RokusMastery extends CardImpl { + + public RokusMastery(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{R}{R}"); + + // Roku's Mastery deals X damage to target creature. If X is 4 or greater, scry 2. + this.getSpellAbility().addEffect(new DamageTargetEffect(GetXValue.instance)); + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new ScryEffect(2), RokusMasteryCondition.instance, "If X is 4 or greater, scry 2" + )); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + private RokusMastery(final RokusMastery card) { + super(card); + } + + @Override + public RokusMastery copy() { + return new RokusMastery(this); + } +} + +enum RokusMasteryCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return GetXValue.instance.calculate(game, source, null) >= 4; + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index d81e5167f7e..975f407df9e 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -62,6 +62,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Mechanical Glider", 256, Rarity.COMMON, mage.cards.m.MechanicalGlider.class)); cards.add(new SetCardInfo("Momo, Rambunctious Rascal", 217, Rarity.UNCOMMON, mage.cards.m.MomoRambunctiousRascal.class)); cards.add(new SetCardInfo("Purple Pentapus", 233, Rarity.COMMON, mage.cards.p.PurplePentapus.class)); + cards.add(new SetCardInfo("Roku's Mastery", 243, Rarity.UNCOMMON, mage.cards.r.RokusMastery.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); cards.add(new SetCardInfo("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From 65616841cbc278fb009135d2347bde829eab0eeb Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:16:25 -0400 Subject: [PATCH 49/60] [TLE] Implement Sledding Otter-Penguin --- .../mage/cards/s/SleddingOtterPenguin.java | 42 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 43 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SleddingOtterPenguin.java diff --git a/Mage.Sets/src/mage/cards/s/SleddingOtterPenguin.java b/Mage.Sets/src/mage/cards/s/SleddingOtterPenguin.java new file mode 100644 index 00000000000..bc1cd5a5f5e --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SleddingOtterPenguin.java @@ -0,0 +1,42 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SleddingOtterPenguin extends CardImpl { + + public SleddingOtterPenguin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.OTTER); + this.subtype.add(SubType.BIRD); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // {3}: Put a +1/+1 counter on this creature. + this.addAbility(new SimpleActivatedAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new GenericManaCost(3) + )); + } + + private SleddingOtterPenguin(final SleddingOtterPenguin card) { + super(card); + } + + @Override + public SleddingOtterPenguin copy() { + return new SleddingOtterPenguin(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 975f407df9e..cac8486eeea 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -64,6 +64,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Purple Pentapus", 233, Rarity.COMMON, mage.cards.p.PurplePentapus.class)); cards.add(new SetCardInfo("Roku's Mastery", 243, Rarity.UNCOMMON, mage.cards.r.RokusMastery.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); + cards.add(new SetCardInfo("Sledding Otter-Penguin", 218, Rarity.COMMON, mage.cards.s.SleddingOtterPenguin.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); cards.add(new SetCardInfo("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); cards.add(new SetCardInfo("The Terror of Serpent's Pass", 225, Rarity.RARE, mage.cards.t.TheTerrorOfSerpentsPass.class)); From 1b87743605eeb1285ad05b7856555103bc2ce114 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:16:54 -0400 Subject: [PATCH 50/60] [TLE] Implement Sokka, Wolf Cove's Protector --- .../mage/cards/s/SokkaWolfCovesProtector.java | 40 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 41 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SokkaWolfCovesProtector.java diff --git a/Mage.Sets/src/mage/cards/s/SokkaWolfCovesProtector.java b/Mage.Sets/src/mage/cards/s/SokkaWolfCovesProtector.java new file mode 100644 index 00000000000..378da070f96 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SokkaWolfCovesProtector.java @@ -0,0 +1,40 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SokkaWolfCovesProtector extends CardImpl { + + public SokkaWolfCovesProtector(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + } + + private SokkaWolfCovesProtector(final SokkaWolfCovesProtector card) { + super(card); + } + + @Override + public SokkaWolfCovesProtector copy() { + return new SokkaWolfCovesProtector(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index cac8486eeea..ce827842ccb 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -65,6 +65,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Roku's Mastery", 243, Rarity.UNCOMMON, mage.cards.r.RokusMastery.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); cards.add(new SetCardInfo("Sledding Otter-Penguin", 218, Rarity.COMMON, mage.cards.s.SleddingOtterPenguin.class)); + cards.add(new SetCardInfo("Sokka, Wolf Cove's Protector", 219, Rarity.UNCOMMON, mage.cards.s.SokkaWolfCovesProtector.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); cards.add(new SetCardInfo("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); cards.add(new SetCardInfo("The Terror of Serpent's Pass", 225, Rarity.RARE, mage.cards.t.TheTerrorOfSerpentsPass.class)); From ef2e4858a34d06e23cd0417f3ba5725b9615f8f5 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:17:16 -0400 Subject: [PATCH 51/60] [TLE] Implement Turtle-Seals --- Mage.Sets/src/mage/cards/t/TurtleSeals.java | 37 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TurtleSeals.java diff --git a/Mage.Sets/src/mage/cards/t/TurtleSeals.java b/Mage.Sets/src/mage/cards/t/TurtleSeals.java new file mode 100644 index 00000000000..ca402fa8aa1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TurtleSeals.java @@ -0,0 +1,37 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TurtleSeals extends CardImpl { + + public TurtleSeals(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add(SubType.TURTLE); + this.subtype.add(SubType.SEAL); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + } + + private TurtleSeals(final TurtleSeals card) { + super(card); + } + + @Override + public TurtleSeals copy() { + return new TurtleSeals(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index ce827842ccb..373d8a07293 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -75,6 +75,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Thriving Isle", 263, Rarity.COMMON, mage.cards.t.ThrivingIsle.class)); cards.add(new SetCardInfo("Thriving Moor", 264, Rarity.COMMON, mage.cards.t.ThrivingMoor.class)); cards.add(new SetCardInfo("Tundra Wall", 220, Rarity.COMMON, mage.cards.t.TundraWall.class)); + cards.add(new SetCardInfo("Turtle-Seals", 226, Rarity.COMMON, mage.cards.t.TurtleSeals.class)); cards.add(new SetCardInfo("Water Whip", 227, Rarity.RARE, mage.cards.w.WaterWhip.class)); cards.add(new SetCardInfo("Wolf Cove Villager", 221, Rarity.COMMON, mage.cards.w.WolfCoveVillager.class)); cards.add(new SetCardInfo("Zhao, the Seething Flame", 245, Rarity.UNCOMMON, mage.cards.z.ZhaoTheSeethingFlame.class)); From b3c699ef6e1166e80320bfac3246cd0762a52bb3 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:17:39 -0400 Subject: [PATCH 52/60] [TLE] Implement Warship Scout --- Mage.Sets/src/mage/cards/w/WarshipScout.java | 33 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 34 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WarshipScout.java diff --git a/Mage.Sets/src/mage/cards/w/WarshipScout.java b/Mage.Sets/src/mage/cards/w/WarshipScout.java new file mode 100644 index 00000000000..3aed4831ebd --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WarshipScout.java @@ -0,0 +1,33 @@ +package mage.cards.w; + +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class WarshipScout extends CardImpl { + + public WarshipScout(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SCOUT); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + } + + private WarshipScout(final WarshipScout card) { + super(card); + } + + @Override + public WarshipScout copy() { + return new WarshipScout(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 373d8a07293..be83fb15e78 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -76,6 +76,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Thriving Moor", 264, Rarity.COMMON, mage.cards.t.ThrivingMoor.class)); cards.add(new SetCardInfo("Tundra Wall", 220, Rarity.COMMON, mage.cards.t.TundraWall.class)); cards.add(new SetCardInfo("Turtle-Seals", 226, Rarity.COMMON, mage.cards.t.TurtleSeals.class)); + cards.add(new SetCardInfo("Warship Scout", 244, Rarity.COMMON, mage.cards.w.WarshipScout.class)); cards.add(new SetCardInfo("Water Whip", 227, Rarity.RARE, mage.cards.w.WaterWhip.class)); cards.add(new SetCardInfo("Wolf Cove Villager", 221, Rarity.COMMON, mage.cards.w.WolfCoveVillager.class)); cards.add(new SetCardInfo("Zhao, the Seething Flame", 245, Rarity.UNCOMMON, mage.cards.z.ZhaoTheSeethingFlame.class)); From 37b41461711186a4effcb7a965d63a58521763c4 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:18:44 -0400 Subject: [PATCH 53/60] [TLE] Implement Zuko, Avatar Hunter --- .../src/mage/cards/z/ZukoAvatarHunter.java | 56 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 57 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/z/ZukoAvatarHunter.java diff --git a/Mage.Sets/src/mage/cards/z/ZukoAvatarHunter.java b/Mage.Sets/src/mage/cards/z/ZukoAvatarHunter.java new file mode 100644 index 00000000000..a8867db8960 --- /dev/null +++ b/Mage.Sets/src/mage/cards/z/ZukoAvatarHunter.java @@ -0,0 +1,56 @@ +package mage.cards.z; + +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.FilterSpell; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.permanent.token.SoldierRedToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ZukoAvatarHunter extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("a red spell"); + + static { + filter.add(new ColorPredicate(ObjectColor.RED)); + } + + public ZukoAvatarHunter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.NOBLE); + this.power = new MageInt(4); + this.toughness = new MageInt(5); + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // Whenever you cast a red spell, create a 2/2 red Soldier creature token. + this.addAbility(new SpellCastControllerTriggeredAbility( + new CreateTokenEffect(new SoldierRedToken()), filter, false + )); + } + + private ZukoAvatarHunter(final ZukoAvatarHunter card) { + super(card); + } + + @Override + public ZukoAvatarHunter copy() { + return new ZukoAvatarHunter(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index be83fb15e78..1e915a72983 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -81,6 +81,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Wolf Cove Villager", 221, Rarity.COMMON, mage.cards.w.WolfCoveVillager.class)); cards.add(new SetCardInfo("Zhao, the Seething Flame", 245, Rarity.UNCOMMON, mage.cards.z.ZhaoTheSeethingFlame.class)); cards.add(new SetCardInfo("Zuko's Offense", 247, Rarity.COMMON, mage.cards.z.ZukosOffense.class)); + cards.add(new SetCardInfo("Zuko, Avatar Hunter", 246, Rarity.RARE, mage.cards.z.ZukoAvatarHunter.class)); cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName())); } From 3b5ee47175308954b5d463f7bd3e00e36744964b Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 09:21:37 -0400 Subject: [PATCH 54/60] [TLE] Implement Lion Vulture --- Mage.Sets/src/mage/cards/l/LionVulture.java | 51 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 52 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LionVulture.java diff --git a/Mage.Sets/src/mage/cards/l/LionVulture.java b/Mage.Sets/src/mage/cards/l/LionVulture.java new file mode 100644 index 00000000000..adf1b4da970 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LionVulture.java @@ -0,0 +1,51 @@ +package mage.cards.l; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.condition.common.OpponentsLostLifeCondition; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.hint.common.OpponentsLostLifeHint; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class LionVulture extends CardImpl { + + public LionVulture(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.CAT); + this.subtype.add(SubType.BIRD); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // At the beginning of your end step, if an opponent lost life this turn, put a +1/+1 counter on this creature and draw a card. + Ability ability = new BeginningOfEndStepTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()) + ).withInterveningIf(OpponentsLostLifeCondition.instance); + ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and")); + this.addAbility(ability.addHint(OpponentsLostLifeHint.instance)); + } + + private LionVulture(final LionVulture card) { + super(card); + } + + @Override + public LionVulture copy() { + return new LionVulture(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 1e915a72983..425365d194c 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -57,6 +57,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Katara, Waterbending Master", 93, Rarity.MYTHIC, mage.cards.k.KataraWaterbendingMaster.class)); cards.add(new SetCardInfo("Komodo Rhino", 241, Rarity.COMMON, mage.cards.k.KomodoRhino.class)); cards.add(new SetCardInfo("Kyoshi Warrior Guard", 216, Rarity.COMMON, mage.cards.k.KyoshiWarriorGuard.class)); + cards.add(new SetCardInfo("Lion Vulture", 232, Rarity.RARE, mage.cards.l.LionVulture.class)); cards.add(new SetCardInfo("Loyal Fire Sage", 242, Rarity.UNCOMMON, mage.cards.l.LoyalFireSage.class)); cards.add(new SetCardInfo("Match the Odds", 253, Rarity.UNCOMMON, mage.cards.m.MatchTheOdds.class)); cards.add(new SetCardInfo("Mechanical Glider", 256, Rarity.COMMON, mage.cards.m.MechanicalGlider.class)); From 5d5ce4e0ab8eedc3eb27fa47646815d2ced05ef7 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 10:47:44 -0400 Subject: [PATCH 55/60] [TLE] Implement Lost in the Spirit World --- .../mage/cards/l/LostInTheSpiritWorld.java | 35 +++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + .../permanent/token/SpiritWorldToken.java | 44 +++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LostInTheSpiritWorld.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/SpiritWorldToken.java diff --git a/Mage.Sets/src/mage/cards/l/LostInTheSpiritWorld.java b/Mage.Sets/src/mage/cards/l/LostInTheSpiritWorld.java new file mode 100644 index 00000000000..e486eeb4d6d --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LostInTheSpiritWorld.java @@ -0,0 +1,35 @@ +package mage.cards.l; + +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.SpiritWorldToken; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class LostInTheSpiritWorld extends CardImpl { + + public LostInTheSpiritWorld(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}"); + + // Return up to one target creature to its owner's hand. Create a 1/1 colorless Spirit creature token with "This token can't block or be blocked by non-Spirit creatures." + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1)); + this.getSpellAbility().addEffect(new CreateTokenEffect(new SpiritWorldToken())); + } + + private LostInTheSpiritWorld(final LostInTheSpiritWorld card) { + super(card); + } + + @Override + public LostInTheSpiritWorld copy() { + return new LostInTheSpiritWorld(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 425365d194c..81e72d23ef5 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -58,6 +58,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Komodo Rhino", 241, Rarity.COMMON, mage.cards.k.KomodoRhino.class)); cards.add(new SetCardInfo("Kyoshi Warrior Guard", 216, Rarity.COMMON, mage.cards.k.KyoshiWarriorGuard.class)); cards.add(new SetCardInfo("Lion Vulture", 232, Rarity.RARE, mage.cards.l.LionVulture.class)); + cards.add(new SetCardInfo("Lost in the Spirit World", 224, Rarity.UNCOMMON, mage.cards.l.LostInTheSpiritWorld.class)); cards.add(new SetCardInfo("Loyal Fire Sage", 242, Rarity.UNCOMMON, mage.cards.l.LoyalFireSage.class)); cards.add(new SetCardInfo("Match the Odds", 253, Rarity.UNCOMMON, mage.cards.m.MatchTheOdds.class)); cards.add(new SetCardInfo("Mechanical Glider", 256, Rarity.COMMON, mage.cards.m.MechanicalGlider.class)); diff --git a/Mage/src/main/java/mage/game/permanent/token/SpiritWorldToken.java b/Mage/src/main/java/mage/game/permanent/token/SpiritWorldToken.java new file mode 100644 index 00000000000..b67361323db --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/SpiritWorldToken.java @@ -0,0 +1,44 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; +import mage.abilities.effects.common.combat.CantBlockCreaturesSourceEffect; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; + +/** + * @author TheElk801 + */ +public final class SpiritWorldToken extends TokenImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(Predicates.not(SubType.SPIRIT.getPredicate())); + } + + public SpiritWorldToken() { + super("Spirit Token", "1/1 colorless Spirit creature token with \"This token can't block or be blocked by non-Spirit creatures.\""); + cardType.add(CardType.CREATURE); + subtype.add(SubType.SPIRIT); + power = new MageInt(1); + toughness = new MageInt(1); + + Ability ability = new SimpleStaticAbility(new CantBlockCreaturesSourceEffect(filter).setText("this token can't block")); + ability.addEffect(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield).setText("or be blocked by non-Spirit creatures")); + this.addAbility(ability); + } + + private SpiritWorldToken(final SpiritWorldToken token) { + super(token); + } + + public SpiritWorldToken copy() { + return new SpiritWorldToken(this); + } +} From d0fa2bc125bd1072d89990d175e925f0972dcc52 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 10:49:34 -0400 Subject: [PATCH 56/60] [TLE] Implement Seismic Tutelage --- .../src/mage/cards/s/SeismicTutelage.java | 54 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 55 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SeismicTutelage.java diff --git a/Mage.Sets/src/mage/cards/s/SeismicTutelage.java b/Mage.Sets/src/mage/cards/s/SeismicTutelage.java new file mode 100644 index 00000000000..c93c4e06f2c --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SeismicTutelage.java @@ -0,0 +1,54 @@ +package mage.cards.s; + +import mage.abilities.common.AttacksAttachedTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DoubleCountersTargetEffect; +import mage.abilities.effects.common.counter.AddCountersAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.CounterType; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SeismicTutelage extends CardImpl { + + public SeismicTutelage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + this.addAbility(new EnchantAbility(auraTarget)); + + // When this Aura enters, put a +1/+1 counter on enchanted creature. + this.addAbility(new EntersBattlefieldTriggeredAbility( + new AddCountersAttachedEffect(CounterType.P1P1.createInstance(), "enchanted creature") + )); + + // Whenever enchanted creature attacks, double the number of +1/+1 counters on it. + this.addAbility(new AttacksAttachedTriggeredAbility( + new DoubleCountersTargetEffect(CounterType.P1P1), + AttachmentType.AURA, false, SetTargetPointer.PERMANENT + )); + } + + private SeismicTutelage(final SeismicTutelage card) { + super(card); + } + + @Override + public SeismicTutelage copy() { + return new SeismicTutelage(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 81e72d23ef5..877f0be8ad6 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -66,6 +66,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Purple Pentapus", 233, Rarity.COMMON, mage.cards.p.PurplePentapus.class)); cards.add(new SetCardInfo("Roku's Mastery", 243, Rarity.UNCOMMON, mage.cards.r.RokusMastery.class)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); + cards.add(new SetCardInfo("Seismic Tutelage", 254, Rarity.RARE, mage.cards.s.SeismicTutelage.class)); cards.add(new SetCardInfo("Sledding Otter-Penguin", 218, Rarity.COMMON, mage.cards.s.SleddingOtterPenguin.class)); cards.add(new SetCardInfo("Sokka, Wolf Cove's Protector", 219, Rarity.UNCOMMON, mage.cards.s.SokkaWolfCovesProtector.class)); cards.add(new SetCardInfo("The Cabbage Merchant", 134, Rarity.RARE, mage.cards.t.TheCabbageMerchant.class)); From f3447ffc875989747a6ed59121260fc21e237b69 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 10:52:35 -0400 Subject: [PATCH 57/60] [TLA] Implement Path to Redemption --- .../src/mage/cards/p/PathToRedemption.java | 62 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 63 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PathToRedemption.java diff --git a/Mage.Sets/src/mage/cards/p/PathToRedemption.java b/Mage.Sets/src/mage/cards/p/PathToRedemption.java new file mode 100644 index 00000000000..d891ecc4354 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PathToRedemption.java @@ -0,0 +1,62 @@ +package mage.cards.p; + +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.MyTurnCondition; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.ExileAttachedEffect; +import mage.abilities.effects.common.combat.CantAttackBlockAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.game.permanent.token.AllyToken; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PathToRedemption extends CardImpl { + + public PathToRedemption(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + this.addAbility(new EnchantAbility(auraTarget)); + + // Enchanted creature can't attack or block. + this.addAbility(new SimpleStaticAbility(new CantAttackBlockAttachedEffect(AttachmentType.AURA))); + + // {5}, Sacrifice this Aura: Exile enchanted creature. Create a 1/1 white Ally creature token. Activate only during your turn. + Ability ability = new ActivateIfConditionActivatedAbility( + new ExileAttachedEffect(), new GenericManaCost(5), MyTurnCondition.instance + ); + ability.addCost(new SacrificeSourceCost()); + ability.addEffect(new CreateTokenEffect(new AllyToken())); + this.addAbility(ability); + } + + private PathToRedemption(final PathToRedemption card) { + super(card); + } + + @Override + public PathToRedemption copy() { + return new PathToRedemption(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 6d94efd8fff..22cb4a5116c 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -87,6 +87,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Ostrich-Horse", 188, Rarity.COMMON, mage.cards.o.OstrichHorse.class)); cards.add(new SetCardInfo("Otter-Penguin", 67, Rarity.COMMON, mage.cards.o.OtterPenguin.class)); cards.add(new SetCardInfo("Ozai's Cruelty", 113, Rarity.UNCOMMON, mage.cards.o.OzaisCruelty.class)); + cards.add(new SetCardInfo("Path to Redemption", 31, Rarity.COMMON, mage.cards.p.PathToRedemption.class)); cards.add(new SetCardInfo("Pillar Launch", 189, Rarity.COMMON, mage.cards.p.PillarLaunch.class)); cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Pretending Poxbearers", 237, Rarity.COMMON, mage.cards.p.PretendingPoxbearers.class)); From 2202bd4453b432568a249c573e284858fcaf1bbc Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 10:55:00 -0400 Subject: [PATCH 58/60] [TLA] Implement Hei Bai, Spirit of Balance --- .../mage/cards/h/HeiBaiSpiritOfBalance.java | 56 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 57 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HeiBaiSpiritOfBalance.java diff --git a/Mage.Sets/src/mage/cards/h/HeiBaiSpiritOfBalance.java b/Mage.Sets/src/mage/cards/h/HeiBaiSpiritOfBalance.java new file mode 100644 index 00000000000..4ea8c21f004 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HeiBaiSpiritOfBalance.java @@ -0,0 +1,56 @@ +package mage.cards.h; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; +import mage.abilities.common.LeavesBattlefieldTriggeredAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.PutSourceCountersOnTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.target.common.TargetControlledCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class HeiBaiSpiritOfBalance extends CardImpl { + + public HeiBaiSpiritOfBalance(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W/B}{W/B}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.BEAR); + this.subtype.add(SubType.SPIRIT); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Whenever Hei Bai enters or attacks, you may sacrifice another creature or artifact. If you do, put two +1/+1 counters on Hei Bai. + this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new DoIfCostPaid( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE_OR_ARTIFACT) + ))); + + // When Hei Bai leaves the battlefield, put its counters on target creature you control. + Ability ability = new LeavesBattlefieldTriggeredAbility(new PutSourceCountersOnTargetEffect()); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.addAbility(ability); + } + + private HeiBaiSpiritOfBalance(final HeiBaiSpiritOfBalance card) { + super(card); + } + + @Override + public HeiBaiSpiritOfBalance copy() { + return new HeiBaiSpiritOfBalance(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 22cb4a5116c..97f875e2bfb 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -67,6 +67,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Glider Kids", 21, Rarity.COMMON, mage.cards.g.GliderKids.class)); cards.add(new SetCardInfo("Haru, Hidden Talent", 182, Rarity.UNCOMMON, mage.cards.h.HaruHiddenTalent.class)); cards.add(new SetCardInfo("Heartless Act", 103, Rarity.UNCOMMON, mage.cards.h.HeartlessAct.class)); + cards.add(new SetCardInfo("Hei Bai, Spirit of Balance", 225, Rarity.UNCOMMON, mage.cards.h.HeiBaiSpiritOfBalance.class)); cards.add(new SetCardInfo("Hog-Monkey", 104, Rarity.COMMON, mage.cards.h.HogMonkey.class)); cards.add(new SetCardInfo("Iguana Parrot", 56, Rarity.COMMON, mage.cards.i.IguanaParrot.class)); cards.add(new SetCardInfo("Island", 288, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); From 5f8f0c96f3f956ad344a7c145a2c8ad29a847775 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 10:58:31 -0400 Subject: [PATCH 59/60] [TLA] Implement Flopsie, Bumi's Buddy --- .../src/mage/cards/f/FlopsieBumisBuddy.java | 60 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 61 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FlopsieBumisBuddy.java diff --git a/Mage.Sets/src/mage/cards/f/FlopsieBumisBuddy.java b/Mage.Sets/src/mage/cards/f/FlopsieBumisBuddy.java new file mode 100644 index 00000000000..993778fe326 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FlopsieBumisBuddy.java @@ -0,0 +1,60 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.combat.CantBeBlockedByMoreThanOneAllEffect; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FlopsieBumisBuddy extends CardImpl { + + private static final FilterPermanent filter + = new FilterControlledCreaturePermanent("creature you control with power 4 or greater"); + + static { + filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 3)); + } + + public FlopsieBumisBuddy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.APE); + this.subtype.add(SubType.GOAT); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // When Flopsie enters, put a +1/+1 counter on each creature you control. + this.addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersAllEffect( + CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE + ))); + + // Each creature you control with power 4 or greater can't be blocked by more than one creature. + this.addAbility(new SimpleStaticAbility(new CantBeBlockedByMoreThanOneAllEffect(filter))); + } + + private FlopsieBumisBuddy(final FlopsieBumisBuddy card) { + super(card); + } + + @Override + public FlopsieBumisBuddy copy() { + return new FlopsieBumisBuddy(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 97f875e2bfb..88ffcbad426 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -61,6 +61,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Fire Sages", 136, Rarity.UNCOMMON, mage.cards.f.FireSages.class)); cards.add(new SetCardInfo("First-Time Flyer", 49, Rarity.COMMON, mage.cards.f.FirstTimeFlyer.class)); cards.add(new SetCardInfo("Flexible Waterbender", 50, Rarity.COMMON, mage.cards.f.FlexibleWaterbender.class)); + cards.add(new SetCardInfo("Flopsie, Bumi's Buddy", 179, Rarity.UNCOMMON, mage.cards.f.FlopsieBumisBuddy.class)); cards.add(new SetCardInfo("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Geyser Leaper", 52, Rarity.COMMON, mage.cards.g.GeyserLeaper.class)); cards.add(new SetCardInfo("Giant Koi", 53, Rarity.COMMON, mage.cards.g.GiantKoi.class)); From 0df1c4b128ab2f4e57182d0f9a40d0aac6aa2d69 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 15 Aug 2025 11:03:53 -0400 Subject: [PATCH 60/60] [TLA] Implement Buzzard-Wasp Colony --- .../src/mage/cards/b/BuzzardWaspColony.java | 99 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 100 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BuzzardWaspColony.java diff --git a/Mage.Sets/src/mage/cards/b/BuzzardWaspColony.java b/Mage.Sets/src/mage/cards/b/BuzzardWaspColony.java new file mode 100644 index 00000000000..25eef058a85 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BuzzardWaspColony.java @@ -0,0 +1,99 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.counters.Counter; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.filter.predicate.permanent.CounterAnyPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BuzzardWaspColony extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledCreaturePermanent("another creature you control"); + + static { + filter.add(AnotherPredicate.instance); + filter.add(CounterAnyPredicate.instance); + } + + public BuzzardWaspColony(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.BIRD); + this.subtype.add(SubType.INSECT); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When this creature enters, you may sacrifice an artifact or creature. If you do, draw a card. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DoIfCostPaid( + new DrawCardSourceControllerEffect(1), + new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE) + ))); + + // Whenever another creature you control dies, if it had counters on it, put its counters on this creature. + this.addAbility(new DiesCreatureTriggeredAbility(new BuzzardWaspColonyEffect(), false, filter)); + } + + private BuzzardWaspColony(final BuzzardWaspColony card) { + super(card); + } + + @Override + public BuzzardWaspColony copy() { + return new BuzzardWaspColony(this); + } +} + +class BuzzardWaspColonyEffect extends OneShotEffect { + + BuzzardWaspColonyEffect() { + super(Outcome.Benefit); + staticText = "if it had counters on it, put its counters on {this}"; + } + + private BuzzardWaspColonyEffect(final BuzzardWaspColonyEffect effect) { + super(effect); + } + + @Override + public BuzzardWaspColonyEffect copy() { + return new BuzzardWaspColonyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = source.getSourcePermanentIfItStillExists(game); + Permanent creature = (Permanent) getValue("creatureDied"); + if (permanent == null || creature == null) { + return false; + } + for (Counter counter : creature.getCounters(game).values()) { + permanent.addCounters(counter.copy(), source, game); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 88ffcbad426..363d71b4765 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -42,6 +42,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Barrels of Blasting Jelly", 254, Rarity.COMMON, mage.cards.b.BarrelsOfBlastingJelly.class)); cards.add(new SetCardInfo("Beetle-Headed Merchants", 86, Rarity.COMMON, mage.cards.b.BeetleHeadedMerchants.class)); cards.add(new SetCardInfo("Bender's Waterskin", 255, Rarity.COMMON, mage.cards.b.BendersWaterskin.class)); + cards.add(new SetCardInfo("Buzzard-Wasp Colony", 88, Rarity.UNCOMMON, mage.cards.b.BuzzardWaspColony.class)); cards.add(new SetCardInfo("Cat-Gator", 91, Rarity.UNCOMMON, mage.cards.c.CatGator.class)); cards.add(new SetCardInfo("Cat-Owl", 212, Rarity.COMMON, mage.cards.c.CatOwl.class)); cards.add(new SetCardInfo("Corrupt Court Official", 92, Rarity.COMMON, mage.cards.c.CorruptCourtOfficial.class));