From 7a241a6f1eca60dea0fa952b2799aa3f996e05b5 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Tue, 12 Aug 2025 20:39:22 -0400 Subject: [PATCH 01/68] [TLA] Implement Toph, the First Metalbender --- .../mage/cards/t/TophTheFirstMetalbender.java | 87 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 3 + .../keyword/EarthbendTargetEffect.java | 2 + 3 files changed, 92 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TophTheFirstMetalbender.java diff --git a/Mage.Sets/src/mage/cards/t/TophTheFirstMetalbender.java b/Mage.Sets/src/mage/cards/t/TophTheFirstMetalbender.java new file mode 100644 index 00000000000..bb8cb053c15 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TophTheFirstMetalbender.java @@ -0,0 +1,87 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.keyword.EarthbendTargetEffect; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +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 java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TophTheFirstMetalbender extends CardImpl { + + public TophTheFirstMetalbender(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{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(3); + this.toughness = new MageInt(3); + + // Nontoken artifacts you control are lands in addition to their other types. + this.addAbility(new SimpleStaticAbility(new TophTheFirstMetalbenderEffect())); + + // 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)); + this.addAbility(ability); + } + + private TophTheFirstMetalbender(final TophTheFirstMetalbender card) { + super(card); + } + + @Override + public TophTheFirstMetalbender copy() { + return new TophTheFirstMetalbender(this); + } +} + +class TophTheFirstMetalbenderEffect extends ContinuousEffectImpl { + + private static final FilterPermanent filter = new FilterControlledArtifactPermanent(); + + static { + filter.add(TokenPredicate.FALSE); + } + + TophTheFirstMetalbenderEffect() { + super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); + staticText = "nontoken artifacts you control are lands in addition to their other types"; + } + + private TophTheFirstMetalbenderEffect(final TophTheFirstMetalbenderEffect effect) { + super(effect); + } + + @Override + public TophTheFirstMetalbenderEffect copy() { + return new TophTheFirstMetalbenderEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (Permanent permanent : game.getBattlefield().getActivePermanents( + filter, source.getControllerId(), source, game + )) { + permanent.addCardType(game, CardType.LAND); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 856aa95c928..162d243d850 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -46,6 +46,9 @@ public final class AvatarTheLastAirbender extends ExpansionSet { 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("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)); + cards.add(new SetCardInfo("Toph, the First Metalbender", 362, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS)); 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)); diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/EarthbendTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/EarthbendTargetEffect.java index 7ec45c93c3a..9982a5dc7fc 100644 --- a/Mage/src/main/java/mage/abilities/effects/keyword/EarthbendTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/keyword/EarthbendTargetEffect.java @@ -11,6 +11,7 @@ import mage.abilities.keyword.HasteAbility; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; +import mage.counters.CounterType; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; @@ -52,6 +53,7 @@ public class EarthbendTargetEffect extends OneShotEffect { .withAbility(HasteAbility.getInstance()), false, true, Duration.Custom ), source); + permanent.addCounters(CounterType.P1P1.createInstance(amount), source, game); game.addDelayedTriggeredAbility(new EarthbendingDelayedTriggeredAbility(permanent, game), source); game.fireEvent(GameEvent.getEvent( GameEvent.EventType.EARTHBENDED, permanent.getId(), From 9828e56590c009c7e76c4b2e4867d50a37051c8c Mon Sep 17 00:00:00 2001 From: theelk801 Date: Tue, 12 Aug 2025 20:54:38 -0400 Subject: [PATCH 02/68] [TLA] waterbend is a cost, not an ability --- Mage.Sets/src/mage/cards/a/AangsIceberg.java | 8 ++-- .../src/mage/cards/y/YueTheMoonSpirit.java | 6 +-- .../abilities/costs/common/WaterbendCost.java | 44 +++++++++++++++++++ .../abilities/costs/mana/ManaCostsImpl.java | 3 +- .../abilities/keyword/WaterbendAbility.java | 37 ---------------- 5 files changed, 52 insertions(+), 46 deletions(-) create mode 100644 Mage/src/main/java/mage/abilities/costs/common/WaterbendCost.java delete mode 100644 Mage/src/main/java/mage/abilities/keyword/WaterbendAbility.java diff --git a/Mage.Sets/src/mage/cards/a/AangsIceberg.java b/Mage.Sets/src/mage/cards/a/AangsIceberg.java index 03f3008cdaf..3b37939c473 100644 --- a/Mage.Sets/src/mage/cards/a/AangsIceberg.java +++ b/Mage.Sets/src/mage/cards/a/AangsIceberg.java @@ -2,13 +2,13 @@ package mage.cards.a; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; -import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.costs.common.WaterbendCost; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.effects.keyword.ScryEffect; import mage.abilities.keyword.FlashAbility; -import mage.abilities.keyword.WaterbendAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -42,9 +42,9 @@ public final class AangsIceberg extends CardImpl { this.addAbility(ability); // Waterbend {3}: Sacrifice this enchantment. If you do, scry 2. - this.addAbility(new WaterbendAbility(new DoIfCostPaid( + this.addAbility(new SimpleActivatedAbility(new DoIfCostPaid( new ScryEffect(2), new SacrificeSourceCost(), null, false - ), new GenericManaCost(3))); + ), new WaterbendCost(3))); } private AangsIceberg(final AangsIceberg card) { diff --git a/Mage.Sets/src/mage/cards/y/YueTheMoonSpirit.java b/Mage.Sets/src/mage/cards/y/YueTheMoonSpirit.java index 903a06b5d59..c2a37a0ff2e 100644 --- a/Mage.Sets/src/mage/cards/y/YueTheMoonSpirit.java +++ b/Mage.Sets/src/mage/cards/y/YueTheMoonSpirit.java @@ -2,12 +2,12 @@ package mage.cards.y; import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.costs.common.WaterbendCost; import mage.abilities.effects.common.cost.CastFromHandForFreeEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.VigilanceAbility; -import mage.abilities.keyword.WaterbendAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -45,7 +45,7 @@ public final class YueTheMoonSpirit extends CardImpl { this.addAbility(VigilanceAbility.getInstance()); // Waterbend {5}, {T}: You may cast a noncreature spell from your hand without paying its mana cost. - Ability ability = new WaterbendAbility(new CastFromHandForFreeEffect(filter), new GenericManaCost(5)); + Ability ability = new SimpleActivatedAbility(new CastFromHandForFreeEffect(filter), new WaterbendCost(5)); ability.addCost(new TapSourceCost()); this.addAbility(ability); } diff --git a/Mage/src/main/java/mage/abilities/costs/common/WaterbendCost.java b/Mage/src/main/java/mage/abilities/costs/common/WaterbendCost.java new file mode 100644 index 00000000000..e1ea59d094a --- /dev/null +++ b/Mage/src/main/java/mage/abilities/costs/common/WaterbendCost.java @@ -0,0 +1,44 @@ +package mage.abilities.costs.common; + +import mage.abilities.Ability; +import mage.abilities.costs.Cost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.game.Game; + +import java.util.UUID; + +/** + * TODO: Implement properly + * + * @author TheElk801 + */ +public class WaterbendCost extends ManaCostsImpl { + + public WaterbendCost(int amount) { + this("{" + amount + '}'); + } + + public WaterbendCost(String mana) { + super(""); + this.text = "waterbend " + mana; + } + + private WaterbendCost(final WaterbendCost cost) { + super(cost); + } + + @Override + public WaterbendCost copy() { + return new WaterbendCost(this); + } + + @Override + public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { + return false; + } + + @Override + public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { + return false; + } +} diff --git a/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java b/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java index 70ba8044ff5..566934b34c7 100644 --- a/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java +++ b/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java @@ -10,7 +10,6 @@ import mage.constants.ColoredManaSymbol; import mage.constants.ManaType; import mage.constants.Outcome; import mage.filter.Filter; -import mage.filter.FilterMana; import mage.game.Game; import mage.players.ManaPool; import mage.players.Player; @@ -43,7 +42,7 @@ public class ManaCostsImpl extends ArrayList implements M load(mana); } - private ManaCostsImpl(final ManaCostsImpl costs) { + protected ManaCostsImpl(final ManaCostsImpl costs) { this.id = costs.id; this.text = costs.text; this.ensureCapacity(costs.size()); diff --git a/Mage/src/main/java/mage/abilities/keyword/WaterbendAbility.java b/Mage/src/main/java/mage/abilities/keyword/WaterbendAbility.java deleted file mode 100644 index f955cbcda41..00000000000 --- a/Mage/src/main/java/mage/abilities/keyword/WaterbendAbility.java +++ /dev/null @@ -1,37 +0,0 @@ -package mage.abilities.keyword; - -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.Cost; -import mage.abilities.effects.Effect; -import mage.constants.Zone; -import mage.util.CardUtil; - -/** - * TODO: Implement properly - * - * @author TheElk801 - */ -public class WaterbendAbility extends SimpleActivatedAbility { - - public WaterbendAbility(Effect effect, Cost cost) { - this(Zone.BATTLEFIELD, effect, cost); - } - - public WaterbendAbility(Zone zone, Effect effect, Cost cost) { - super(zone, effect, cost); - } - - private WaterbendAbility(final WaterbendAbility ability) { - super(ability); - } - - @Override - public WaterbendAbility copy() { - return new WaterbendAbility(this); - } - - @Override - public String getRule() { - return "Waterbend " + CardUtil.getTextWithFirstCharUpperCase(super.getRule()); - } -} From 16c789aaf7abf23386209b8465d47a0ced6dba84 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Tue, 12 Aug 2025 20:58:39 -0400 Subject: [PATCH 03/68] [TLA] Implement Katara, Water Tribe's Hope --- .../mage/cards/k/KataraWaterTribesHope.java | 64 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 2 + 2 files changed, 66 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KataraWaterTribesHope.java diff --git a/Mage.Sets/src/mage/cards/k/KataraWaterTribesHope.java b/Mage.Sets/src/mage/cards/k/KataraWaterTribesHope.java new file mode 100644 index 00000000000..35f78ab4521 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KataraWaterTribesHope.java @@ -0,0 +1,64 @@ +package mage.cards.k; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.MyTurnCondition; +import mage.abilities.costs.common.WaterbendCost; +import mage.abilities.costs.mana.VariableManaCost; +import mage.abilities.dynamicvalue.common.GetXValue; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessAllEffect; +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.constants.SuperType; +import mage.filter.StaticFilters; +import mage.game.permanent.token.AllyToken; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class KataraWaterTribesHope extends CardImpl { + + public KataraWaterTribesHope(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{U}{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(3); + this.toughness = new MageInt(3); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // When Katara enters, create a 1/1 white Ally creature token. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new AllyToken()))); + + // Waterbend {X}: Creatures you control have base power and toughness X/X until end of turn. X can't be 0. Activate only during your turn. + Ability ability = new ActivateIfConditionActivatedAbility(new SetBasePowerToughnessAllEffect( + GetXValue.instance, GetXValue.instance, Duration.EndOfTurn, + StaticFilters.FILTER_CONTROLLED_CREATURES + ), new WaterbendCost("{X}"), MyTurnCondition.instance); + CardUtil.castStream(ability.getCosts(), VariableManaCost.class).forEach(cost -> cost.setMinX(1)); + this.addAbility(ability); + } + + private KataraWaterTribesHope(final KataraWaterTribesHope card) { + super(card); + } + + @Override + public KataraWaterTribesHope copy() { + return new KataraWaterTribesHope(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 162d243d850..32e91942aa6 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -34,6 +34,8 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Fire Nation Attacks", 133, Rarity.UNCOMMON, mage.cards.f.FireNationAttacks.class)); cards.add(new SetCardInfo("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Island", 288, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); + 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)); 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)); From 84a7e9f5b86768f757d77c463ae4593a911417e7 Mon Sep 17 00:00:00 2001 From: Steven Knipe Date: Tue, 12 Aug 2025 23:35:52 -0700 Subject: [PATCH 04/68] Simplify Transform triggers, fix Wildsong Howler --- .../abilities/keywords/TransformTest.java | 26 +++++++++++++++++-- .../TransformIntoSourceTriggeredAbility.java | 7 +---- .../TransformsOrEntersTriggeredAbility.java | 14 +--------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java index ad94dfaed49..04417cc619c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java @@ -1,6 +1,5 @@ package org.mage.test.cards.abilities.keywords; -import mage.cards.s.SpringOfEternalPeace; import mage.constants.CardType; import mage.constants.PhaseStep; import mage.constants.Zone; @@ -384,7 +383,6 @@ public class TransformTest extends CardTestPlayerBase { assertPowerToughness(playerA, "Huntmaster of the Fells", 2, 2); assertTappedCount("Plains", true, 2); assertTappedCount("Wastes", true, 1); - } @Test @@ -413,8 +411,32 @@ public class TransformTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Ravager of the Fells", 0); assertPermanentCount(playerA, "Huntmaster of the Fells", 1); assertPowerToughness(playerA, "Huntmaster of the Fells", 2, 2); + } + @Test + public void testWildsongHowlerTrigger() { + // The only Daybound/Nightbound card with a Transforms trigger on the back side + removeAllCardsFromLibrary(playerA); + addCard(Zone.HAND, playerA, "Howlpack Piper", 2); // Creature {2}{R}{G} + addCard(Zone.LIBRARY, playerA, "Silvercoat Lion", 50); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 4); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Howlpack Piper"); + setChoice(playerA, true); //Transform trigger + addTarget(playerA, "Silvercoat Lion"); + + castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Howlpack Piper"); + setChoice(playerA, true); //ETB trigger + addTarget(playerA, "Silvercoat Lion"); + setStopAt(3, PhaseStep.POSTCOMBAT_MAIN); + setStrictChooseMode(true); + + execute(); + + assertPermanentCount(playerA, "Wildsong Howler", 2); + assertPermanentCount(playerA, "Howlpack Piper", 0); // They should be both transformed + assertHandCount(playerA, "Silvercoat Lion", 3); + assertHandCount(playerA, 3); //The two Silvercoat Lions from triggers and 1 from natural card draw } /** diff --git a/Mage/src/main/java/mage/abilities/common/TransformIntoSourceTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/TransformIntoSourceTriggeredAbility.java index c1908819867..28005a50453 100644 --- a/Mage/src/main/java/mage/abilities/common/TransformIntoSourceTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/TransformIntoSourceTriggeredAbility.java @@ -5,7 +5,6 @@ import mage.abilities.effects.Effect; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; /** * @author TheElk801 @@ -41,10 +40,6 @@ public class TransformIntoSourceTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (!event.getTargetId().equals(this.getSourceId())) { - return false; - } - Permanent permanent = getSourcePermanentIfItStillExists(game); - return permanent != null && permanent.isTransformed(); + return event.getTargetId().equals(this.getSourceId()); } } diff --git a/Mage/src/main/java/mage/abilities/common/TransformsOrEntersTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/TransformsOrEntersTriggeredAbility.java index 43635f5246c..41bb07e832b 100644 --- a/Mage/src/main/java/mage/abilities/common/TransformsOrEntersTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/TransformsOrEntersTriggeredAbility.java @@ -5,13 +5,11 @@ import mage.abilities.effects.Effect; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; /** * @author TheElk801 */ public class TransformsOrEntersTriggeredAbility extends TriggeredAbilityImpl { - public TransformsOrEntersTriggeredAbility(Effect effect, boolean optional) { super(Zone.BATTLEFIELD, effect, optional); setTriggerPhrase("Whenever this creature enters or transforms into {this}, "); @@ -34,16 +32,6 @@ public class TransformsOrEntersTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (!event.getTargetId().equals(this.getSourceId())) { - return false; - } - switch (event.getType()) { - case TRANSFORMED: - Permanent permanent = getSourcePermanentIfItStillExists(game); - return permanent != null && !permanent.isTransformed(); - case ENTERS_THE_BATTLEFIELD: - return true; - } - return false; + return event.getTargetId().equals(this.getSourceId()); } } From 0865b94875df84dc840538bd0f5996ef3e9083d9 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Wed, 13 Aug 2025 12:00:29 -0400 Subject: [PATCH 05/68] [TLA] Implement Avatar Aang / Aang, Master of Elements --- .../mage/cards/a/AangMasterOfElements.java | 112 +++++++++++++ Mage.Sets/src/mage/cards/a/AvatarAang.java | 156 ++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 4 + 3 files changed, 272 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AangMasterOfElements.java create mode 100644 Mage.Sets/src/mage/cards/a/AvatarAang.java diff --git a/Mage.Sets/src/mage/cards/a/AangMasterOfElements.java b/Mage.Sets/src/mage/cards/a/AangMasterOfElements.java new file mode 100644 index 00000000000..951e3c91215 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AangMasterOfElements.java @@ -0,0 +1,112 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.CostImpl; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.common.DamagePlayersEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.counters.CounterType; +import mage.filter.FilterCard; +import mage.game.Game; + +import java.util.Optional; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AangMasterOfElements extends CardImpl { + + private static final FilterCard filter = new FilterCard("spells"); + + public AangMasterOfElements(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.AVATAR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + this.nightCard = true; + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Spells you cast cost {W}{U}{B}{R}{G} less to cast. + this.addAbility(new SimpleStaticAbility(new SpellsCostReductionControllerEffect( + filter, new ManaCostsImpl<>("{W}{U}{B}{R}{G}"), StaticValue.get(1), true + ))); + + // At the beginning of each upkeep, you may transform Aang, Master of Elements. If you do, you gain 4 life, draw four cards, put four +1/+1 counters on him, and he deals 4 damage to each opponent. + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + TargetController.ANY, + new DoIfCostPaid(new GainLifeEffect(4), new AangMasterOfElementsCost()) + .addEffect(new DrawCardSourceControllerEffect(4).concatBy(",")) + .addEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(4)) + .setText(", put four +1/+1 counters on him")) + .addEffect(new DamagePlayersEffect(4, TargetController.OPPONENT) + .setText(", and he deals 4 damage to each opponent")), + false + )); + } + + private AangMasterOfElements(final AangMasterOfElements card) { + super(card); + } + + @Override + public AangMasterOfElements copy() { + return new AangMasterOfElements(this); + } +} + +class AangMasterOfElementsCost extends CostImpl { + + AangMasterOfElementsCost() { + super(); + text = "transform {this}"; + } + + private AangMasterOfElementsCost(final AangMasterOfElementsCost cost) { + super(cost); + } + + @Override + public AangMasterOfElementsCost copy() { + return new AangMasterOfElementsCost(this); + } + + @Override + public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { + return Optional + .ofNullable(source.getSourcePermanentIfItStillExists(game)) + .filter(Card::isTransformable) + .isPresent(); + } + + @Override + public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { + paid = Optional + .ofNullable(source.getSourcePermanentIfItStillExists(game)) + .filter(permanent -> permanent.transform(source, game)) + .isPresent(); + return paid; + } +} diff --git a/Mage.Sets/src/mage/cards/a/AvatarAang.java b/Mage.Sets/src/mage/cards/a/AvatarAang.java new file mode 100644 index 00000000000..24be5ad614e --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AvatarAang.java @@ -0,0 +1,156 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.condition.Condition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.FirebendingAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.watchers.Watcher; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AvatarAang extends CardImpl { + + public AvatarAang(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{G}{W}{U}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.AVATAR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + this.secondSideCardClazz = mage.cards.a.AangMasterOfElements.class; + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Firebending 2 + this.addAbility(new FirebendingAbility(2)); + + // Whenever you waterbend, earthbend, firebend, or airbend, draw a card. Then if you've done all four this turn, transform Avatar Aang. + this.addAbility(new AvatarAangTriggeredAbility()); + } + + private AvatarAang(final AvatarAang card) { + super(card); + } + + @Override + public AvatarAang copy() { + return new AvatarAang(this); + } +} + +class AvatarAangTriggeredAbility extends TriggeredAbilityImpl { + + private enum AvatarAangCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return AvatarAangWatcher.checkPlayer(game, source); + } + } + + AvatarAangTriggeredAbility() { + super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1)); + this.addEffect(new ConditionalOneShotEffect( + new TransformSourceEffect(), AvatarAangCondition.instance, + "Then if you've done all four this turn, transform {this}" + )); + this.setTriggerPhrase("Whenever you waterbend, earthbend, firebend, or airbend, "); + this.addWatcher(new AvatarAangWatcher()); + } + + private AvatarAangTriggeredAbility(final AvatarAangTriggeredAbility ability) { + super(ability); + } + + @Override + public AvatarAangTriggeredAbility copy() { + return new AvatarAangTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + switch (event.getType()) { + case EARTHBENDED: + case AIRBENDED: + case FIREBENDED: + case WATERBENDED: + return true; + default: + return false; + } + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return isControlledBy(event.getPlayerId()); + } +} + +class AvatarAangWatcher extends Watcher { + + private final Set earthSet = new HashSet<>(); + private final Set airSet = new HashSet<>(); + private final Set fireSet = new HashSet<>(); + private final Set waterSet = new HashSet<>(); + + AvatarAangWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + switch (event.getType()) { + case EARTHBENDED: + earthSet.add(event.getPlayerId()); + return; + case AIRBENDED: + airSet.add(event.getPlayerId()); + return; + case FIREBENDED: + fireSet.add(event.getPlayerId()); + return; + case WATERBENDED: + waterSet.add(event.getPlayerId()); + } + } + + @Override + public void reset() { + super.reset(); + earthSet.clear(); + airSet.clear(); + fireSet.clear(); + earthSet.clear(); + } + + private boolean checkPlayer(UUID playerId) { + return earthSet.contains(playerId) + && airSet.contains(playerId) + && fireSet.contains(playerId) + && earthSet.contains(playerId); + } + + static boolean checkPlayer(Game game, Ability source) { + return game.getState().getWatcher(AvatarAangWatcher.class).checkPlayer(source.getControllerId()); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 32e91942aa6..61b0e403c4c 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -27,8 +27,12 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Aang's Iceberg", 336, Rarity.RARE, mage.cards.a.AangsIceberg.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Aang's Iceberg", 5, Rarity.RARE, mage.cards.a.AangsIceberg.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Aang, Master of Elements", 207, Rarity.MYTHIC, mage.cards.a.AangMasterOfElements.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Aang, Master of Elements", 363, Rarity.MYTHIC, mage.cards.a.AangMasterOfElements.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Appa, Steadfast Guardian", 10, Rarity.MYTHIC, mage.cards.a.AppaSteadfastGuardian.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Appa, Steadfast Guardian", 316, Rarity.MYTHIC, mage.cards.a.AppaSteadfastGuardian.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Avatar Aang", 207, Rarity.MYTHIC, mage.cards.a.AvatarAang.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Avatar Aang", 363, Rarity.MYTHIC, mage.cards.a.AvatarAang.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Avatar Enthusiasts", 11, Rarity.COMMON, mage.cards.a.AvatarEnthusiasts.class)); cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); cards.add(new SetCardInfo("Fire Nation Attacks", 133, Rarity.UNCOMMON, mage.cards.f.FireNationAttacks.class)); From 43ac27894656c97825996c3f6b1293d7235430fd Mon Sep 17 00:00:00 2001 From: theelk801 Date: Wed, 13 Aug 2025 11:53:14 -0400 Subject: [PATCH 06/68] [TLA] Implement Fated Firepower --- .../src/mage/cards/f/FatedFirepower.java | 102 ++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 2 + .../main/java/mage/counters/CounterType.java | 1 + 3 files changed, 105 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FatedFirepower.java diff --git a/Mage.Sets/src/mage/cards/f/FatedFirepower.java b/Mage.Sets/src/mage/cards/f/FatedFirepower.java new file mode 100644 index 00000000000..0461c864193 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FatedFirepower.java @@ -0,0 +1,102 @@ +package mage.cards.f; + +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect; +import mage.abilities.keyword.FlashAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.Player; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FatedFirepower extends CardImpl { + + public FatedFirepower(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{X}{R}{R}{R}"); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // This enchantment enters with X fire counters on it. + this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldWithXCountersEffect(CounterType.FIRE.createInstance()))); + + // If a source you control would deal damage to an opponent or a permanent an opponent controls, it deals that much damage plus an amount of damage equal to the number of fire counters on this enchantment instead. + this.addAbility(new SimpleStaticAbility(new FatedFirepowerEffect())); + } + + private FatedFirepower(final FatedFirepower card) { + super(card); + } + + @Override + public FatedFirepower copy() { + return new FatedFirepower(this); + } +} + +class FatedFirepowerEffect extends ReplacementEffectImpl { + + private static final DynamicValue xValue = new CountersSourceCount(CounterType.FIRE); + + FatedFirepowerEffect() { + super(Duration.WhileOnBattlefield, Outcome.Damage); + this.staticText = "if a source you control would deal damage to an opponent or a permanent " + + "an opponent controls, it deals that much damage plus an amount of damage equal to " + + "the number of fire counters on this enchantment instead."; + } + + private FatedFirepowerEffect(final FatedFirepowerEffect effect) { + super(effect); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + event.setAmount(CardUtil.overflowInc(event.getAmount(), xValue.calculate(game, source, this))); + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + switch (event.getType()) { + case DAMAGE_PERMANENT: + case DAMAGE_PLAYER: + return true; + default: + return false; + } + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + return controller != null + && controller.hasOpponent(getControllerOrSelf(event.getTargetId(), game), game) + && source.isControlledBy(game.getControllerId(event.getSourceId())) + && event.getAmount() > 0; + } + + private static UUID getControllerOrSelf(UUID id, Game game) { + UUID outId = game.getControllerId(id); + return outId == null ? id : outId; + } + + @Override + public FatedFirepowerEffect copy() { + return new FatedFirepowerEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 61b0e403c4c..36bd1d71f3e 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -35,6 +35,8 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Avatar Aang", 363, Rarity.MYTHIC, mage.cards.a.AvatarAang.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Avatar Enthusiasts", 11, Rarity.COMMON, mage.cards.a.AvatarEnthusiasts.class)); cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); + cards.add(new SetCardInfo("Fated Firepower", 132, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Fated Firepower", 341, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fire Nation Attacks", 133, Rarity.UNCOMMON, mage.cards.f.FireNationAttacks.class)); cards.add(new SetCardInfo("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Island", 288, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); diff --git a/Mage/src/main/java/mage/counters/CounterType.java b/Mage/src/main/java/mage/counters/CounterType.java index 6cd4529ef60..62104d11a95 100644 --- a/Mage/src/main/java/mage/counters/CounterType.java +++ b/Mage/src/main/java/mage/counters/CounterType.java @@ -87,6 +87,7 @@ public enum CounterType { FETCH("fetch"), FILIBUSTER("filibuster"), FINALITY("finality"), + FIRE("fire"), FIRST_STRIKE("first strike"), FLAME("flame"), FLOOD("flood"), From ef270721a5cfdc2462e38afc81a3cc60375116df Mon Sep 17 00:00:00 2001 From: theelk801 Date: Wed, 13 Aug 2025 12:00:11 -0400 Subject: [PATCH 07/68] [TLA] Implement Fire Lord Zuko --- .../mage/cards/f/FaldornDreadWolfHerald.java | 7 +- Mage.Sets/src/mage/cards/f/FireLordZuko.java | 96 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 2 + 3 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/f/FireLordZuko.java diff --git a/Mage.Sets/src/mage/cards/f/FaldornDreadWolfHerald.java b/Mage.Sets/src/mage/cards/f/FaldornDreadWolfHerald.java index 298ec7eb06d..48eff382aa0 100644 --- a/Mage.Sets/src/mage/cards/f/FaldornDreadWolfHerald.java +++ b/Mage.Sets/src/mage/cards/f/FaldornDreadWolfHerald.java @@ -92,9 +92,10 @@ class FaldornDreadWolfHeraldTriggeredAbility extends TriggeredAbilityImpl { return Optional .ofNullable(game.getSpell(event.getTargetId())) .map(Spell::getFromZone) - .orElse(Zone.ALL) - .equals(Zone.EXILED); + .filter(Zone.EXILED::match) + .isPresent(); + default: + return false; } - return false; } } diff --git a/Mage.Sets/src/mage/cards/f/FireLordZuko.java b/Mage.Sets/src/mage/cards/f/FireLordZuko.java new file mode 100644 index 00000000000..bff43f58139 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FireLordZuko.java @@ -0,0 +1,96 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.dynamicvalue.common.SourcePermanentPowerValue; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.abilities.keyword.FirebendingAbility; +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.game.events.EntersTheBattlefieldEvent; +import mage.game.events.GameEvent; +import mage.game.stack.Spell; + +import java.util.Optional; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FireLordZuko extends CardImpl { + + public FireLordZuko(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{W}{B}"); + + 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(4); + + // Firebending X, where X is Fire Lord Zuko's power. + this.addAbility(new FirebendingAbility(SourcePermanentPowerValue.NOT_NEGATIVE)); + + // Whenever you cast a spell from exile and whenever a permanent you control enters from exile, put a +1/+1 counter on each creature you control. + this.addAbility(new FireLordZukoTriggeredAbility()); + } + + private FireLordZuko(final FireLordZuko card) { + super(card); + } + + @Override + public FireLordZuko copy() { + return new FireLordZuko(this); + } +} + +class FireLordZukoTriggeredAbility extends TriggeredAbilityImpl { + + FireLordZukoTriggeredAbility() { + super(Zone.BATTLEFIELD, new AddCountersAllEffect(CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE)); + setTriggerPhrase("Whenever you cast a spell from exile and whenever a permanent you control enters from exile, "); + } + + private FireLordZukoTriggeredAbility(final FireLordZukoTriggeredAbility ability) { + super(ability); + } + + @Override + public FireLordZukoTriggeredAbility copy() { + return new FireLordZukoTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD + || event.getType() == GameEvent.EventType.SPELL_CAST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (!this.isControlledBy(event.getPlayerId())) { + return false; + } + switch (event.getType()) { + case ENTERS_THE_BATTLEFIELD: + return Zone.EXILED.match(((EntersTheBattlefieldEvent) event).getFromZone()); + case SPELL_CAST: + return Optional + .ofNullable(game.getSpell(event.getTargetId())) + .map(Spell::getFromZone) + .filter(Zone.EXILED::match) + .isPresent(); + default: + return false; + } + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 36bd1d71f3e..27f7e474cd9 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -37,6 +37,8 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); cards.add(new SetCardInfo("Fated Firepower", 132, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fated Firepower", 341, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); + 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("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Island", 288, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); From 05e304e621e033bed72118cddb216dcb805623b6 Mon Sep 17 00:00:00 2001 From: jmlundeen Date: Wed, 13 Aug 2025 16:25:53 -0500 Subject: [PATCH 08/68] [TDM] fix Mistrise Village effect * Add additional tests and fix effect to only work on next spell cast * closes #13891 --- .../src/mage/cards/m/MistriseVillage.java | 36 +++- .../cards/single/tdm/MistriseVillageTest.java | 173 ++++++++++++++++-- 2 files changed, 185 insertions(+), 24 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MistriseVillage.java b/Mage.Sets/src/mage/cards/m/MistriseVillage.java index ea2132cfd54..d5dc9545d45 100644 --- a/Mage.Sets/src/mage/cards/m/MistriseVillage.java +++ b/Mage.Sets/src/mage/cards/m/MistriseVillage.java @@ -1,10 +1,6 @@ package mage.cards.m; -import java.util.UUID; - -import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.common.CantBeCounteredSourceAbility; import mage.abilities.common.EntersBattlefieldTappedUnlessAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.common.YouControlPermanentCondition; @@ -13,7 +9,6 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.AddContinuousEffectToGame; -import mage.abilities.effects.common.continuous.NextSpellCastHasAbilityEffect; import mage.abilities.mana.BlueManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -27,6 +22,10 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.stack.Spell; import mage.game.stack.StackObject; +import mage.watchers.common.SpellsCastWatcher; + +import java.util.List; +import java.util.UUID; /** * @@ -71,6 +70,8 @@ public final class MistriseVillage extends CardImpl { class MistriseCantBeCounteredEffect extends ContinuousRuleModifyingEffectImpl { + private int spellsCastThisTurn; + public MistriseCantBeCounteredEffect() { super(Duration.OneUse, Outcome.Benefit, false, true); staticText = "the next spell you cast this turn can't be countered"; @@ -78,6 +79,7 @@ class MistriseCantBeCounteredEffect extends ContinuousRuleModifyingEffectImpl { protected MistriseCantBeCounteredEffect(final MistriseCantBeCounteredEffect effect) { super(effect); + this.spellsCastThisTurn = effect.spellsCastThisTurn; } @Override @@ -90,6 +92,15 @@ class MistriseCantBeCounteredEffect extends ContinuousRuleModifyingEffectImpl { return event.getType() == GameEvent.EventType.COUNTER; } + @Override + public void init(Ability source, Game game) { + super.init(source, game); + SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class); + if (watcher != null) { + spellsCastThisTurn = watcher.getSpellsCastThisTurn(source.getControllerId()).size(); + } + } + @Override public String getInfoMessage(Ability source, GameEvent event, Game game) { StackObject sourceObject = game.getStack().getStackObject(event.getSourceId()); @@ -103,10 +114,17 @@ class MistriseCantBeCounteredEffect extends ContinuousRuleModifyingEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Spell spell = game.getStack().getSpell(event.getTargetId()); - boolean res = spell != null && spell.isControlledBy(source.getControllerId()); - if (res) { - discard(); + SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class); + if (spell == null || !spell.isControlledBy(source.getControllerId()) || watcher == null) { + return false; } - return res; + List spellsCast = watcher.getSpellsCastThisTurn(source.getControllerId()); + for (int i = 0; i < spellsCast.size(); i++) { + if (i == spellsCastThisTurn && spellsCast.get(i).getId().equals(spell.getId())) { + discard(); + return true; + } + } + return false; } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/tdm/MistriseVillageTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/tdm/MistriseVillageTest.java index 98c2cbee505..db830aa633c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/tdm/MistriseVillageTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/tdm/MistriseVillageTest.java @@ -8,10 +8,41 @@ import org.mage.test.serverside.base.CardTestPlayerBase; public class MistriseVillageTest extends CardTestPlayerBase { + /* + Mistrise Village + Land + This land enters tapped unless you control a Mountain or a Forest. + {T}: Add {U}. + {U}, {T}: The next spell you cast this turn can’t be countered. + */ private static final String MISTRISE = "Mistrise Village"; - private static final String COUNTER = "Counterspell"; - private static final String CUB = "Bear Cub"; - private static final String BEARS = "Balduvian Bears"; + private static final String COUNTERSPELL = "Counterspell"; + private static final String BEAR_CUB = "Bear Cub"; + private static final String BALDUVIAN_BEARS = "Balduvian Bears"; + /* + Force of Negation + {1}{U}{U} + Instant + If it’s not your turn, you may exile a blue card from your hand rather than pay this spell’s mana cost. + Counter target noncreature spell. If that spell is countered this way, exile it instead of putting it into its owner’s graveyard. + */ + public static final String FORCE_OF_NEGATION = "Force of Negation"; + /* + Narset, Parter of Veils + {1}{U}{U} + Legendary Planeswalker — Narset + Each opponent can’t draw more than one card each turn. + −2: Look at the top four cards of your library. You may reveal a noncreature, nonland card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. + */ + public static final String NARSET_PARTER_OF_VEILS = "Narset, Parter of Veils"; + /* + Aether Spellbomb + {1} + Artifact + {U}, Sacrifice this artifact: Return target creature to its owner’s hand. + {1}, Sacrifice this artifact: Draw a card. + */ + public static final String AETHER_SPELLBOMB = "Aether Spellbomb"; @Test public void testCounter() { @@ -21,22 +52,134 @@ public class MistriseVillageTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Island"); addCard(Zone.BATTLEFIELD, playerA, "Forest", 4); addCard(Zone.BATTLEFIELD, playerB, "Island", 4); - addCard(Zone.HAND, playerB, COUNTER, 2); - addCard(Zone.HAND, playerA, CUB); - addCard(Zone.HAND, playerA, BEARS); + addCard(Zone.HAND, playerB, COUNTERSPELL, 2); + addCard(Zone.HAND, playerA, BEAR_CUB); + addCard(Zone.HAND, playerA, BALDUVIAN_BEARS); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}, {T}"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}, {T}"); // Activate mistrise waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, CUB, true); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, COUNTER, CUB, CUB); - castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, BEARS, true); - castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, COUNTER, BEARS, BEARS); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, BEAR_CUB, true); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, COUNTERSPELL, BEAR_CUB, BEAR_CUB); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, BALDUVIAN_BEARS, true); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, COUNTERSPELL, BALDUVIAN_BEARS, BALDUVIAN_BEARS); setStopAt(1, PhaseStep.END_TURN); execute(); - assertPermanentCount(playerA, CUB, 1); - assertGraveyardCount(playerA, BEARS, 1); - assertGraveyardCount(playerB, COUNTER, 2); + assertPermanentCount(playerA, BEAR_CUB, 1); + assertGraveyardCount(playerA, BALDUVIAN_BEARS, 1); + assertGraveyardCount(playerB, COUNTERSPELL, 2); } -} \ No newline at end of file + + @Test + public void testCastCounterAfterCastingSpell() { + setStrictChooseMode(true); + skipInitShuffling(); + + addCard(Zone.BATTLEFIELD, playerA, MISTRISE); + addCard(Zone.BATTLEFIELD, playerA, "Island", 8); + addCard(Zone.HAND, playerA, NARSET_PARTER_OF_VEILS); + addCard(Zone.HAND, playerA, AETHER_SPELLBOMB); + addCard(Zone.BATTLEFIELD, playerB, "Island", 3); + addCard(Zone.HAND, playerB, FORCE_OF_NEGATION); + addCard(Zone.LIBRARY, playerA, "Stock Up"); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}, {T}"); // Activate mistrise + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, NARSET_PARTER_OF_VEILS); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-2: "); // Narset ability + setChoice(playerA, true); + addTarget(playerA, "Stock Up"); + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Stock Up"); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, FORCE_OF_NEGATION, "Stock Up"); + + waitStackResolved(1, PhaseStep.POSTCOMBAT_MAIN, playerA); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, AETHER_SPELLBOMB); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, NARSET_PARTER_OF_VEILS, 1); + assertPermanentCount(playerA, AETHER_SPELLBOMB, 1); + assertGraveyardCount(playerB, FORCE_OF_NEGATION, 1); + assertExileCount(playerA, "Stock Up", 1); + } + + @Test + public void testMultipleMistrise() { + setStrictChooseMode(true); + skipInitShuffling(); + + addCard(Zone.BATTLEFIELD, playerA, MISTRISE,2); + addCard(Zone.BATTLEFIELD, playerA, "Island", 8); + addCard(Zone.HAND, playerA, NARSET_PARTER_OF_VEILS); + addCard(Zone.BATTLEFIELD, playerB, "Island", 6); + addCard(Zone.HAND, playerB, FORCE_OF_NEGATION, 2); + addCard(Zone.LIBRARY, playerA, AETHER_SPELLBOMB); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}, {T}"); // Activate mistrise + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}, {T}"); // Activate mistrise + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 2); + + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, NARSET_PARTER_OF_VEILS); + checkPlayableAbility("cast force", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Cast Force", true); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, FORCE_OF_NEGATION, NARSET_PARTER_OF_VEILS); // Fail to counter + setChoice(playerB, "Cast with no alternative cost"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-2: "); // Narset ability + setChoice(playerA, true); + addTarget(playerA, AETHER_SPELLBOMB); + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, AETHER_SPELLBOMB); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, FORCE_OF_NEGATION, AETHER_SPELLBOMB); // Successful counter + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, NARSET_PARTER_OF_VEILS, 1); + assertGraveyardCount(playerB, FORCE_OF_NEGATION, 2); + assertExileCount(playerA, AETHER_SPELLBOMB, 1); + } + + @Test + public void testMultipleMistriseNotConsecutive() { + setStrictChooseMode(true); + skipInitShuffling(); + + addCard(Zone.BATTLEFIELD, playerA, MISTRISE,2); + addCard(Zone.BATTLEFIELD, playerA, "Island", 8); + addCard(Zone.HAND, playerA, NARSET_PARTER_OF_VEILS); + addCard(Zone.BATTLEFIELD, playerB, "Island", 6); + addCard(Zone.HAND, playerB, FORCE_OF_NEGATION, 2); + addCard(Zone.LIBRARY, playerA, AETHER_SPELLBOMB); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}, {T}"); // Activate mistrise + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1); + + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, NARSET_PARTER_OF_VEILS); + checkPlayableAbility("cast force", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Cast Force", true); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, FORCE_OF_NEGATION, NARSET_PARTER_OF_VEILS); // Fail to counter + setChoice(playerB, "Cast with no alternative cost"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-2: "); // Narset ability + setChoice(playerA, true); + addTarget(playerA, AETHER_SPELLBOMB); + + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{U}, {T}"); // Activate mistrise + waitStackResolved(1, PhaseStep.POSTCOMBAT_MAIN, 1); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, AETHER_SPELLBOMB); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, FORCE_OF_NEGATION, AETHER_SPELLBOMB); // Successful counter + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, NARSET_PARTER_OF_VEILS, 1); + assertGraveyardCount(playerB, FORCE_OF_NEGATION, 2); + assertPermanentCount(playerA, AETHER_SPELLBOMB, 1); + } +} From b8504d56f2ef2ecd5112a3f348d8848081e038f1 Mon Sep 17 00:00:00 2001 From: jmlundeen Date: Thu, 14 Aug 2025 11:44:19 -0500 Subject: [PATCH 09/68] fix CantBeCounteredSourceEffect info message saying spell can't be countered by itself --- .../abilities/effects/common/CantBeCounteredSourceEffect.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/CantBeCounteredSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CantBeCounteredSourceEffect.java index 4d9f3514c6f..dde43e653e3 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CantBeCounteredSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CantBeCounteredSourceEffect.java @@ -9,7 +9,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.game.stack.Spell; import mage.game.stack.StackObject; @@ -34,7 +33,7 @@ public class CantBeCounteredSourceEffect extends ContinuousRuleModifyingEffectIm @Override public String getInfoMessage(Ability source, GameEvent event, Game game) { - StackObject stackObject = game.getStack().getStackObject(event.getTargetId()); + StackObject stackObject = game.getStack().getStackObject(event.getSourceId()); MageObject sourceObject = game.getObject(source); if (stackObject != null && sourceObject != null) { return sourceObject.getLogName() + " can't be countered by " + stackObject.getName(); From ec2c7e6ad666f3894c38dfb63e6372e65a0ddf27 Mon Sep 17 00:00:00 2001 From: jmlundeen Date: Thu, 14 Aug 2025 13:03:44 -0500 Subject: [PATCH 10/68] [TDM] change Mistrise Village effect duration to end of turn and add discard logic * effect now has end of turn duration and is discarded after resolving the next spell --- .../src/mage/cards/m/MistriseVillage.java | 56 ++++++++----------- .../cards/single/tdm/MistriseVillageTest.java | 36 +++++++++++- 2 files changed, 58 insertions(+), 34 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MistriseVillage.java b/Mage.Sets/src/mage/cards/m/MistriseVillage.java index d5dc9545d45..3095a898891 100644 --- a/Mage.Sets/src/mage/cards/m/MistriseVillage.java +++ b/Mage.Sets/src/mage/cards/m/MistriseVillage.java @@ -1,25 +1,22 @@ package mage.cards.m; import mage.abilities.Ability; +import mage.abilities.common.CantBeCounteredSourceAbility; import mage.abilities.common.EntersBattlefieldTappedUnlessAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.common.YouControlPermanentCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.AddContinuousEffectToGame; import mage.abilities.mana.BlueManaAbility; 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.constants.*; import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.Predicates; import mage.game.Game; -import mage.game.events.GameEvent; import mage.game.stack.Spell; import mage.game.stack.StackObject; import mage.watchers.common.SpellsCastWatcher; @@ -43,7 +40,7 @@ public final class MistriseVillage extends CardImpl { public MistriseVillage(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - + // This land enters tapped unless you control a Mountain or a Forest. this.addAbility(new EntersBattlefieldTappedUnlessAbility(condition).addHint(condition.getHint())); @@ -68,12 +65,12 @@ public final class MistriseVillage extends CardImpl { } } -class MistriseCantBeCounteredEffect extends ContinuousRuleModifyingEffectImpl { +class MistriseCantBeCounteredEffect extends ContinuousEffectImpl { private int spellsCastThisTurn; public MistriseCantBeCounteredEffect() { - super(Duration.OneUse, Outcome.Benefit, false, true); + super(Duration.EndOfTurn, Layer.RulesEffects, SubLayer.NA, Outcome.Benefit); staticText = "the next spell you cast this turn can't be countered"; } @@ -87,11 +84,6 @@ class MistriseCantBeCounteredEffect extends ContinuousRuleModifyingEffectImpl { return new MistriseCantBeCounteredEffect(this); } - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.COUNTER; - } - @Override public void init(Ability source, Game game) { super.init(source, game); @@ -102,27 +94,27 @@ class MistriseCantBeCounteredEffect extends ContinuousRuleModifyingEffectImpl { } @Override - public String getInfoMessage(Ability source, GameEvent event, Game game) { - StackObject sourceObject = game.getStack().getStackObject(event.getSourceId()); - StackObject targetObject = game.getStack().getStackObject(event.getTargetId()); - if (sourceObject != null && targetObject != null) { - return targetObject.getName() + " cannot be countered by " + sourceObject.getName(); - } - return staticText; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - Spell spell = game.getStack().getSpell(event.getTargetId()); + public boolean apply(Game game, Ability source) { SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class); - if (spell == null || !spell.isControlledBy(source.getControllerId()) || watcher == null) { + if (watcher == null) { return false; } - List spellsCast = watcher.getSpellsCastThisTurn(source.getControllerId()); - for (int i = 0; i < spellsCast.size(); i++) { - if (i == spellsCastThisTurn && spellsCast.get(i).getId().equals(spell.getId())) { - discard(); - return true; + if (game.getStack().isEmpty() && watcher.getSpellsCastThisTurn(source.getControllerId()).size() >= spellsCastThisTurn + 1) { + discard(); + return false; + } + for (StackObject stackObject : game.getStack()) { + if (!(stackObject instanceof Spell) || !stackObject.isControlledBy(source.getControllerId())) { + continue; + } + Spell spell = (Spell) stackObject; + + List spellsCast = watcher.getSpellsCastThisTurn(source.getControllerId()); + for (int i = 0; i < spellsCast.size(); i++) { + if (i == spellsCastThisTurn && spellsCast.get(i).getId().equals(spell.getId())) { + game.getState().addOtherAbility(spell.getCard(), new CantBeCounteredSourceAbility()); + return true; + } } } return false; diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/tdm/MistriseVillageTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/tdm/MistriseVillageTest.java index db830aa633c..a636b0be12e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/tdm/MistriseVillageTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/tdm/MistriseVillageTest.java @@ -137,7 +137,7 @@ public class MistriseVillageTest extends CardTestPlayerBase { castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, AETHER_SPELLBOMB); castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, FORCE_OF_NEGATION, AETHER_SPELLBOMB); // Successful counter - setStopAt(1, PhaseStep.END_TURN); + setStopAt(2, PhaseStep.END_TURN); execute(); assertPermanentCount(playerA, NARSET_PARTER_OF_VEILS, 1); @@ -162,7 +162,6 @@ public class MistriseVillageTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, NARSET_PARTER_OF_VEILS); - checkPlayableAbility("cast force", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Cast Force", true); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, FORCE_OF_NEGATION, NARSET_PARTER_OF_VEILS); // Fail to counter setChoice(playerB, "Cast with no alternative cost"); waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA); @@ -182,4 +181,37 @@ public class MistriseVillageTest extends CardTestPlayerBase { assertGraveyardCount(playerB, FORCE_OF_NEGATION, 2); assertPermanentCount(playerA, AETHER_SPELLBOMB, 1); } + + @Test + public void testCastingMultipleSpells() { + setStrictChooseMode(true); + skipInitShuffling(); + + addCard(Zone.BATTLEFIELD, playerA, MISTRISE,2); + addCard(Zone.BATTLEFIELD, playerA, "Island", 13); + addCard(Zone.HAND, playerA, NARSET_PARTER_OF_VEILS); + addCard(Zone.HAND, playerA, "Hieroglyphic Illumination"); + addCard(Zone.BATTLEFIELD, playerB, "Island", 6); + addCard(Zone.HAND, playerB, FORCE_OF_NEGATION, 2); + addCard(Zone.LIBRARY, playerA, AETHER_SPELLBOMB); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}, {T}"); // Activate mistrise + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 2); + + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, NARSET_PARTER_OF_VEILS); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Hieroglyphic Illumination"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, FORCE_OF_NEGATION, NARSET_PARTER_OF_VEILS); // Fail to counter + setChoice(playerB, "Cast with no alternative cost"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA); + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, AETHER_SPELLBOMB); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, FORCE_OF_NEGATION, AETHER_SPELLBOMB); // Successful counter + setStopAt(2, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, NARSET_PARTER_OF_VEILS, 1); + assertGraveyardCount(playerB, FORCE_OF_NEGATION, 2); + assertExileCount(playerA, AETHER_SPELLBOMB, 1); + } } From dd83ccb09541404ffe390e65a801369597e89a9a Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:04:00 -0400 Subject: [PATCH 11/68] [TLA] update spoiler --- Utils/mtg-cards-data.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index fc2b028b622..097ef0ce318 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -59719,26 +59719,42 @@ Twilight Mire|Edge of Eternities Commander|189|R||Land|||{T}: Add {C}.${B/G}, {T Viridescent Bog|Edge of Eternities Commander|190|R||Land|||{1}, {T}: Add {B}{G}.| Wastes|Edge of Eternities Commander|191|C||Basic Land|||{T}: Add {C}.| Aang's Journey|Avatar: The Last Airbender|1|C|{2}|Sorcery - Lesson|||Kicker {2}$Search your library for a basic land card. If this spell was kicked, instead search your library for a basic land card and a Shrine card. Reveal those cards, put them into your hand, then shuffle.$You gain 2 life.| +Aang, the Last Airbender|Avatar: The Last Airbender|4|U|{3}{W}|Legendary Creature - Human Avatar Ally|3|2|Flying$When Aang enters, airbend up to one other target nonland permanent.$Whenever you cast a Lesson spell, Aang gains lifelink until end of turn.| Aang's Iceberg|Avatar: The Last Airbender|5|R|{2}{W}|Enchantment|||Flash$When this enchantment enters, exile up to one other target nonland permanent until this enchantment leaves the battlefield.$Waterbend {3}: Sacrifice this enchantment. If you do, scry 2.| +Airbending Lesson|Avatar: The Last Airbender|8|C|{2}{W}|Instant - Lesson|||Airbend target nonland permanent.$Draw a card.| Appa, Steadfast Guardian|Avatar: The Last Airbender|10|M|{2}{W}{W}|Legendary Creature - Bison Ally|3|4|Flash$Flying$When Appa enters, airbend any number of other target nonland permanents you control.$Whenever you cast a spell from exile, create a 1/1 white Ally creature token.| Avatar Enthusiasts|Avatar: The Last Airbender|11|C|{2}{W}|Creature - Human Peasant Ally|2|2|Whenever another Ally you control enters, put a +1/+1 counter on this creature.| Momo, Friendly Flier|Avatar: The Last Airbender|29|R|{W}|Legendary Creature - Lemur Bat Ally|1|1|Flying$The first non-Lemur creature spell with flying you cast during each of your turns costs {1} less to cast.$Whenever another creature you control with flying enters, Momo gets +1/+1 until end of turn.| Southern Air Temple|Avatar: The Last Airbender|36|U|{3}{W}|Legendary Enchantment - Shrine|||When Southern Air Temple enters, put X +1/+1 counters on each creature you control, where X is the number of Shrines you control.$Whenever another Shrine you control enters, put a +1/+1 counter on each creature you control.| Sokka's Haiku|Avatar: The Last Airbender|71|U|{3}{U}{U}|Instant - Lesson|||Counter target spell.$Draw a card, then mill three cards.$Untap target land.| Yue, the Moon Spirit|Avatar: The Last Airbender|83|R|{3}{U}|Legendary Creature - Spirit Ally|3|3|Flying, vigilance$Waterbend {5}, {T}: You may cast a noncreature spell from your hand without paying its mana cost.| +Azula Always Lies|Avatar: The Last Airbender|84|C|{1}{B}|Instant - Lesson|||Choose one or both --$* Target creature gets -1/-1 until end of turn.$* Put a +1/+1 counter on target creature.| +Beetle-Headed Merchants|Avatar: The Last Airbender|86|C|{4}{B}|Creature - Human Citizen|5|4|Whenever this creature attacks, you may sacrifice another creature or artifact. If you do, draw a card and put a +1/+1 counter on this creature.| +Buzzard-Wasp Colony|Avatar: The Last Airbender|88|U|{3}{B}|Creature - Bird Insect|2|2|Flying$When this creature enters, you may sacrifice an artifact or creature. If you do, draw a card.$Whenever another creature you control dies, if it had counters on it, put its counters on this creature.| +Cat-Gator|Avatar: The Last Airbender|91|U|{6}{B}|Creature - Fish Crocodile|3|2|Lifelink$When this creature enters, it deals damage equal to the number of Swamps you control to any target.| +Dai Li Indoctrination|Avatar: The Last Airbender|93|C|{1}{B}|Sorcery - Lesson|||Choose one --$* Target opponent reveals their hand. You choose a nonland permanent card from it. That player discards that card.$* Earthbend 2.| The Rise of Sozin|Avatar: The Last Airbender|117|M|{4}{B}{B}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter.)$I -- Destroy all creatures.$II -- Choose a card name. Search target opponent's graveyard, hand, and library for up to four cards with that name and exile them. Then that player shuffles.$III -- Exile this Saga, then return it to the battlefield transformed under your control.| Fire Lord Sozin|Avatar: The Last Airbender|117|M||Legendary Creature - Human Noble|5|5|Menace, firebending 3$Whenever Fire Lord Sozin deals combat damage to a player, you may pay {X}. When you do, put any number of target creature cards with total mana value X or less from that player's graveyard onto the battlefield under your control.| +Deserter's Disciple|Avatar: The Last Airbender|131|C|{1}{R}|Creature - Human Rebel Ally|2|2|{T}: Another target creature you control with power 2 or less can't be blocked this turn.| Fated Firepower|Avatar: The Last Airbender|132|M|{X}{R}{R}{R}|Enchantment|||Flash$This enchantment enters with X fire counters on it.$If a source you control would deal damage to an opponent or a permanent an opponent controls, it deals that much damage plus an amount of damage equal to the number of fire counters on this enchantment instead.| Fire Nation Attacks|Avatar: The Last Airbender|133|U|{4}{R}|Instant|||Create two 2/2 red Soldier creature tokens with firebending 1.$Flashback {8}{R}| Redirect Lightning|Avatar: The Last Airbender|151|R|{R}|Instant - Lesson|||As an additional cost to cast this spell, pay 5 life or pay {2}.$Change the target of target spell or ability with a single target.| +Badgermole|Avatar: The Last Airbender|166|C|{4}{G}|Creature - Badger Mole|4|4|When this creature enters, earthbend 2.$Creatures you control with +1/+1 counters on them have trample.| +Earth Rumble|Avatar: The Last Airbender|174|U|{3}{G}|Sorcery|||Earthbend 2. When you do, up to one target creature you control fights target creature an opponent controls.| Earthbending Lesson|Avatar: The Last Airbender|176|C|{3}{G}|Sorcery - Lesson|||Earthbend 4.| +Abandon Attachments|Avatar: The Last Airbender|205|C|{1}{U/R}|Instant - Lesson|||You may discard a card. If you do, draw two cards.| Avatar Aang|Avatar: The Last Airbender|207|M|{R}{G}{W}{U}|Legendary Creature - Human Avatar Ally|4|4|Flying, firebending 2$Whenever you waterbend, earthbend, firebend, or airbend, draw a card. Then if you've done all four this turn, transform Avatar Aang.| Aang, Master of Elements|Avatar: The Last Airbender|207|M||Legendary Creature - Avatar Ally|6|6|Flying$Spells you cast cost {W}{U}{B}{R}{G} less to cast.$At the beginning of each upkeep, you may transform Aang, Master of Elements. If you do, you gain 4 life, draw four cards, put four +1/+1 counters on him, and he deals 4 damage to each opponent.| +Cat-Owl|Avatar: The Last Airbender|212|C|{3}{W/U}|Creature - Cat Bird|3|3|Flying$Whenever this creature attacks, untap target artifact or creature.| +Earth Kingdom Soldier|Avatar: The Last Airbender|216|C|{4}{G/W}|Creature - Human Soldier|3|4|Vigilance$When this creature enters, put a +1/+1 counter on each of up to two target creatures you control.| +Earth Village Ruffians|Avatar: The Last Airbender|219|C|{2}{B/G}|Creature - Human Soldier Rogue|3|1|When this creature dies, earthbend 2.| Fire Lord Zuko|Avatar: The Last Airbender|221|R|{R}{W}{B}|Legendary Creature - Human Noble Ally|2|4|Firebending X, where X is Fire Lord Zuko's power.$Whenever you cast a spell from exile and whenever a permanent you control enters from exile, put a +1/+1 counter on each creature you control.| Katara, the Fearless|Avatar: The Last Airbender|230|R|{G}{W}{U}|Legendary Creature - Human Warrior Ally|3|3|If a triggered ability of an Ally you control triggers, that ability triggers an additional time.| Katara, Water Tribe's Hope|Avatar: The Last Airbender|231|R|{2}{W}{U}{U}|Legendary Creature - Human Warrior Ally|3|3|Vigilance$When Katara enters, create a 1/1 white Ally creature token.$Waterbend {X}: Creatures you control have base power and toughness X/X until end of turn. X can't be 0. Activate only during your turn.| Sokka, Bold Boomeranger|Avatar: The Last Airbender|240|R|{U}{R}|Legendary Creature - Human Warrior Ally|1|1|When Sokka enters, discard up to two cards, then draw that many cards.$Whenever you cast an artifact or Lesson spell, put a +1/+1 counter on Sokka.| Toph, the First Metalbender|Avatar: The Last Airbender|247|R|{1}{R}{G}{W}|Legendary Creature - Human Warrior Ally|3|3|Nontoken artifacts you control are lands in addition to their other types.$At the beginning of your end step, earthbend 2.| +Barrels of Blasting Jelly|Avatar: The Last Airbender|254|C|{1}|Artifact|||{1}: Add one mana of any color. Activate only once each turn.${5}, {T}, Sacrifice this artifact: It deals 5 damage to target creature.| +Bender's Waterskin|Avatar: The Last Airbender|255|C|{3}|Artifact|||Untap this artifact during each other player's untap step.${T}: Add one mana of any color.| Plains|Avatar: The Last Airbender|287|C||Basic Land - Plains|||({T}: Add {W}.)| Island|Avatar: The Last Airbender|288|C||Basic Land - Island|||({T}: Add {U}.)| Swamp|Avatar: The Last Airbender|289|C||Basic Land - Swamp|||({T}: Add {B}.)| From 065a271f5744dac9bc1fb8fec4c1eafa62b6c4a7 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:06:40 -0400 Subject: [PATCH 12/68] [TLA] Implement Aang, the Last Airbender --- .../mage/cards/a/AangTheLastAirbender.java | 70 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 71 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AangTheLastAirbender.java diff --git a/Mage.Sets/src/mage/cards/a/AangTheLastAirbender.java b/Mage.Sets/src/mage/cards/a/AangTheLastAirbender.java new file mode 100644 index 00000000000..8bfcd1d7928 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AangTheLastAirbender.java @@ -0,0 +1,70 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.effects.keyword.AirbendTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.LifelinkAbility; +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.FilterPermanent; +import mage.filter.FilterSpell; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AangTheLastAirbender extends CardImpl { + + private static final FilterPermanent filter = new FilterNonlandPermanent("other target nonland permanent"); + private static final FilterSpell filter2 = new FilterSpell("a Lesson spell"); + + static { + filter.add(AnotherPredicate.instance); + filter2.add(SubType.LESSON.getPredicate()); + } + + public AangTheLastAirbender(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.AVATAR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Aang enters, airbend up to one other target nonland permanent. + Ability ability = new EntersBattlefieldTriggeredAbility(new AirbendTargetEffect()); + ability.addTarget(new TargetPermanent(0, 1, filter)); + this.addAbility(ability); + + // Whenever you cast a Lesson spell, Aang gains lifelink until end of turn. + this.addAbility(new SpellCastControllerTriggeredAbility( + new GainAbilitySourceEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn), filter2, false + )); + } + + private AangTheLastAirbender(final AangTheLastAirbender card) { + super(card); + } + + @Override + public AangTheLastAirbender copy() { + return new AangTheLastAirbender(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 27f7e474cd9..55d60fbcd44 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -29,6 +29,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Aang's Iceberg", 5, Rarity.RARE, mage.cards.a.AangsIceberg.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Aang, Master of Elements", 207, Rarity.MYTHIC, mage.cards.a.AangMasterOfElements.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Aang, Master of Elements", 363, Rarity.MYTHIC, mage.cards.a.AangMasterOfElements.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Aang, the Last Airbender", 4, Rarity.UNCOMMON, mage.cards.a.AangTheLastAirbender.class)); cards.add(new SetCardInfo("Appa, Steadfast Guardian", 10, Rarity.MYTHIC, mage.cards.a.AppaSteadfastGuardian.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Appa, Steadfast Guardian", 316, Rarity.MYTHIC, mage.cards.a.AppaSteadfastGuardian.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Avatar Aang", 207, Rarity.MYTHIC, mage.cards.a.AvatarAang.class, NON_FULL_USE_VARIOUS)); From 88dae5ff4b9cb136f097cf19e936d1a6c9a13bea Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:07:22 -0400 Subject: [PATCH 13/68] [TLA] Implement Abandon Attachments --- .../src/mage/cards/a/AbandonAttachments.java | 35 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 36 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AbandonAttachments.java diff --git a/Mage.Sets/src/mage/cards/a/AbandonAttachments.java b/Mage.Sets/src/mage/cards/a/AbandonAttachments.java new file mode 100644 index 00000000000..d3a447913d0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AbandonAttachments.java @@ -0,0 +1,35 @@ +package mage.cards.a; + +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +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 AbandonAttachments extends CardImpl { + + public AbandonAttachments(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U/R}"); + + this.subtype.add(SubType.LESSON); + + // You may discard a card. If you do, draw two cards. + this.getSpellAbility().addEffect(new DoIfCostPaid(new DrawCardSourceControllerEffect(2), new DiscardCardCost())); + } + + private AbandonAttachments(final AbandonAttachments card) { + super(card); + } + + @Override + public AbandonAttachments copy() { + return new AbandonAttachments(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 55d60fbcd44..7bc875ed171 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -30,6 +30,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Aang, Master of Elements", 207, Rarity.MYTHIC, mage.cards.a.AangMasterOfElements.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Aang, Master of Elements", 363, Rarity.MYTHIC, mage.cards.a.AangMasterOfElements.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Aang, the Last Airbender", 4, Rarity.UNCOMMON, mage.cards.a.AangTheLastAirbender.class)); + cards.add(new SetCardInfo("Abandon Attachments", 205, Rarity.COMMON, mage.cards.a.AbandonAttachments.class)); cards.add(new SetCardInfo("Appa, Steadfast Guardian", 10, Rarity.MYTHIC, mage.cards.a.AppaSteadfastGuardian.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Appa, Steadfast Guardian", 316, Rarity.MYTHIC, mage.cards.a.AppaSteadfastGuardian.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Avatar Aang", 207, Rarity.MYTHIC, mage.cards.a.AvatarAang.class, NON_FULL_USE_VARIOUS)); From 355e8c15bc21de2179e1e9343ebdcb9a1609a126 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:07:42 -0400 Subject: [PATCH 14/68] remove temporary verify skip --- Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 67dba8ac8c8..f7b6493ce98 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -1018,9 +1018,6 @@ public class VerifyCardDataTest { // CHECK: unknown set or wrong name for (ExpansionSet set : sets) { - if ("TLE".equals(set.getCode())) { // temporary - continue; - } if (set.getSetType().equals(SetType.CUSTOM_SET)) { // skip unofficial sets like Star Wars continue; @@ -2081,7 +2078,6 @@ public class VerifyCardDataTest { } } } - private void checkSubtypes(Card card, MtgJsonCard ref) { if (skipListHaveName(SKIP_LIST_SUBTYPE, card.getExpansionSetCode(), card.getName())) { return; From 32a1ff367d0a10e46d627aeb3bee34e51ecb68af Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:08:34 -0400 Subject: [PATCH 15/68] [TLA] Implement Airbending Lesson --- .../src/mage/cards/a/AirbendingLesson.java | 39 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 40 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AirbendingLesson.java diff --git a/Mage.Sets/src/mage/cards/a/AirbendingLesson.java b/Mage.Sets/src/mage/cards/a/AirbendingLesson.java new file mode 100644 index 00000000000..d86ccfd133e --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AirbendingLesson.java @@ -0,0 +1,39 @@ +package mage.cards.a; + +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.keyword.AirbendTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.common.TargetNonlandPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AirbendingLesson extends CardImpl { + + public AirbendingLesson(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}"); + + this.subtype.add(SubType.LESSON); + + // Airbend target nonland permanent. + this.getSpellAbility().addEffect(new AirbendTargetEffect()); + this.getSpellAbility().addTarget(new TargetNonlandPermanent()); + + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("
")); + } + + private AirbendingLesson(final AirbendingLesson card) { + super(card); + } + + @Override + public AirbendingLesson copy() { + return new AirbendingLesson(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 7bc875ed171..3fba5bc02ba 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -31,6 +31,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Aang, Master of Elements", 363, Rarity.MYTHIC, mage.cards.a.AangMasterOfElements.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Aang, the Last Airbender", 4, Rarity.UNCOMMON, mage.cards.a.AangTheLastAirbender.class)); cards.add(new SetCardInfo("Abandon Attachments", 205, Rarity.COMMON, mage.cards.a.AbandonAttachments.class)); + cards.add(new SetCardInfo("Airbending Lesson", 8, Rarity.COMMON, mage.cards.a.AirbendingLesson.class)); cards.add(new SetCardInfo("Appa, Steadfast Guardian", 10, Rarity.MYTHIC, mage.cards.a.AppaSteadfastGuardian.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Appa, Steadfast Guardian", 316, Rarity.MYTHIC, mage.cards.a.AppaSteadfastGuardian.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Avatar Aang", 207, Rarity.MYTHIC, mage.cards.a.AvatarAang.class, NON_FULL_USE_VARIOUS)); From a5068798a261fcafee227ec95d495657c1aaaf4d Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:09:54 -0400 Subject: [PATCH 16/68] [TLA] Implement Azula Always Lies --- .../src/mage/cards/a/AzulaAlwaysLies.java | 46 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AzulaAlwaysLies.java diff --git a/Mage.Sets/src/mage/cards/a/AzulaAlwaysLies.java b/Mage.Sets/src/mage/cards/a/AzulaAlwaysLies.java new file mode 100644 index 00000000000..f8d7dbe6f40 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AzulaAlwaysLies.java @@ -0,0 +1,46 @@ +package mage.cards.a; + +import mage.abilities.Mode; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +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 AzulaAlwaysLies extends CardImpl { + + public AzulaAlwaysLies(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}"); + + this.subtype.add(SubType.LESSON); + + // Choose one or both -- + this.getSpellAbility().getModes().setMinModes(1); + this.getSpellAbility().getModes().setMaxModes(2); + + // * Target creature gets -1/-1 until end of turn. + this.getSpellAbility().addEffect(new BoostTargetEffect(-1, -1)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + // * Put a +1/+1 counter on target creature. + this.getSpellAbility().addMode(new Mode(new AddCountersTargetEffect(CounterType.P1P1.createInstance())) + .addTarget(new TargetCreaturePermanent())); + } + + private AzulaAlwaysLies(final AzulaAlwaysLies card) { + super(card); + } + + @Override + public AzulaAlwaysLies copy() { + return new AzulaAlwaysLies(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 3fba5bc02ba..90ddfae8760 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -37,6 +37,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Avatar Aang", 207, Rarity.MYTHIC, mage.cards.a.AvatarAang.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Avatar Aang", 363, Rarity.MYTHIC, mage.cards.a.AvatarAang.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Avatar Enthusiasts", 11, Rarity.COMMON, mage.cards.a.AvatarEnthusiasts.class)); + cards.add(new SetCardInfo("Azula Always Lies", 84, Rarity.COMMON, mage.cards.a.AzulaAlwaysLies.class)); cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); cards.add(new SetCardInfo("Fated Firepower", 132, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fated Firepower", 341, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); From 038c8f05ef4d8c6fef0aab6e0f589f49a43d4f29 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:12:12 -0400 Subject: [PATCH 17/68] [TLA] Implement Badgermole --- Mage.Sets/src/mage/cards/b/Badgermole.java | 53 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + .../main/java/mage/filter/StaticFilters.java | 7 +++ 3 files changed, 61 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/Badgermole.java diff --git a/Mage.Sets/src/mage/cards/b/Badgermole.java b/Mage.Sets/src/mage/cards/b/Badgermole.java new file mode 100644 index 00000000000..0c6326da4e9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/Badgermole.java @@ -0,0 +1,53 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; +import mage.abilities.effects.keyword.EarthbendTargetEffect; +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.filter.StaticFilters; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Badgermole extends CardImpl { + + public Badgermole(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}"); + + this.subtype.add(SubType.BADGER); + this.subtype.add(SubType.MOLE); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // When this creature enters, earthbend 2. + Ability ability = new EntersBattlefieldTriggeredAbility(new EarthbendTargetEffect(2)); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND)); + this.addAbility(ability); + + // Creatures you control with +1/+1 counters on them have trample. + this.addAbility(new SimpleStaticAbility(new GainAbilityAllEffect( + TrampleAbility.getInstance(), Duration.WhileOnBattlefield, + StaticFilters.FILTER_CONTROLLED_CREATURES_P1P1 + ))); + } + + private Badgermole(final Badgermole card) { + super(card); + } + + @Override + public Badgermole copy() { + return new Badgermole(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 90ddfae8760..fdc91139fed 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -38,6 +38,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Avatar Aang", 363, Rarity.MYTHIC, mage.cards.a.AvatarAang.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Avatar Enthusiasts", 11, Rarity.COMMON, mage.cards.a.AvatarEnthusiasts.class)); cards.add(new SetCardInfo("Azula Always Lies", 84, Rarity.COMMON, mage.cards.a.AzulaAlwaysLies.class)); + cards.add(new SetCardInfo("Badgermole", 166, Rarity.COMMON, mage.cards.b.Badgermole.class)); cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); cards.add(new SetCardInfo("Fated Firepower", 132, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fated Firepower", 341, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 22e9caa2ea1..748c56a2dec 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -1197,6 +1197,13 @@ public final class StaticFilters { FILTER_CONTROLLED_CREATURE_P1P1.setLockedFilter(true); } + public static final FilterControlledCreaturePermanent FILTER_CONTROLLED_CREATURES_P1P1 = new FilterControlledCreaturePermanent("creatures you control with a +1/+1 counter on it"); + + static { + FILTER_CONTROLLED_CREATURES_P1P1.add(CounterType.P1P1.getPredicate()); + FILTER_CONTROLLED_CREATURES_P1P1.setLockedFilter(true); + } + public static final FilterControlledCreaturePermanent FILTER_EACH_CONTROLLED_CREATURE_P1P1 = new FilterControlledCreaturePermanent("each creature you control with a +1/+1 counter on it"); static { From cac3be5c4ace39ffd3db9d990c5ba0d6c41f5279 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:13:51 -0400 Subject: [PATCH 18/68] [TLA] Implement Beetle-Headed Merchants --- .../mage/cards/b/BeetleHeadedMerchants.java | 46 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BeetleHeadedMerchants.java diff --git a/Mage.Sets/src/mage/cards/b/BeetleHeadedMerchants.java b/Mage.Sets/src/mage/cards/b/BeetleHeadedMerchants.java new file mode 100644 index 00000000000..78eb80306ae --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BeetleHeadedMerchants.java @@ -0,0 +1,46 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +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 BeetleHeadedMerchants extends CardImpl { + + public BeetleHeadedMerchants(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CITIZEN); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // Whenever this creature attacks, you may sacrifice another creature or artifact. If you do, draw a card and put a +1/+1 counter on this creature. + this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid( + new DrawCardSourceControllerEffect(1), + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE_OR_ARTIFACT) + ).addEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance()).concatBy("and")))); + } + + private BeetleHeadedMerchants(final BeetleHeadedMerchants card) { + super(card); + } + + @Override + public BeetleHeadedMerchants copy() { + return new BeetleHeadedMerchants(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index fdc91139fed..cd8a68e969d 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -39,6 +39,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Avatar Enthusiasts", 11, Rarity.COMMON, mage.cards.a.AvatarEnthusiasts.class)); cards.add(new SetCardInfo("Azula Always Lies", 84, Rarity.COMMON, mage.cards.a.AzulaAlwaysLies.class)); cards.add(new SetCardInfo("Badgermole", 166, Rarity.COMMON, mage.cards.b.Badgermole.class)); + cards.add(new SetCardInfo("Beetle-Headed Merchants", 86, Rarity.COMMON, mage.cards.b.BeetleHeadedMerchants.class)); cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); cards.add(new SetCardInfo("Fated Firepower", 132, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fated Firepower", 341, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); From ade5935d1a56c1c2030f916a2e845060d4e9089f Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:15:05 -0400 Subject: [PATCH 19/68] [TLA] Implement Bender's Waterskin --- .../src/mage/cards/b/BendersWaterskin.java | 35 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 36 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BendersWaterskin.java diff --git a/Mage.Sets/src/mage/cards/b/BendersWaterskin.java b/Mage.Sets/src/mage/cards/b/BendersWaterskin.java new file mode 100644 index 00000000000..9d28a9147ea --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BendersWaterskin.java @@ -0,0 +1,35 @@ +package mage.cards.b; + +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.UntapSourceDuringEachOtherPlayersUntapStepEffect; +import mage.abilities.mana.AnyColorManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BendersWaterskin extends CardImpl { + + public BendersWaterskin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + // Untap this artifact during each other player's untap step. + this.addAbility(new SimpleStaticAbility(new UntapSourceDuringEachOtherPlayersUntapStepEffect())); + + // {T}: Add one mana of any color. + this.addAbility(new AnyColorManaAbility()); + } + + private BendersWaterskin(final BendersWaterskin card) { + super(card); + } + + @Override + public BendersWaterskin copy() { + return new BendersWaterskin(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index cd8a68e969d..926377e6a7b 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -40,6 +40,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Azula Always Lies", 84, Rarity.COMMON, mage.cards.a.AzulaAlwaysLies.class)); cards.add(new SetCardInfo("Badgermole", 166, Rarity.COMMON, mage.cards.b.Badgermole.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("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); cards.add(new SetCardInfo("Fated Firepower", 132, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fated Firepower", 341, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); From bfaba3069fe983388e0fafcfa15f39da8af42213 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:17:31 -0400 Subject: [PATCH 20/68] [TLA] Implement Barrels of Blasting Jelly --- .../mage/cards/b/BarrelsOfBlastingJelly.java | 48 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 49 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BarrelsOfBlastingJelly.java diff --git a/Mage.Sets/src/mage/cards/b/BarrelsOfBlastingJelly.java b/Mage.Sets/src/mage/cards/b/BarrelsOfBlastingJelly.java new file mode 100644 index 00000000000..9fdd9763dbb --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BarrelsOfBlastingJelly.java @@ -0,0 +1,48 @@ +package mage.cards.b; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.mana.AddManaOfAnyColorEffect; +import mage.abilities.mana.LimitedTimesPerTurnActivatedManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BarrelsOfBlastingJelly extends CardImpl { + + public BarrelsOfBlastingJelly(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); + + // {1}: Add one mana of any color. Activate only once each turn. + this.addAbility(new LimitedTimesPerTurnActivatedManaAbility( + Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(), new GenericManaCost(1) + )); + + // {5}, {T}, Sacrifice this artifact: It deals 5 damage to target creature. + Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(5, "it"), new GenericManaCost(5)); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + private BarrelsOfBlastingJelly(final BarrelsOfBlastingJelly card) { + super(card); + } + + @Override + public BarrelsOfBlastingJelly copy() { + return new BarrelsOfBlastingJelly(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 926377e6a7b..10fb4f157cd 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -39,6 +39,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Avatar Enthusiasts", 11, Rarity.COMMON, mage.cards.a.AvatarEnthusiasts.class)); cards.add(new SetCardInfo("Azula Always Lies", 84, Rarity.COMMON, mage.cards.a.AzulaAlwaysLies.class)); cards.add(new SetCardInfo("Badgermole", 166, Rarity.COMMON, mage.cards.b.Badgermole.class)); + 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("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); From a877ab3f1ad3e5ce32d66d54a9c3103e921410a1 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:18:27 -0400 Subject: [PATCH 21/68] [TLA] Implement Cat-Owl --- Mage.Sets/src/mage/cards/c/CatOwl.java | 47 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 48 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CatOwl.java diff --git a/Mage.Sets/src/mage/cards/c/CatOwl.java b/Mage.Sets/src/mage/cards/c/CatOwl.java new file mode 100644 index 00000000000..74b806921ab --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CatOwl.java @@ -0,0 +1,47 @@ +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.keyword.FlyingAbility; +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 java.util.UUID; + +/** + * @author TheElk801 + */ +public final class CatOwl extends CardImpl { + + public CatOwl(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W/U}"); + + this.subtype.add(SubType.CAT); + this.subtype.add(SubType.BIRD); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever this creature attacks, untap target artifact or creature. + Ability ability = new AttacksTriggeredAbility(new UntapTargetEffect()); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE)); + this.addAbility(ability); + } + + private CatOwl(final CatOwl card) { + super(card); + } + + @Override + public CatOwl copy() { + return new CatOwl(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 10fb4f157cd..771636fb7f5 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("Cat-Owl", 212, Rarity.COMMON, mage.cards.c.CatOwl.class)); cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); cards.add(new SetCardInfo("Fated Firepower", 132, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fated Firepower", 341, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); From 6067624df2cc45c36f000da52b5bba15dd42b934 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:20:05 -0400 Subject: [PATCH 22/68] [TLA] Implement Dai Li Indoctrination --- .../src/mage/cards/d/DaiLiIndoctrination.java | 53 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 54 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DaiLiIndoctrination.java diff --git a/Mage.Sets/src/mage/cards/d/DaiLiIndoctrination.java b/Mage.Sets/src/mage/cards/d/DaiLiIndoctrination.java new file mode 100644 index 00000000000..7b5a7c24c06 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DaiLiIndoctrination.java @@ -0,0 +1,53 @@ +package mage.cards.d; + +import mage.abilities.Mode; +import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; +import mage.abilities.effects.keyword.EarthbendTargetEffect; +import mage.cards.CardImpl; +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.TargetOpponent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DaiLiIndoctrination extends CardImpl { + + private static final FilterCard filter = new FilterPermanentCard("a nonland permanent card"); + + static { + filter.add(Predicates.not(CardType.LAND.getPredicate())); + } + + public DaiLiIndoctrination(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); + + this.subtype.add(SubType.LESSON); + + // Choose one -- + // * Target opponent reveals their hand. You choose a nonland permanent card from it. That player discards that card. + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter)); + this.getSpellAbility().addTarget(new TargetOpponent()); + + // * Earthbend 2. + this.getSpellAbility().addMode(new Mode(new EarthbendTargetEffect(2)) + .addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND))); + } + + private DaiLiIndoctrination(final DaiLiIndoctrination card) { + super(card); + } + + @Override + public DaiLiIndoctrination copy() { + return new DaiLiIndoctrination(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 771636fb7f5..8f7fb6980b2 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -43,6 +43,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { 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("Cat-Owl", 212, Rarity.COMMON, mage.cards.c.CatOwl.class)); + cards.add(new SetCardInfo("Dai Li Indoctrination", 93, Rarity.COMMON, mage.cards.d.DaiLiIndoctrination.class)); cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); cards.add(new SetCardInfo("Fated Firepower", 132, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fated Firepower", 341, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); From 3367622d35f301dcad4245f21ea00d94d85adbcc Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:21:24 -0400 Subject: [PATCH 23/68] [TLA] Implement Deserter's Disciple --- .../src/mage/cards/d/DesertersDisciple.java | 57 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 58 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DesertersDisciple.java diff --git a/Mage.Sets/src/mage/cards/d/DesertersDisciple.java b/Mage.Sets/src/mage/cards/d/DesertersDisciple.java new file mode 100644 index 00000000000..68f3a9142c6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DesertersDisciple.java @@ -0,0 +1,57 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DesertersDisciple extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledCreaturePermanent("another target creature you control with power 2 or less"); + + static { + filter.add(AnotherPredicate.instance); + filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 3)); + } + + public DesertersDisciple(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.REBEL); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {T}: Another target creature you control with power 2 or less can't be blocked this turn. + Ability ability = new SimpleActivatedAbility(new CantBeBlockedTargetEffect(Duration.EndOfTurn), new TapSourceCost()); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + private DesertersDisciple(final DesertersDisciple card) { + super(card); + } + + @Override + public DesertersDisciple copy() { + return new DesertersDisciple(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 8f7fb6980b2..cebd13c0763 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -44,6 +44,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Bender's Waterskin", 255, Rarity.COMMON, mage.cards.b.BendersWaterskin.class)); cards.add(new SetCardInfo("Cat-Owl", 212, Rarity.COMMON, mage.cards.c.CatOwl.class)); cards.add(new SetCardInfo("Dai Li Indoctrination", 93, Rarity.COMMON, mage.cards.d.DaiLiIndoctrination.class)); + cards.add(new SetCardInfo("Deserter's Disciple", 131, Rarity.COMMON, mage.cards.d.DesertersDisciple.class)); cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); cards.add(new SetCardInfo("Fated Firepower", 132, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fated Firepower", 341, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); From 5c0411d02e7ba149cf3a9dc218d3871fde588024 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:22:20 -0400 Subject: [PATCH 24/68] [TLA] Implement Earth Kingdom Soldier --- .../src/mage/cards/e/EarthKingdomSoldier.java | 47 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 48 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EarthKingdomSoldier.java diff --git a/Mage.Sets/src/mage/cards/e/EarthKingdomSoldier.java b/Mage.Sets/src/mage/cards/e/EarthKingdomSoldier.java new file mode 100644 index 00000000000..58b1e7fb78b --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EarthKingdomSoldier.java @@ -0,0 +1,47 @@ +package mage.cards.e; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.target.common.TargetControlledCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class EarthKingdomSoldier extends CardImpl { + + public EarthKingdomSoldier(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G/W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // When this creature enters, put a +1/+1 counter on each of up to two target creatures you control. + Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance())); + ability.addTarget(new TargetControlledCreaturePermanent(0, 2)); + this.addAbility(ability); + } + + private EarthKingdomSoldier(final EarthKingdomSoldier card) { + super(card); + } + + @Override + public EarthKingdomSoldier copy() { + return new EarthKingdomSoldier(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index cebd13c0763..14b1d997382 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -45,6 +45,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Cat-Owl", 212, Rarity.COMMON, mage.cards.c.CatOwl.class)); cards.add(new SetCardInfo("Dai Li Indoctrination", 93, Rarity.COMMON, mage.cards.d.DaiLiIndoctrination.class)); cards.add(new SetCardInfo("Deserter's Disciple", 131, Rarity.COMMON, mage.cards.d.DesertersDisciple.class)); + cards.add(new SetCardInfo("Earth Kingdom Soldier", 216, Rarity.COMMON, mage.cards.e.EarthKingdomSoldier.class)); cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); cards.add(new SetCardInfo("Fated Firepower", 132, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fated Firepower", 341, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); From c80f70deeb2f90b6375858eebb6b7f961be688cd Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:23:35 -0400 Subject: [PATCH 25/68] [TLA] Implement Earth Village Ruffians --- .../mage/cards/e/EarthVillageRuffians.java | 44 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 45 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EarthVillageRuffians.java diff --git a/Mage.Sets/src/mage/cards/e/EarthVillageRuffians.java b/Mage.Sets/src/mage/cards/e/EarthVillageRuffians.java new file mode 100644 index 00000000000..19a0aeb8634 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EarthVillageRuffians.java @@ -0,0 +1,44 @@ +package mage.cards.e; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.effects.keyword.EarthbendTargetEffect; +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 java.util.UUID; + +/** + * @author TheElk801 + */ +public final class EarthVillageRuffians extends CardImpl { + + public EarthVillageRuffians(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B/G}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.subtype.add(SubType.ROGUE); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // When this creature dies, earthbend 2. + Ability ability = new DiesSourceTriggeredAbility(new EarthbendTargetEffect(2)); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND)); + this.addAbility(ability); + } + + private EarthVillageRuffians(final EarthVillageRuffians card) { + super(card); + } + + @Override + public EarthVillageRuffians copy() { + return new EarthVillageRuffians(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 14b1d997382..bf6cfa4cd0f 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -46,6 +46,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Dai Li Indoctrination", 93, Rarity.COMMON, mage.cards.d.DaiLiIndoctrination.class)); cards.add(new SetCardInfo("Deserter's Disciple", 131, Rarity.COMMON, mage.cards.d.DesertersDisciple.class)); cards.add(new SetCardInfo("Earth Kingdom Soldier", 216, Rarity.COMMON, mage.cards.e.EarthKingdomSoldier.class)); + cards.add(new SetCardInfo("Earth Village Ruffians", 219, Rarity.COMMON, mage.cards.e.EarthVillageRuffians.class)); cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); cards.add(new SetCardInfo("Fated Firepower", 132, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fated Firepower", 341, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); From cfeb1af64aff0dd29df9775d15587736099aafff Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:24:09 -0400 Subject: [PATCH 26/68] [TLE] update spoiler and reprints --- .../mage/sets/AvatarTheLastAirbenderEternal.java | 2 ++ Utils/mtg-cards-data.txt | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 9c5f7bae80e..4b9da85c917 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -21,6 +21,8 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { this.rotationSet = true; this.hasBasicLands = false; + 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("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); } } diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 097ef0ce318..99c2c498448 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -59881,7 +59881,20 @@ Miles Morales|Marvel's Spider-Man|234|M|{1}{G}|Legendary Creature - Human Citize Ultimate Spider-Man|Marvel's Spider-Man|234|M|{3}{R}{G}{W}|Legendary Creature - Spider Human Hero|4|3|First strike, haste$Camouflage -- {2}: Put a +1/+1 counter on Ultimate Spider-Man. He gains hexproof and becomes colorless until end of turn.$Whenever you attack, double the number of each kind of counter on each Spider and legendary creature you control.| Anti-Venom, Horrifying Healer|Marvel's Spider-Man|244|M|{W}{W}{W}{W}{W}|Legendary Creature - Symbiote Hero|5|5|When Anti-Venom enters, if he was cast, return target creature card from your graveyard to the battlefield.$If damage would be dealt to Anti-Venom, prevent that damage and put that many +1/+1 counters on him.| Iron Spider, Stark Upgrade|Marvel's Spider-Man|279|R|{3}|Legendary Artifact Creature - Spider Hero|2|3|Vigilance${T}: Put a +1/+1 counter on each artifact creature and/or Vehicle you control.${2}, Remove two +1/+1 counters from among artifacts you control: Draw a card.| +Force of Negation|Avatar: The Last Airbender Eternal|13|M|{1}{U}{U}|Instant|||If it's not your turn, you may exile a blue card from your hand rather than pay this spell's mana cost.$Counter target noncreature spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard.| +The Great Henge|Avatar: The Last Airbender Eternal|41|M|{7}{G}{G}|Legendary Artifact|||This spell costs {X} less to cast, where X is the greatest power among creatures you control.${T}: Add {G}{G}. You gain 2 life.$Whenever a nontoken creature you control enters, put a +1/+1 counter on it and draw a card.| Aang, Airbending Master|Avatar: The Last Airbender Eternal|74|M|{4}{W}|Legendary Creature - Human Avatar Ally|4|4|When Aang enters, airbend another target creature.$Whenever one or more creatures you control leave the battlefield without dying, you get an experience counter.$At the beginning of your upkeep, create a 1/1 white Ally creature token for each experience counter you have.| Katara, Waterbending Master|Avatar: The Last Airbender Eternal|93|M|{1}{U}|Legendary Creature - Human Warrior Ally|1|3|Whenever you cast a spell during an opponent's turn, you get an experience counter.$Whenever Katara attacks, you may draw a card for each experience counter you have. If you do, discard a card.| Fire Lord Ozai|Avatar: The Last Airbender Eternal|104|M|{3}{B}|Legendary Creature - Human Noble|4|4|Whenever Fire Lord Ozai attacks, you may sacrifice another creature. If you do, add an amount of {R} equal to the sacrificed creature's power. Until end of combat, you don't lose this mana as steps end.${6}: Exile the top card of each opponent's library. Until end of turn, you may play one of those cards without paying its mana cost.| The Cabbage Merchant|Avatar: The Last Airbender Eternal|134|R|{2}{G}|Legendary Creature - Human Citizen|2|2|Whenever an opponent casts a noncreature spell, create a Food token.$Whenever a creature deals combat damage to you, sacrifice a Food token.$Tap two untapped Foods you control: Add one mana of any color.| +Aang, Air Nomad|Avatar: The Last Airbender Eternal|210|R|{3}{W}{W}|Legendary Creature - Human Avatar Ally|5|4|Flying$Vigilance$Other creatures you control have vigilance.| +Aang's Defense|Avatar: The Last Airbender Eternal|211|C|{W}|Instant|||Target blocking creature you control gets +2/+2 until end of turn.$Draw a card.| +Aardvark Sloth|Avatar: The Last Airbender Eternal|212|C|{3}{W}|Creature - Sloth Beast|3|3|Lifelink| +Allied Teamwork|Avatar: The Last Airbender Eternal|213|R|{2}{W}|Enchantment|||When this enchantment enters, create a 1/1 white Ally creature token.$Allies you control get +1/+1.| +Appa, Aang's Companion|Avatar: The Last Airbender Eternal|214|U|{3}{W}|Legendary Creature - Bison Ally|2|4|Flying$Whenever Appa attacks, another target attacking creature without flying gains flying until until end of turn.| +Deny Entry|Avatar: The Last Airbender Eternal|222|C|{2}{U}|Instant|||Counter target creature spell. Draw a card, then discard a card.| +Elephant-Rat|Avatar: The Last Airbender Eternal|228|C|{1}{B}|Creature - Elephant Rat|1|3|Menace| +Capital Guard|Avatar: The Last Airbender Eternal|234|C|{1}{R}|Creature - Human Soldier|2|2|| +Dragon Moose|Avatar: The Last Airbender Eternal|235|C|{3}{R}|Creature - Dragon Elk|3|3|Haste| +Bumi, Eclectic Earthbender|Avatar: The Last Airbender Eternal|248|R|{3}{G}{G}|Legendary Creature - Human Noble Ally|4|4|When Bumi enters, earthbend 1.$Whenever Bumi attacks, put two +1/+1 counters on each land creature you control.| +Eel-Hounds|Avatar: The Last Airbender Eternal|250|U|{3}{G}|Creature - Fish Dog|4|2|Trample$Whenever this creature attacks, another target creature you control gets +2/+2 and gains trample until end of turn.| From 01944d39bbd5b7cd9d698423fe501e134693bad9 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:25:33 -0400 Subject: [PATCH 27/68] [TLE] Implement Aang, Air Nomad --- Mage.Sets/src/mage/cards/a/AangAirNomad.java | 54 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 55 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AangAirNomad.java diff --git a/Mage.Sets/src/mage/cards/a/AangAirNomad.java b/Mage.Sets/src/mage/cards/a/AangAirNomad.java new file mode 100644 index 00000000000..ff064854e72 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AangAirNomad.java @@ -0,0 +1,54 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.FlyingAbility; +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.constants.SuperType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AangAirNomad extends CardImpl { + + public AangAirNomad(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.AVATAR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Other creatures you control have vigilance. + this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( + VigilanceAbility.getInstance(), Duration.WhileOnBattlefield, + StaticFilters.FILTER_PERMANENT_CREATURES, true + ))); + } + + private AangAirNomad(final AangAirNomad card) { + super(card); + } + + @Override + public AangAirNomad copy() { + return new AangAirNomad(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 4b9da85c917..b84c15f91e5 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -21,6 +21,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { this.rotationSet = true; this.hasBasicLands = false; + cards.add(new SetCardInfo("Aang, Air Nomad", 210, Rarity.RARE, mage.cards.a.AangAirNomad.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("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From 2f594c8445332f1eb077f7c20253b8fab176333f Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:26:55 -0400 Subject: [PATCH 28/68] [TLE] Implement Aang's Defense --- Mage.Sets/src/mage/cards/a/AangsDefense.java | 45 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 46 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AangsDefense.java diff --git a/Mage.Sets/src/mage/cards/a/AangsDefense.java b/Mage.Sets/src/mage/cards/a/AangsDefense.java new file mode 100644 index 00000000000..9ab76ccdcf0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AangsDefense.java @@ -0,0 +1,45 @@ +package mage.cards.a; + +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.BlockingPredicate; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AangsDefense extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledCreaturePermanent("blocking creature you control"); + + static { + filter.add(BlockingPredicate.instance); + } + + public AangsDefense(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); + + // Target blocking creature you control gets +2/+2 until end of turn. + this.getSpellAbility().addEffect(new BoostTargetEffect(2, 2)); + this.getSpellAbility().addTarget(new TargetPermanent(filter)); + + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("
")); + } + + private AangsDefense(final AangsDefense card) { + super(card); + } + + @Override + public AangsDefense copy() { + return new AangsDefense(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index b84c15f91e5..975713768d6 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -21,6 +21,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { this.rotationSet = true; this.hasBasicLands = false; + cards.add(new SetCardInfo("Aang's Defense", 211, Rarity.COMMON, mage.cards.a.AangsDefense.class)); cards.add(new SetCardInfo("Aang, Air Nomad", 210, Rarity.RARE, mage.cards.a.AangAirNomad.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)); From 42291c75afaf5a037f2a7ff6a23f81237b597ac5 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:27:22 -0400 Subject: [PATCH 29/68] [TLE] Implement Aardvark Sloth --- Mage.Sets/src/mage/cards/a/AardvarkSloth.java | 37 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AardvarkSloth.java diff --git a/Mage.Sets/src/mage/cards/a/AardvarkSloth.java b/Mage.Sets/src/mage/cards/a/AardvarkSloth.java new file mode 100644 index 00000000000..bbda1b20a66 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AardvarkSloth.java @@ -0,0 +1,37 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.keyword.LifelinkAbility; +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 AardvarkSloth extends CardImpl { + + public AardvarkSloth(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.SLOTH); + this.subtype.add(SubType.BEAST); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + } + + private AardvarkSloth(final AardvarkSloth card) { + super(card); + } + + @Override + public AardvarkSloth copy() { + return new AardvarkSloth(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 975713768d6..ed02247a0ea 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -23,6 +23,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Aang's Defense", 211, Rarity.COMMON, mage.cards.a.AangsDefense.class)); cards.add(new SetCardInfo("Aang, Air Nomad", 210, Rarity.RARE, mage.cards.a.AangAirNomad.class)); + cards.add(new SetCardInfo("Aardvark Sloth", 212, Rarity.COMMON, mage.cards.a.AardvarkSloth.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("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From d349c8eea04530bec8dd78e087454fd540e9f0c2 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:29:05 -0400 Subject: [PATCH 30/68] [TLE] Implement Allied Teamwork --- .../src/mage/cards/a/AlliedTeamwork.java | 43 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 44 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AlliedTeamwork.java diff --git a/Mage.Sets/src/mage/cards/a/AlliedTeamwork.java b/Mage.Sets/src/mage/cards/a/AlliedTeamwork.java new file mode 100644 index 00000000000..0c51d4ab1fa --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AlliedTeamwork.java @@ -0,0 +1,43 @@ +package mage.cards.a; + +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +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.game.permanent.token.AllyToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AlliedTeamwork extends CardImpl { + + private static final FilterPermanent filter = new FilterCreaturePermanent(SubType.ALLY, "Allies"); + + public AlliedTeamwork(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); + + // When this enchantment enters, create a 1/1 white Ally creature token. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new AllyToken()))); + + // Allies you control get +1/+1. + this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter))); + } + + private AlliedTeamwork(final AlliedTeamwork card) { + super(card); + } + + @Override + public AlliedTeamwork copy() { + return new AlliedTeamwork(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index ed02247a0ea..14a8db9e032 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -24,6 +24,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Aang's Defense", 211, Rarity.COMMON, mage.cards.a.AangsDefense.class)); cards.add(new SetCardInfo("Aang, Air Nomad", 210, Rarity.RARE, mage.cards.a.AangAirNomad.class)); cards.add(new SetCardInfo("Aardvark Sloth", 212, Rarity.COMMON, mage.cards.a.AardvarkSloth.class)); + cards.add(new SetCardInfo("Allied Teamwork", 213, Rarity.RARE, mage.cards.a.AlliedTeamwork.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("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From 7e6185afa6125c66fbf2dc0c63f7566d287b3815 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:30:54 -0400 Subject: [PATCH 31/68] [TLE] Implement Appa, Aang's Companion --- .../src/mage/cards/a/AppaAangsCompanion.java | 62 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 63 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AppaAangsCompanion.java diff --git a/Mage.Sets/src/mage/cards/a/AppaAangsCompanion.java b/Mage.Sets/src/mage/cards/a/AppaAangsCompanion.java new file mode 100644 index 00000000000..e95d762bb8c --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AppaAangsCompanion.java @@ -0,0 +1,62 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +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.FilterControlledCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AppaAangsCompanion extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledCreaturePermanent("another target attacking creature without flying"); + + static { + filter.add(AnotherPredicate.instance); + filter.add(AttackingPredicate.instance); + filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class))); + } + + public AppaAangsCompanion(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.BISON); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever Appa attacks, another target attacking creature without flying gains flying until until end of turn. + Ability ability = new AttacksTriggeredAbility(new GainAbilityTargetEffect(FlyingAbility.getInstance())); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + private AppaAangsCompanion(final AppaAangsCompanion card) { + super(card); + } + + @Override + public AppaAangsCompanion copy() { + return new AppaAangsCompanion(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 14a8db9e032..0df681b8536 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -25,6 +25,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Aang, Air Nomad", 210, Rarity.RARE, mage.cards.a.AangAirNomad.class)); cards.add(new SetCardInfo("Aardvark Sloth", 212, Rarity.COMMON, mage.cards.a.AardvarkSloth.class)); cards.add(new SetCardInfo("Allied Teamwork", 213, Rarity.RARE, mage.cards.a.AlliedTeamwork.class)); + cards.add(new SetCardInfo("Appa, Aang's Companion", 214, Rarity.UNCOMMON, mage.cards.a.AppaAangsCompanion.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("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From 498084c5302d78eea36822d2c902a6cd26d874f1 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:32:31 -0400 Subject: [PATCH 32/68] [TLE] Implement Bumi, Eclectic Earthbender --- .../mage/cards/b/BumiEclecticEarthbender.java | 60 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 61 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BumiEclecticEarthbender.java diff --git a/Mage.Sets/src/mage/cards/b/BumiEclecticEarthbender.java b/Mage.Sets/src/mage/cards/b/BumiEclecticEarthbender.java new file mode 100644 index 00000000000..f8ad29546ec --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BumiEclecticEarthbender.java @@ -0,0 +1,60 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.abilities.effects.keyword.EarthbendTargetEffect; +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.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BumiEclecticEarthbender extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledCreaturePermanent("land creature you control"); + + static { + filter.add(CardType.LAND.getPredicate()); + } + + public BumiEclecticEarthbender(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.NOBLE); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // When Bumi enters, earthbend 1. + Ability ability = new EntersBattlefieldTriggeredAbility(new EarthbendTargetEffect(1)); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND)); + this.addAbility(ability); + + // Whenever Bumi attacks, put two +1/+1 counters on each land creature you control. + this.addAbility(new AttacksTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(2), filter))); + } + + private BumiEclecticEarthbender(final BumiEclecticEarthbender card) { + super(card); + } + + @Override + public BumiEclecticEarthbender copy() { + return new BumiEclecticEarthbender(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 0df681b8536..25fe561a845 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -26,6 +26,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Aardvark Sloth", 212, Rarity.COMMON, mage.cards.a.AardvarkSloth.class)); cards.add(new SetCardInfo("Allied Teamwork", 213, Rarity.RARE, mage.cards.a.AlliedTeamwork.class)); cards.add(new SetCardInfo("Appa, Aang's Companion", 214, Rarity.UNCOMMON, mage.cards.a.AppaAangsCompanion.class)); + cards.add(new SetCardInfo("Bumi, Eclectic Earthbender", 248, Rarity.RARE, mage.cards.b.BumiEclecticEarthbender.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("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From f0572c755104d726d2e9905f751a05b4427dbcb9 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:32:59 -0400 Subject: [PATCH 33/68] [TLE] Implement Capital Guard --- Mage.Sets/src/mage/cards/c/CapitalGuard.java | 33 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 34 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CapitalGuard.java diff --git a/Mage.Sets/src/mage/cards/c/CapitalGuard.java b/Mage.Sets/src/mage/cards/c/CapitalGuard.java new file mode 100644 index 00000000000..3614b01388c --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CapitalGuard.java @@ -0,0 +1,33 @@ +package mage.cards.c; + +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 CapitalGuard extends CardImpl { + + public CapitalGuard(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + } + + private CapitalGuard(final CapitalGuard card) { + super(card); + } + + @Override + public CapitalGuard copy() { + return new CapitalGuard(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 25fe561a845..e3ff9ce45f5 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -27,6 +27,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Allied Teamwork", 213, Rarity.RARE, mage.cards.a.AlliedTeamwork.class)); cards.add(new SetCardInfo("Appa, Aang's Companion", 214, Rarity.UNCOMMON, mage.cards.a.AppaAangsCompanion.class)); cards.add(new SetCardInfo("Bumi, Eclectic Earthbender", 248, Rarity.RARE, mage.cards.b.BumiEclecticEarthbender.class)); + cards.add(new SetCardInfo("Capital Guard", 234, Rarity.COMMON, mage.cards.c.CapitalGuard.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("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From 07cd325711ee76e72a4fc5ca83a061cbfcb56529 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:34:06 -0400 Subject: [PATCH 34/68] [TLE] Implement Deny Entry --- Mage.Sets/src/mage/cards/d/DenyEntry.java | 35 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 36 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DenyEntry.java diff --git a/Mage.Sets/src/mage/cards/d/DenyEntry.java b/Mage.Sets/src/mage/cards/d/DenyEntry.java new file mode 100644 index 00000000000..027b7c9f74d --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DenyEntry.java @@ -0,0 +1,35 @@ +package mage.cards.d; + +import mage.abilities.effects.common.CounterTargetEffect; +import mage.abilities.effects.common.DrawDiscardControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; +import mage.target.TargetSpell; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DenyEntry extends CardImpl { + + public DenyEntry(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}"); + + // Counter target creature spell. Draw a card, then discard a card. + this.getSpellAbility().addEffect(new CounterTargetEffect()); + this.getSpellAbility().addTarget(new TargetSpell(StaticFilters.FILTER_SPELL_CREATURE)); + this.getSpellAbility().addEffect(new DrawDiscardControllerEffect(1, 1)); + } + + private DenyEntry(final DenyEntry card) { + super(card); + } + + @Override + public DenyEntry copy() { + return new DenyEntry(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index e3ff9ce45f5..c9bae277bb0 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -28,6 +28,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Appa, Aang's Companion", 214, Rarity.UNCOMMON, mage.cards.a.AppaAangsCompanion.class)); cards.add(new SetCardInfo("Bumi, Eclectic Earthbender", 248, Rarity.RARE, mage.cards.b.BumiEclecticEarthbender.class)); 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("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("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From 35c5344a310213c612d60cd499b5b79fba9a7f2e Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:34:46 -0400 Subject: [PATCH 35/68] [TLE] Implement Dragon Moose --- Mage.Sets/src/mage/cards/d/DragonMoose.java | 37 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DragonMoose.java diff --git a/Mage.Sets/src/mage/cards/d/DragonMoose.java b/Mage.Sets/src/mage/cards/d/DragonMoose.java new file mode 100644 index 00000000000..9a2fe5bb4ff --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DragonMoose.java @@ -0,0 +1,37 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.abilities.keyword.HasteAbility; +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 DragonMoose extends CardImpl { + + public DragonMoose(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.DRAGON); + this.subtype.add(SubType.ELK); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Haste + this.addAbility(HasteAbility.getInstance()); + } + + private DragonMoose(final DragonMoose card) { + super(card); + } + + @Override + public DragonMoose copy() { + return new DragonMoose(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index c9bae277bb0..fae64914390 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -29,6 +29,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Bumi, Eclectic Earthbender", 248, Rarity.RARE, mage.cards.b.BumiEclecticEarthbender.class)); 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("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("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From 12f52b24df16c6246b62ed28f3cfc1a6f2d3567d Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:36:11 -0400 Subject: [PATCH 36/68] [TLE] Implement Eel-Hounds --- Mage.Sets/src/mage/cards/e/EelHounds.java | 49 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 50 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EelHounds.java diff --git a/Mage.Sets/src/mage/cards/e/EelHounds.java b/Mage.Sets/src/mage/cards/e/EelHounds.java new file mode 100644 index 00000000000..5e313e6c556 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EelHounds.java @@ -0,0 +1,49 @@ +package mage.cards.e; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.TrampleAbility; +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 java.util.UUID; + +/** + * @author TheElk801 + */ +public final class EelHounds extends CardImpl { + + public EelHounds(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + + this.subtype.add(SubType.FISH); + this.subtype.add(SubType.DOG); + this.power = new MageInt(4); + this.toughness = new MageInt(2); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Whenever this creature attacks, another target creature you control gets +2/+2 and gains trample until end of turn. + Ability ability = new AttacksTriggeredAbility(new BoostTargetEffect(2, 2).setText("another target creature you control gets +2/+2")); + ability.addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance()).setText("and gains trample until end of turn")); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE_YOU_CONTROL)); + this.addAbility(ability); + } + + private EelHounds(final EelHounds card) { + super(card); + } + + @Override + public EelHounds copy() { + return new EelHounds(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index fae64914390..4c363a07239 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -30,6 +30,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("Eel-Hounds", 250, Rarity.UNCOMMON, mage.cards.e.EelHounds.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("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From 3ecf58a3e164eb9683250c65fb9f12f996d0cfc1 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 14:36:37 -0400 Subject: [PATCH 37/68] [TLE] Implement Elephant-Rat --- Mage.Sets/src/mage/cards/e/ElephantRat.java | 37 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/ElephantRat.java diff --git a/Mage.Sets/src/mage/cards/e/ElephantRat.java b/Mage.Sets/src/mage/cards/e/ElephantRat.java new file mode 100644 index 00000000000..0698a4082c9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/ElephantRat.java @@ -0,0 +1,37 @@ +package mage.cards.e; + +import mage.MageInt; +import mage.abilities.keyword.MenaceAbility; +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 ElephantRat extends CardImpl { + + public ElephantRat(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add(SubType.ELEPHANT); + this.subtype.add(SubType.RAT); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Menace + this.addAbility(new MenaceAbility()); + } + + private ElephantRat(final ElephantRat card) { + super(card); + } + + @Override + public ElephantRat copy() { + return new ElephantRat(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 4c363a07239..6e4c3c65678 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -31,6 +31,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { 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("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("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("The Great Henge", 41, Rarity.MYTHIC, mage.cards.t.TheGreatHenge.class)); From 5adff9bd516be17f51b0313e8ac90c822c2e334a Mon Sep 17 00:00:00 2001 From: Steven Knipe Date: Thu, 14 Aug 2025 17:17:52 -0700 Subject: [PATCH 38/68] Fix ThreeDogGalaxyNewsDJTokenEffect bug from variable shadowing --- .../mage/cards/t/ThreeDogGalaxyNewsDJ.java | 37 +++++-------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/Mage.Sets/src/mage/cards/t/ThreeDogGalaxyNewsDJ.java b/Mage.Sets/src/mage/cards/t/ThreeDogGalaxyNewsDJ.java index be6d2d08ff0..a8cc25fd73f 100644 --- a/Mage.Sets/src/mage/cards/t/ThreeDogGalaxyNewsDJ.java +++ b/Mage.Sets/src/mage/cards/t/ThreeDogGalaxyNewsDJ.java @@ -18,14 +18,12 @@ import mage.constants.SubType; import mage.constants.SuperType; import mage.filter.FilterPermanent; import mage.filter.common.FilterAttackingCreature; -import mage.filter.predicate.ObjectSourcePlayer; -import mage.filter.predicate.ObjectSourcePlayerPredicate; import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.filter.predicate.permanent.AttachedToSourcePredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import java.util.Optional; import java.util.UUID; /** @@ -61,24 +59,7 @@ class ThreeDogGalaxyNewsDJEffect extends OneShotEffect { private static final FilterPermanent filter = new FilterPermanent(SubType.AURA, "Aura attached to this creature"); static { - filter.add(ThreeDogGalaxyNewsDJPredicate.instance); - } - - enum ThreeDogGalaxyNewsDJPredicate implements ObjectSourcePlayerPredicate { - instance; - - @Override - public boolean apply(ObjectSourcePlayer input, Game game) { - return input - .getSource() - .getSourceObjectIfItStillExists(game) != null - && Optional - .ofNullable(input) - .map(ObjectSourcePlayer::getObject) - .map(Permanent::getAttachedTo) - .map(input.getSourceId()::equals) - .orElse(false); - } + filter.add(AttachedToSourcePredicate.instance); } ThreeDogGalaxyNewsDJEffect() { @@ -133,18 +114,18 @@ class ThreeDogGalaxyNewsDJTokenEffect extends OneShotEffect { filter.add(AnotherPredicate.instance); } - private final Permanent permanent; + private final Permanent sacPermanent; ThreeDogGalaxyNewsDJTokenEffect(Permanent permanent) { super(Outcome.Benefit); - this.permanent = permanent != null ? permanent.copy() : null; + this.sacPermanent = permanent != null ? permanent.copy() : null; staticText = "for each other attacking creature you control, " + "create a token that's a copy of that Aura attached to that creature"; } private ThreeDogGalaxyNewsDJTokenEffect(final ThreeDogGalaxyNewsDJTokenEffect effect) { super(effect); - this.permanent = effect.permanent != null ? effect.permanent.copy() : null; + this.sacPermanent = effect.sacPermanent != null ? effect.sacPermanent.copy() : null; } @Override @@ -154,15 +135,15 @@ class ThreeDogGalaxyNewsDJTokenEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - if (permanent == null) { + if (sacPermanent == null) { return false; } - for (Permanent permanent : game.getBattlefield().getActivePermanents( + for (Permanent attacker : game.getBattlefield().getActivePermanents( filter, source.getControllerId(), source, game )) { new CreateTokenCopyTargetEffect() - .setSavedPermanent(permanent) - .setAttachedTo(permanent.getId()) + .setSavedPermanent(sacPermanent) + .setAttachedTo(attacker.getId()) .apply(game, source); } return true; From 9c6a2762bbc60e25241cea13827460b269460828 Mon Sep 17 00:00:00 2001 From: Grath <1895280+Grath@users.noreply.github.com> Date: Thu, 14 Aug 2025 22:02:09 -0400 Subject: [PATCH 39/68] [TLA] Implement Haru, Hidden Talent --- .../src/mage/cards/h/HaruHiddenTalent.java | 52 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 53 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HaruHiddenTalent.java diff --git a/Mage.Sets/src/mage/cards/h/HaruHiddenTalent.java b/Mage.Sets/src/mage/cards/h/HaruHiddenTalent.java new file mode 100644 index 00000000000..150100e1f52 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HaruHiddenTalent.java @@ -0,0 +1,52 @@ + +package mage.cards.h; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.effects.keyword.EarthbendTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; + +import java.util.UUID; + +/** + * + * @author Grath + */ +public final class HaruHiddenTalent extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledPermanent(SubType.ALLY, "another Ally you control"); + + static { + filter.add(AnotherPredicate.instance); + } + + public HaruHiddenTalent(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(1); + this.toughness = new MageInt(1); + + // Whenever another Ally you control enters, earthbend 1. + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + new EarthbendTargetEffect(1), filter + )); + } + + private HaruHiddenTalent(final HaruHiddenTalent card) { + super(card); + } + + @Override + public HaruHiddenTalent copy() { + return new HaruHiddenTalent(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index bf6cfa4cd0f..f730509cd5f 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -54,6 +54,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("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Haru, Hidden Talent", 182, Rarity.UNCOMMON, mage.cards.h.HaruHiddenTalent.class)); cards.add(new SetCardInfo("Island", 288, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); 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)); From 32080c731f9839fc13aa896a67681f2b45d717dd Mon Sep 17 00:00:00 2001 From: Grath <1895280+Grath@users.noreply.github.com> Date: Thu, 14 Aug 2025 22:12:42 -0400 Subject: [PATCH 40/68] [TLA] Fix Haru not having a target. --- Mage.Sets/src/mage/cards/h/HaruHiddenTalent.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/h/HaruHiddenTalent.java b/Mage.Sets/src/mage/cards/h/HaruHiddenTalent.java index 150100e1f52..4c46979c96d 100644 --- a/Mage.Sets/src/mage/cards/h/HaruHiddenTalent.java +++ b/Mage.Sets/src/mage/cards/h/HaruHiddenTalent.java @@ -2,6 +2,7 @@ package mage.cards.h; import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.effects.keyword.EarthbendTargetEffect; import mage.cards.CardImpl; @@ -9,8 +10,10 @@ 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 java.util.UUID; @@ -36,9 +39,9 @@ public final class HaruHiddenTalent extends CardImpl { this.toughness = new MageInt(1); // Whenever another Ally you control enters, earthbend 1. - this.addAbility(new EntersBattlefieldAllTriggeredAbility( - new EarthbendTargetEffect(1), filter - )); + Ability ability = new EntersBattlefieldAllTriggeredAbility(new EarthbendTargetEffect(1), filter); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND)); + this.addAbility(ability); } private HaruHiddenTalent(final HaruHiddenTalent card) { From 0ec783cfdca4e72d9975b20b9922360124d52462 Mon Sep 17 00:00:00 2001 From: Grath <1895280+Grath@users.noreply.github.com> Date: Thu, 14 Aug 2025 22:18:52 -0400 Subject: [PATCH 41/68] [TLE] Implement Aang, Airbending Master --- .../mage/cards/a/AangAirbendingMaster.java | 102 ++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 103 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AangAirbendingMaster.java diff --git a/Mage.Sets/src/mage/cards/a/AangAirbendingMaster.java b/Mage.Sets/src/mage/cards/a/AangAirbendingMaster.java new file mode 100644 index 00000000000..93777a102f1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AangAirbendingMaster.java @@ -0,0 +1,102 @@ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.BatchTriggeredAbility; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CountersControllerCount; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.counter.AddCountersPlayersEffect; +import mage.abilities.effects.keyword.AirbendTargetEffect; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; +import mage.constants.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeBatchEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.AllyToken; +import mage.target.TargetPermanent; + +/** + * + * @author Grath + */ +public final class AangAirbendingMaster extends CardImpl { + + private static final DynamicValue xValue = new CountersControllerCount(CounterType.EXPERIENCE); + + public AangAirbendingMaster(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.AVATAR); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // When Aang enters, airbend another target creature. + Ability ability = new EntersBattlefieldTriggeredAbility(new AirbendTargetEffect(), false); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE)); + this.addAbility(ability); + + // Whenever one or more creatures you control leave the battlefield without dying, you get an experience counter. + this.addAbility(new AangAirbendingMasterTriggeredAbility()); + + // At the beginning of your upkeep, create a 1/1 white Ally creature token for each experience counter you have. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CreateTokenEffect(new AllyToken(), xValue))); + } + + private AangAirbendingMaster(final AangAirbendingMaster card) { + super(card); + } + + @Override + public AangAirbendingMaster copy() { + return new AangAirbendingMaster(this); + } +} + +class AangAirbendingMasterTriggeredAbility extends TriggeredAbilityImpl implements BatchTriggeredAbility { + + AangAirbendingMasterTriggeredAbility() { + super(Zone.BATTLEFIELD, new AddCountersPlayersEffect(CounterType.EXPERIENCE.createInstance(), TargetController.YOU)); + setTriggerPhrase("Whenever one or more creatures you control leave the battlefield without dying, "); + } + + private AangAirbendingMasterTriggeredAbility(final AangAirbendingMasterTriggeredAbility ability) { + super(ability); + } + + @Override + public AangAirbendingMasterTriggeredAbility copy() { + return new AangAirbendingMasterTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE_BATCH; + } + + @Override + public boolean checkEvent(ZoneChangeEvent event, Game game) { + if (event.getFromZone() != Zone.BATTLEFIELD || event.getToZone() == Zone.GRAVEYARD) { + return false; + } + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); + return permanent != null && permanent.isCreature(game) && permanent.isControlledBy(getControllerId()); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return !getFilteredEvents((ZoneChangeBatchEvent) event, game).isEmpty(); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 6e4c3c65678..46ce5344889 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -23,6 +23,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Aang's Defense", 211, Rarity.COMMON, mage.cards.a.AangsDefense.class)); cards.add(new SetCardInfo("Aang, Air Nomad", 210, Rarity.RARE, mage.cards.a.AangAirNomad.class)); + cards.add(new SetCardInfo("Aang, Airbending Master", 74, Rarity.MYTHIC, mage.cards.a.AangAirbendingMaster.class)); cards.add(new SetCardInfo("Aardvark Sloth", 212, Rarity.COMMON, mage.cards.a.AardvarkSloth.class)); cards.add(new SetCardInfo("Allied Teamwork", 213, Rarity.RARE, mage.cards.a.AlliedTeamwork.class)); cards.add(new SetCardInfo("Appa, Aang's Companion", 214, Rarity.UNCOMMON, mage.cards.a.AppaAangsCompanion.class)); From c5a52232d0559af79a9305cf8d5e867a622e3fea Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 17:09:50 -0400 Subject: [PATCH 42/68] [TLE] Implement The Cabbage Merchant --- .../src/mage/cards/t/TheCabbageMerchant.java | 67 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 68 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TheCabbageMerchant.java diff --git a/Mage.Sets/src/mage/cards/t/TheCabbageMerchant.java b/Mage.Sets/src/mage/cards/t/TheCabbageMerchant.java new file mode 100644 index 00000000000..d79315922f4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TheCabbageMerchant.java @@ -0,0 +1,67 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.common.DealsDamageToYouAllTriggeredAbility; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.costs.common.TapTargetCost; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.SacrificeControllerEffect; +import mage.abilities.mana.AnyColorManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.game.permanent.token.FoodToken; +import mage.target.common.TargetControlledPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TheCabbageMerchant extends CardImpl { + + private static final FilterControlledPermanent filter + = new FilterControlledPermanent(SubType.FOOD, "untapped Foods you control"); + + static { + filter.add(TappedPredicate.UNTAPPED); + } + + public TheCabbageMerchant(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.CITIZEN); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever an opponent casts a noncreature spell, create a Food token. + this.addAbility(new SpellCastOpponentTriggeredAbility( + new CreateTokenEffect(new FoodToken()), StaticFilters.FILTER_SPELL_NON_CREATURE, false + )); + + // Whenever a creature deals combat damage to you, sacrifice a Food token. + this.addAbility(new DealsDamageToYouAllTriggeredAbility( + StaticFilters.FILTER_PERMANENT_CREATURE, + new SacrificeControllerEffect(StaticFilters.FILTER_CONTROLLED_FOOD, 1, ""), true + )); + + // Tap two untapped Foods you control: Add one mana of any color. + this.addAbility(new AnyColorManaAbility(new TapTargetCost(new TargetControlledPermanent(2, filter)))); + } + + private TheCabbageMerchant(final TheCabbageMerchant card) { + super(card); + } + + @Override + public TheCabbageMerchant copy() { + return new TheCabbageMerchant(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 46ce5344889..bef3f2463ee 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -35,6 +35,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Elephant-Rat", 228, Rarity.COMMON, mage.cards.e.ElephantRat.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("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 2f85f46e32570e29b8b1f277f55e09b53730c2eb Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 17:23:26 -0400 Subject: [PATCH 43/68] [TLE] Implement Aang, Airbending Master --- .../mage/cards/a/AangAirbendingMaster.java | 67 +++++-------------- Mage.Sets/src/mage/cards/d/DourPortMage.java | 49 ++------------ ...MoreLeaveWithoutDyingTriggeredAbility.java | 52 ++++++++++++++ 3 files changed, 72 insertions(+), 96 deletions(-) create mode 100644 Mage/src/main/java/mage/abilities/common/OneOrMoreLeaveWithoutDyingTriggeredAbility.java diff --git a/Mage.Sets/src/mage/cards/a/AangAirbendingMaster.java b/Mage.Sets/src/mage/cards/a/AangAirbendingMaster.java index 93777a102f1..6f1ac6a3f2b 100644 --- a/Mage.Sets/src/mage/cards/a/AangAirbendingMaster.java +++ b/Mage.Sets/src/mage/cards/a/AangAirbendingMaster.java @@ -1,33 +1,30 @@ package mage.cards.a; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.BatchTriggeredAbility; -import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.OneOrMoreLeaveWithoutDyingTriggeredAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.CountersControllerCount; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.counter.AddCountersPlayersEffect; import mage.abilities.effects.keyword.AirbendTargetEffect; import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.constants.*; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.TargetController; import mage.counters.CounterType; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeBatchEvent; -import mage.game.events.ZoneChangeEvent; -import mage.game.permanent.Permanent; import mage.game.permanent.token.AllyToken; import mage.target.TargetPermanent; +import java.util.UUID; + /** - * - * @author Grath + * @author TheElk801 */ public final class AangAirbendingMaster extends CardImpl { @@ -35,7 +32,7 @@ public final class AangAirbendingMaster extends CardImpl { public AangAirbendingMaster(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.AVATAR); @@ -44,15 +41,19 @@ public final class AangAirbendingMaster extends CardImpl { this.toughness = new MageInt(4); // When Aang enters, airbend another target creature. - Ability ability = new EntersBattlefieldTriggeredAbility(new AirbendTargetEffect(), false); + Ability ability = new EntersBattlefieldTriggeredAbility(new AirbendTargetEffect()); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE)); this.addAbility(ability); // Whenever one or more creatures you control leave the battlefield without dying, you get an experience counter. - this.addAbility(new AangAirbendingMasterTriggeredAbility()); + this.addAbility(new OneOrMoreLeaveWithoutDyingTriggeredAbility( + new AddCountersPlayersEffect(CounterType.EXPERIENCE.createInstance(), TargetController.YOU), + StaticFilters.FILTER_CONTROLLED_CREATURES + )); // At the beginning of your upkeep, create a 1/1 white Ally creature token for each experience counter you have. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CreateTokenEffect(new AllyToken(), xValue))); + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CreateTokenEffect(new AllyToken(), xValue) + .setText("create a 1/1 white Ally creature token for each experience counter you have"))); } private AangAirbendingMaster(final AangAirbendingMaster card) { @@ -64,39 +65,3 @@ public final class AangAirbendingMaster extends CardImpl { return new AangAirbendingMaster(this); } } - -class AangAirbendingMasterTriggeredAbility extends TriggeredAbilityImpl implements BatchTriggeredAbility { - - AangAirbendingMasterTriggeredAbility() { - super(Zone.BATTLEFIELD, new AddCountersPlayersEffect(CounterType.EXPERIENCE.createInstance(), TargetController.YOU)); - setTriggerPhrase("Whenever one or more creatures you control leave the battlefield without dying, "); - } - - private AangAirbendingMasterTriggeredAbility(final AangAirbendingMasterTriggeredAbility ability) { - super(ability); - } - - @Override - public AangAirbendingMasterTriggeredAbility copy() { - return new AangAirbendingMasterTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ZONE_CHANGE_BATCH; - } - - @Override - public boolean checkEvent(ZoneChangeEvent event, Game game) { - if (event.getFromZone() != Zone.BATTLEFIELD || event.getToZone() == Zone.GRAVEYARD) { - return false; - } - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); - return permanent != null && permanent.isCreature(game) && permanent.isControlledBy(getControllerId()); - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - return !getFilteredEvents((ZoneChangeBatchEvent) event, game).isEmpty(); - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/d/DourPortMage.java b/Mage.Sets/src/mage/cards/d/DourPortMage.java index 34cf369b0b7..070db06b979 100644 --- a/Mage.Sets/src/mage/cards/d/DourPortMage.java +++ b/Mage.Sets/src/mage/cards/d/DourPortMage.java @@ -2,8 +2,7 @@ package mage.cards.d; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.BatchTriggeredAbility; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.OneOrMoreLeaveWithoutDyingTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; @@ -13,13 +12,7 @@ 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 mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeBatchEvent; -import mage.game.events.ZoneChangeEvent; -import mage.game.permanent.Permanent; import mage.target.TargetPermanent; import java.util.UUID; @@ -38,7 +31,9 @@ public final class DourPortMage extends CardImpl { this.toughness = new MageInt(3); // Whenever one or more other creatures you control leave the battlefield without dying, draw a card. - this.addAbility(new DourPortMageTriggeredAbility()); + this.addAbility(new OneOrMoreLeaveWithoutDyingTriggeredAbility( + new DrawCardSourceControllerEffect(1), StaticFilters.FILTER_OTHER_CONTROLLED_CREATURES + )); // {1}{U}, {T}: Return another target creature you control to its owner's hand. Ability ability = new SimpleActivatedAbility(new ReturnToHandTargetEffect(), new ManaCostsImpl<>("{1}{U}")); @@ -56,39 +51,3 @@ public final class DourPortMage extends CardImpl { return new DourPortMage(this); } } - -class DourPortMageTriggeredAbility extends TriggeredAbilityImpl implements BatchTriggeredAbility { - - DourPortMageTriggeredAbility() { - super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1)); - setTriggerPhrase("Whenever one or more other creatures you control leave the battlefield without dying, "); - } - - private DourPortMageTriggeredAbility(final DourPortMageTriggeredAbility ability) { - super(ability); - } - - @Override - public DourPortMageTriggeredAbility copy() { - return new DourPortMageTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ZONE_CHANGE_BATCH; - } - - @Override - public boolean checkEvent(ZoneChangeEvent event, Game game) { - if (event.getFromZone() != Zone.BATTLEFIELD || event.getToZone() == Zone.GRAVEYARD || event.getTargetId().equals(getSourceId())) { - return false; - } - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); - return permanent != null && permanent.isCreature(game) && permanent.isControlledBy(getControllerId()); - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - return !getFilteredEvents((ZoneChangeBatchEvent) event, game).isEmpty(); - } -} diff --git a/Mage/src/main/java/mage/abilities/common/OneOrMoreLeaveWithoutDyingTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/OneOrMoreLeaveWithoutDyingTriggeredAbility.java new file mode 100644 index 00000000000..cad44fa1bf2 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/OneOrMoreLeaveWithoutDyingTriggeredAbility.java @@ -0,0 +1,52 @@ +package mage.abilities.common; + +import mage.abilities.BatchTriggeredAbility; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeBatchEvent; +import mage.game.events.ZoneChangeEvent; + +/** + * @author TheElk801 + */ +public class OneOrMoreLeaveWithoutDyingTriggeredAbility extends TriggeredAbilityImpl implements BatchTriggeredAbility { + + private final FilterPermanent filter; + + public OneOrMoreLeaveWithoutDyingTriggeredAbility(Effect effect, FilterPermanent filter) { + super(Zone.BATTLEFIELD, effect); + this.filter = filter; + setTriggerPhrase("Whenever one or more " + filter.getMessage() + " leave the battlefield without dying, "); + } + + private OneOrMoreLeaveWithoutDyingTriggeredAbility(final OneOrMoreLeaveWithoutDyingTriggeredAbility ability) { + super(ability); + this.filter = ability.filter; + } + + @Override + public OneOrMoreLeaveWithoutDyingTriggeredAbility copy() { + return new OneOrMoreLeaveWithoutDyingTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE_BATCH; + } + + @Override + public boolean checkEvent(ZoneChangeEvent event, Game game) { + return Zone.BATTLEFIELD.match(event.getFromZone()) + && !Zone.GRAVEYARD.match(event.getToZone()) + && filter.match(event.getTarget(), getControllerId(), this, game); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return !getFilteredEvents((ZoneChangeBatchEvent) event, game).isEmpty(); + } +} From 89702ad81dbe0afe9df220ff564397b9c85f6939 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 18:00:29 -0400 Subject: [PATCH 44/68] [TLE] Implement Cat-Gator --- Mage.Sets/src/mage/cards/c/CatGator.java | 57 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 58 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CatGator.java diff --git a/Mage.Sets/src/mage/cards/c/CatGator.java b/Mage.Sets/src/mage/cards/c/CatGator.java new file mode 100644 index 00000000000..e53c110a7d5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CatGator.java @@ -0,0 +1,57 @@ +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.common.FilterControlledPermanent; +import mage.target.common.TargetAnyTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class CatGator extends CardImpl { + + private static final DynamicValue xValue = new PermanentsOnBattlefieldCount( + new FilterControlledPermanent(SubType.SWAMP, "Swamps you control") + ); + private static final Hint hint = new ValueHint("Swamps you control", xValue); + + public CatGator(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{B}"); + + this.subtype.add(SubType.FISH); + this.subtype.add(SubType.CROCODILE); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // When this creature enters, it deals damage equal to the number of Swamps you control to any target. + Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(xValue) + .setText("it deals damage equal to the number of Swamps you control to any target")); + ability.addTarget(new TargetAnyTarget()); + this.addAbility(ability.addHint(hint)); + } + + private CatGator(final CatGator card) { + super(card); + } + + @Override + public CatGator copy() { + return new CatGator(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index f730509cd5f..c982d8f2573 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("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("Dai Li Indoctrination", 93, Rarity.COMMON, mage.cards.d.DaiLiIndoctrination.class)); cards.add(new SetCardInfo("Deserter's Disciple", 131, Rarity.COMMON, mage.cards.d.DesertersDisciple.class)); From 80ba2a2dd06e0d4e2ade76c50c97299a9e3d9715 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 18:03:07 -0400 Subject: [PATCH 45/68] [TLE] Implement Earth Rumble --- Mage.Sets/src/mage/cards/e/EarthRumble.java | 68 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 69 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EarthRumble.java diff --git a/Mage.Sets/src/mage/cards/e/EarthRumble.java b/Mage.Sets/src/mage/cards/e/EarthRumble.java new file mode 100644 index 00000000000..cda332c1739 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EarthRumble.java @@ -0,0 +1,68 @@ +package mage.cards.e; + +import mage.abilities.Ability; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.FightTargetsEffect; +import mage.abilities.effects.keyword.EarthbendTargetEffect; +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.TargetOpponentsCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class EarthRumble extends CardImpl { + + public EarthRumble(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}"); + + // 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().addEffect(new EarthRumbleEffect()); + } + + private EarthRumble(final EarthRumble card) { + super(card); + } + + @Override + public EarthRumble copy() { + return new EarthRumble(this); + } +} + +class EarthRumbleEffect extends OneShotEffect { + + EarthRumbleEffect() { + super(Outcome.Benefit); + staticText = "When you do, up to one target creature you control fights target creature an opponent controls"; + } + + private EarthRumbleEffect(final EarthRumbleEffect effect) { + super(effect); + } + + @Override + public EarthRumbleEffect copy() { + return new EarthRumbleEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new FightTargetsEffect(), false); + ability.addTarget(new TargetControlledCreaturePermanent(0, 1)); + ability.addTarget(new TargetOpponentsCreaturePermanent()); + game.fireReflexiveTriggeredAbility(ability, source); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index c982d8f2573..84104be5e87 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -47,6 +47,7 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Dai Li Indoctrination", 93, Rarity.COMMON, mage.cards.d.DaiLiIndoctrination.class)); cards.add(new SetCardInfo("Deserter's Disciple", 131, Rarity.COMMON, mage.cards.d.DesertersDisciple.class)); cards.add(new SetCardInfo("Earth Kingdom Soldier", 216, Rarity.COMMON, mage.cards.e.EarthKingdomSoldier.class)); + cards.add(new SetCardInfo("Earth Rumble", 174, Rarity.UNCOMMON, mage.cards.e.EarthRumble.class)); cards.add(new SetCardInfo("Earth Village Ruffians", 219, Rarity.COMMON, mage.cards.e.EarthVillageRuffians.class)); cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); cards.add(new SetCardInfo("Fated Firepower", 132, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); From 38bb4422a6d04b599be6691ab58e4c1d4214b5fd Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:22:13 -0400 Subject: [PATCH 46/68] [TLE] update spoiler and reprints --- .../sets/AvatarTheLastAirbenderEternal.java | 8 ++++ Utils/mtg-cards-data.txt | 44 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index bef3f2463ee..4d2026a5759 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -33,9 +33,17 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Dragon Moose", 235, Rarity.COMMON, mage.cards.d.DragonMoose.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)); + cards.add(new SetCardInfo("Feed the Swarm", 257, Rarity.COMMON, mage.cards.f.FeedTheSwarm.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)); 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("Thriving Bluff", 260, Rarity.COMMON, mage.cards.t.ThrivingBluff.class)); + cards.add(new SetCardInfo("Thriving Grove", 261, Rarity.COMMON, mage.cards.t.ThrivingGrove.class)); + cards.add(new SetCardInfo("Thriving Heath", 262, Rarity.COMMON, mage.cards.t.ThrivingHeath.class)); + 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)); } } diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 99c2c498448..651a936f871 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -59892,9 +59892,53 @@ Aang's Defense|Avatar: The Last Airbender Eternal|211|C|{W}|Instant|||Target blo Aardvark Sloth|Avatar: The Last Airbender Eternal|212|C|{3}{W}|Creature - Sloth Beast|3|3|Lifelink| Allied Teamwork|Avatar: The Last Airbender Eternal|213|R|{2}{W}|Enchantment|||When this enchantment enters, create a 1/1 white Ally creature token.$Allies you control get +1/+1.| Appa, Aang's Companion|Avatar: The Last Airbender Eternal|214|U|{3}{W}|Legendary Creature - Bison Ally|2|4|Flying$Whenever Appa attacks, another target attacking creature without flying gains flying until until end of turn.| +Katara, Heroic Healer|Avatar: The Last Airbender Eternal|215|U|{4}{W}|Legendary Creature - Human Warrior Ally|2|3|Lifelink$When Katara enters, put a +1/+1 counter on each other creature you control.| +Kyoshi Warrior Guard|Avatar: The Last Airbender Eternal|216|C|{1}{W}|Creature - Human Warrior Ally|2|3|| +Momo, Rambunctious Rascal|Avatar: The Last Airbender Eternal|217|U|{2}{W}|Legendary Creature - Lemur Bat Ally|1|1|Flying$When Momo enters, he deals 4 damage to target tapped creature an opponent controls.| +Sledding Otter-Penguin|Avatar: The Last Airbender Eternal|218|C|{2}{W}|Creature - Otter Bird|2|3|{3}: Put a +1/+1 counter on this creature.| +Sokka, Wolf Cove's Protector|Avatar: The Last Airbender Eternal|219|U|{2}{W}|Legendary Creature - Human Warrior Ally|3|3|Vigilance| +Tundra Wall|Avatar: The Last Airbender Eternal|220|C|{1}{W}|Creature - Wall|0|4|Defender| +Wolf Cove Villager|Avatar: The Last Airbender Eternal|221|C|{W}|Creature - Human Peasant|2|2|This creature enters tapped.| Deny Entry|Avatar: The Last Airbender Eternal|222|C|{2}{U}|Instant|||Counter target creature spell. Draw a card, then discard a card.| +Flying Dolphin-Fish|Avatar: The Last Airbender Eternal|223|C|{1}{U}|Creature - Whale Fish|1|3|Flying| +Lost in the Spirit World|Avatar: The Last Airbender Eternal|224|U|{2}{U}|Sorcery|||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."| +The Terror of Serpent's Pass|Avatar: The Last Airbender Eternal|225|R|{5}{U}{U}|Legendary Creature - Serpent|8|8|Hexproof| +Turtle-Seals|Avatar: The Last Airbender Eternal|226|C|{3}{U}|Creature - Turtle Seal|2|4|Vigilance| +Water Whip|Avatar: The Last Airbender Eternal|227|R|{U}{U}|Sorcery - Lesson|||As an additional cost to cast this spell, waterbend {5}.$Return up to two target creatures to their owners' hands. Draw two cards.| Elephant-Rat|Avatar: The Last Airbender Eternal|228|C|{1}{B}|Creature - Elephant Rat|1|3|Menace| +Fire Nation Ambushers|Avatar: The Last Airbender Eternal|229|C|{2}{B}|Creature - Human Soldier|3|2|Flash| +Fire Nation Sentinels|Avatar: The Last Airbender Eternal|230|R|{3}{B}{B}|Creature - Human Soldier|4|4|Whenever a nontoken creature an opponent controls dies, put a +1/+1 counter on each creature you control.| +Gilacorn|Avatar: The Last Airbender Eternal|231|C|{B}|Creature - Lizard|1|1|Deathtouch| +Lion Vulture|Avatar: The Last Airbender Eternal|232|R|{3}{B}|Creature - Cat Bird|2|2|Flying$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.| +Purple Pentapus|Avatar: The Last Airbender Eternal|233|C|{B}|Creature - Octopus Starfish|1|1|When this creature enters, surveil 1.${2}{B}, Tap an untapped creature you control: Return this card from your graveyard to the battlefield tapped.| Capital Guard|Avatar: The Last Airbender Eternal|234|C|{1}{R}|Creature - Human Soldier|2|2|| Dragon Moose|Avatar: The Last Airbender Eternal|235|C|{3}{R}|Creature - Dragon Elk|3|3|Haste| +Explosive Shot|Avatar: The Last Airbender Eternal|236|C|{1}{R}|Sorcery|||Explosive Shot deals 4 damage to target creature.| +Fire Nation Archers|Avatar: The Last Airbender Eternal|237|R|{3}{R}|Creature - Human Archer|3|4|Reach${5}: This creature deals 2 damage to each opponent. Create a 2/2 red Soldier creature token.| +Fire Nation Soldier|Avatar: The Last Airbender Eternal|238|C|{2}{R}|Creature - Human Soldier|3|2|Haste| +Fire Nation's Conquest|Avatar: The Last Airbender Eternal|239|U|{2}{R}|Enchantment|||Creatures you control get +1/+0.| +Iroh, Firebending Instructor|Avatar: The Last Airbender Eternal|240|U|{2}{R}|Legendary Creature - Human Noble Ally|2|2|Whenever Iroh attacks, attacking creatures get +1/+1 until end of turn.| +Komodo Rhino|Avatar: The Last Airbender Eternal|241|C|{3}{R}|Creature - Lizard Rhino|5|2|Trample| +Loyal Fire Sage|Avatar: The Last Airbender Eternal|242|U|{2}{R}|Creature - Human Cleric Ally|3|3|Firebending 1${5}: Create a 1/1 white Ally creature token.| +Roku's Mastery|Avatar: The Last Airbender Eternal|243|U|{X}{R}{R}|Instant|||Roku's Mastery deals X damage to target creature. If X is 4 or greater, scry 2.| +Warship Scout|Avatar: The Last Airbender Eternal|244|C|{R}|Creature - Human Scout|2|1|| +Zhao, the Seething Flame|Avatar: The Last Airbender Eternal|245|U|{4}{R}|Legendary Creature - Human Soldier|5|5|Menace| +Zuko, Avatar Hunter|Avatar: The Last Airbender Eternal|246|R|{3}{R}{R}|Legendary Creature - Human Noble|4|5|Reach$Whenever you cast a red spell, create a 2/2 red Soldier creature token.| +Zuko's Offense|Avatar: The Last Airbender Eternal|247|C|{R}|Sorcery|||Zuko's Offense deals 2 damage to any target.| Bumi, Eclectic Earthbender|Avatar: The Last Airbender Eternal|248|R|{3}{G}{G}|Legendary Creature - Human Noble Ally|4|4|When Bumi enters, earthbend 1.$Whenever Bumi attacks, put two +1/+1 counters on each land creature you control.| +Earthbending Student|Avatar: The Last Airbender Eternal|249|U|{2}{G}|Creature - Human Warrior Ally|1|3|When this creature enters, earthbend 2.$Land creatures you control have vigilance.| Eel-Hounds|Avatar: The Last Airbender Eternal|250|U|{3}{G}|Creature - Fish Dog|4|2|Trample$Whenever this creature attacks, another target creature you control gets +2/+2 and gains trample until end of turn.| +Frog-Squirrels|Avatar: The Last Airbender Eternal|251|C|{1}{G}|Creature - Frog Squirrel|2|2|Reach| +Hippo-Cows|Avatar: The Last Airbender Eternal|252|C|{4}{G}|Creature - Hippo Ox|5|4|Trample| +Match the Odds|Avatar: The Last Airbender Eternal|253|U|{2}{G}|Sorcery - Lesson|||Create a 1/1 white Ally creature token. Put a +1/+1 counter on it for each creature your opponents control.| +Seismic Tutelage|Avatar: The Last Airbender Eternal|254|R|{3}{G}|Enchantment - Aura|||Enchant creature$When this Aura enters, put a +1/+1 counter on enchanted creature.$Whenever enchanted creature attacks, double the number of +1/+1 counters on it.| +Hog-Monkey Rampage|Avatar: The Last Airbender Eternal|255|U|{1}{R/G}|Instant|||Choose target creature you control and target creature an opponent controls. Put a +1/+1 counter on the creature you control if it has power 4 or greater. Then those creatures fight each other.| +Mechanical Glider|Avatar: The Last Airbender Eternal|256|C|{1}|Artifact - Equipment|||When this Equipment enters, attach it to target creature you control.$Equipped creature has flying.$Equip {2}| +Feed the Swarm|Avatar: The Last Airbender Eternal|257|C|{1}{B}|Sorcery|||Destroy target creature or enchantment an opponent controls. You lose life equal to that permanent's mana value.| +Run Amok|Avatar: The Last Airbender Eternal|258|C|{1}{R}|Instant|||Target attacking creature gets +3/+3 and gains trample until end of turn.| +Explore|Avatar: The Last Airbender Eternal|259|C|{1}{G}|Sorcery|||You may play an additional land this turn.$Draw a card.| +Thriving Bluff|Avatar: The Last Airbender Eternal|260|C||Land|||This land enters tapped. As it enters, choose a color other than red.${T}: Add {R} or one mana of the chosen color.| +Thriving Grove|Avatar: The Last Airbender Eternal|261|C||Land|||This land enters tapped. As it enters, choose a color other than green.${T}: Add {G} or one mana of the chosen color.| +Thriving Heath|Avatar: The Last Airbender Eternal|262|C||Land|||This land enters tapped. As it enters, choose a color other than white.${T}: Add {W} or one mana of the chosen color.| +Thriving Isle|Avatar: The Last Airbender Eternal|263|C||Land|||This land enters tapped. As it enters, choose a color other than blue.${T}: Add {U} or one mana of the chosen color.| +Thriving Moor|Avatar: The Last Airbender Eternal|264|C||Land|||This land enters tapped. As it enters, choose a color other than black.${T}: Add {B} or one mana of the chosen color.| From a598d92eb2efdefcedd2b28140361f33d35ee17e Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:22:53 -0400 Subject: [PATCH 47/68] [TLE] Implement Zhao, the Seething Flame --- .../mage/cards/z/ZhaoTheSeethingFlame.java | 39 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 40 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/z/ZhaoTheSeethingFlame.java diff --git a/Mage.Sets/src/mage/cards/z/ZhaoTheSeethingFlame.java b/Mage.Sets/src/mage/cards/z/ZhaoTheSeethingFlame.java new file mode 100644 index 00000000000..e9978822ea8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/z/ZhaoTheSeethingFlame.java @@ -0,0 +1,39 @@ +package mage.cards.z; + +import mage.MageInt; +import mage.abilities.keyword.MenaceAbility; +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 ZhaoTheSeethingFlame extends CardImpl { + + public ZhaoTheSeethingFlame(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Menace + this.addAbility(new MenaceAbility()); + } + + private ZhaoTheSeethingFlame(final ZhaoTheSeethingFlame card) { + super(card); + } + + @Override + public ZhaoTheSeethingFlame copy() { + return new ZhaoTheSeethingFlame(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 4d2026a5759..dee2b0cc2d6 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -45,5 +45,6 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Thriving Heath", 262, Rarity.COMMON, mage.cards.t.ThrivingHeath.class)); 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("Zhao, the Seething Flame", 245, Rarity.UNCOMMON, mage.cards.z.ZhaoTheSeethingFlame.class)); } } From 6d883b5a778396a34ac44d4a188e195ad3183ac6 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:23:41 -0400 Subject: [PATCH 48/68] [TLE] Implement Zuko's Offense --- Mage.Sets/src/mage/cards/z/ZukosOffense.java | 32 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 33 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/z/ZukosOffense.java diff --git a/Mage.Sets/src/mage/cards/z/ZukosOffense.java b/Mage.Sets/src/mage/cards/z/ZukosOffense.java new file mode 100644 index 00000000000..581a4ce5fd2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/z/ZukosOffense.java @@ -0,0 +1,32 @@ +package mage.cards.z; + +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetAnyTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ZukosOffense extends CardImpl { + + public ZukosOffense(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}"); + + // Zuko's Offense deals 2 damage to any target. + this.getSpellAbility().addEffect(new DamageTargetEffect(2)); + this.getSpellAbility().addTarget(new TargetAnyTarget()); + } + + private ZukosOffense(final ZukosOffense card) { + super(card); + } + + @Override + public ZukosOffense copy() { + return new ZukosOffense(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index dee2b0cc2d6..48146182e48 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -46,5 +46,6 @@ 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("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)); } } From c6b631a5b462e8f3be5aba3b68719e7bbcd7ab63 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:24:12 -0400 Subject: [PATCH 49/68] [TLE] Implement Wolf Cove Villager --- .../src/mage/cards/w/WolfCoveVillager.java | 37 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WolfCoveVillager.java diff --git a/Mage.Sets/src/mage/cards/w/WolfCoveVillager.java b/Mage.Sets/src/mage/cards/w/WolfCoveVillager.java new file mode 100644 index 00000000000..94c9a626062 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WolfCoveVillager.java @@ -0,0 +1,37 @@ +package mage.cards.w; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTappedAbility; +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 WolfCoveVillager extends CardImpl { + + public WolfCoveVillager(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.PEASANT); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // This creature enters tapped. + this.addAbility(new EntersBattlefieldTappedAbility()); + } + + private WolfCoveVillager(final WolfCoveVillager card) { + super(card); + } + + @Override + public WolfCoveVillager copy() { + return new WolfCoveVillager(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 48146182e48..c3c5583e517 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("Thriving Heath", 262, Rarity.COMMON, mage.cards.t.ThrivingHeath.class)); 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("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)); } From 3fd6ee8d6a21e95836cf823c686e3337a8fab591 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:26:09 -0400 Subject: [PATCH 50/68] [TLE] Implement Water Whip --- Mage.Sets/src/mage/cards/w/WaterWhip.java | 41 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 8 ++++ 2 files changed, 49 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WaterWhip.java diff --git a/Mage.Sets/src/mage/cards/w/WaterWhip.java b/Mage.Sets/src/mage/cards/w/WaterWhip.java new file mode 100644 index 00000000000..7bf6ea5f9fe --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WaterWhip.java @@ -0,0 +1,41 @@ +package mage.cards.w; + +import mage.abilities.costs.common.WaterbendCost; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class WaterWhip extends CardImpl { + + public WaterWhip(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}{U}"); + + this.subtype.add(SubType.LESSON); + + // As an additional cost to cast this spell, waterbend {5}. + this.getSpellAbility().addCost(new WaterbendCost(5)); + + // Return up to two target creatures to their owners' hands. Draw two cards. + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2)); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2)); + } + + private WaterWhip(final WaterWhip card) { + super(card); + } + + @Override + public WaterWhip copy() { + return new WaterWhip(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index c3c5583e517..e4d0eb500e7 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -4,11 +4,16 @@ import mage.cards.ExpansionSet; import mage.constants.Rarity; import mage.constants.SetType; +import java.util.Arrays; +import java.util.List; + /** * @author TheElk801 */ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { + private static final List unfinished = Arrays.asList("Water Whip"); + private static final AvatarTheLastAirbenderEternal instance = new AvatarTheLastAirbenderEternal(); public static AvatarTheLastAirbenderEternal getInstance() { @@ -45,8 +50,11 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Thriving Heath", 262, Rarity.COMMON, mage.cards.t.ThrivingHeath.class)); 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("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)); cards.add(new SetCardInfo("Zuko's Offense", 247, Rarity.COMMON, mage.cards.z.ZukosOffense.class)); + + cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName())); } } From 014e21d035012162248a0b3360c331a5e53a2c5f Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:26:30 -0400 Subject: [PATCH 51/68] [TLE] Implement Tundra Wall --- Mage.Sets/src/mage/cards/t/TundraWall.java | 36 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 37 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TundraWall.java diff --git a/Mage.Sets/src/mage/cards/t/TundraWall.java b/Mage.Sets/src/mage/cards/t/TundraWall.java new file mode 100644 index 00000000000..374148207c4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TundraWall.java @@ -0,0 +1,36 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.keyword.DefenderAbility; +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 TundraWall extends CardImpl { + + public TundraWall(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add(SubType.WALL); + this.power = new MageInt(0); + this.toughness = new MageInt(4); + + // Defender + this.addAbility(DefenderAbility.getInstance()); + } + + private TundraWall(final TundraWall card) { + super(card); + } + + @Override + public TundraWall copy() { + return new TundraWall(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index e4d0eb500e7..e256681cc71 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("Thriving Heath", 262, Rarity.COMMON, mage.cards.t.ThrivingHeath.class)); 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("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 6a175067cb6fdb9899e6f19207697c1ac78d6f96 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:27:05 -0400 Subject: [PATCH 52/68] [TLE] Implement The Terror of Serpent's Pass --- .../mage/cards/t/TheTerrorOfSerpentsPass.java | 38 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 39 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TheTerrorOfSerpentsPass.java diff --git a/Mage.Sets/src/mage/cards/t/TheTerrorOfSerpentsPass.java b/Mage.Sets/src/mage/cards/t/TheTerrorOfSerpentsPass.java new file mode 100644 index 00000000000..f492a5426d2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TheTerrorOfSerpentsPass.java @@ -0,0 +1,38 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.keyword.HexproofAbility; +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 TheTerrorOfSerpentsPass extends CardImpl { + + public TheTerrorOfSerpentsPass(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.SERPENT); + this.power = new MageInt(8); + this.toughness = new MageInt(8); + + // Hexproof + this.addAbility(HexproofAbility.getInstance()); + } + + private TheTerrorOfSerpentsPass(final TheTerrorOfSerpentsPass card) { + super(card); + } + + @Override + public TheTerrorOfSerpentsPass copy() { + return new TheTerrorOfSerpentsPass(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index e256681cc71..8fdb93964ce 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("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)); + cards.add(new SetCardInfo("The Terror of Serpent's Pass", 225, Rarity.RARE, mage.cards.t.TheTerrorOfSerpentsPass.class)); cards.add(new SetCardInfo("Thriving Bluff", 260, Rarity.COMMON, mage.cards.t.ThrivingBluff.class)); cards.add(new SetCardInfo("Thriving Grove", 261, Rarity.COMMON, mage.cards.t.ThrivingGrove.class)); cards.add(new SetCardInfo("Thriving Heath", 262, Rarity.COMMON, mage.cards.t.ThrivingHeath.class)); From 174ccedfaefcfd49148ec639f1e2caaf1ff0d5ac Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:28:39 -0400 Subject: [PATCH 53/68] [TLE] Implement Explosive Shot --- Mage.Sets/src/mage/cards/e/ExplosiveShot.java | 32 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 33 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/ExplosiveShot.java diff --git a/Mage.Sets/src/mage/cards/e/ExplosiveShot.java b/Mage.Sets/src/mage/cards/e/ExplosiveShot.java new file mode 100644 index 00000000000..064c918e829 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/ExplosiveShot.java @@ -0,0 +1,32 @@ +package mage.cards.e; + +import mage.abilities.effects.common.DamageTargetEffect; +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 ExplosiveShot extends CardImpl { + + public ExplosiveShot(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}"); + + // Explosive Shot deals 4 damage to target creature. + this.getSpellAbility().addEffect(new DamageTargetEffect(4)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + private ExplosiveShot(final ExplosiveShot card) { + super(card); + } + + @Override + public ExplosiveShot copy() { + return new ExplosiveShot(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 8fdb93964ce..c020132b71a 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -39,6 +39,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { 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)); + 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("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)); From 93e709cc8281a1b5b14ca2edcd208b4365363b8c Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:29:51 -0400 Subject: [PATCH 54/68] [TLE] Implement Fire Nation Soldier --- .../src/mage/cards/f/FireNationSoldier.java | 37 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FireNationSoldier.java diff --git a/Mage.Sets/src/mage/cards/f/FireNationSoldier.java b/Mage.Sets/src/mage/cards/f/FireNationSoldier.java new file mode 100644 index 00000000000..d267e16f0c0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FireNationSoldier.java @@ -0,0 +1,37 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.keyword.HasteAbility; +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 FireNationSoldier extends CardImpl { + + public FireNationSoldier(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Haste + this.addAbility(HasteAbility.getInstance()); + } + + private FireNationSoldier(final FireNationSoldier card) { + super(card); + } + + @Override + public FireNationSoldier copy() { + return new FireNationSoldier(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index c020132b71a..6f18e39972e 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -41,6 +41,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Explore", 259, Rarity.COMMON, mage.cards.e.Explore.class)); 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 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)); cards.add(new SetCardInfo("Run Amok", 258, Rarity.COMMON, mage.cards.r.RunAmok.class)); From 9a43922b4077d9206caf5d1a89a0dba5e5bdddad Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:30:24 -0400 Subject: [PATCH 55/68] [TLE] Implement Fire Nation Ambushers --- .../src/mage/cards/f/FireNationAmbushers.java | 37 +++++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FireNationAmbushers.java diff --git a/Mage.Sets/src/mage/cards/f/FireNationAmbushers.java b/Mage.Sets/src/mage/cards/f/FireNationAmbushers.java new file mode 100644 index 00000000000..7f0f2444a60 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FireNationAmbushers.java @@ -0,0 +1,37 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.keyword.FlashAbility; +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 FireNationAmbushers extends CardImpl { + + public FireNationAmbushers(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Flash + this.addAbility(FlashAbility.getInstance()); + } + + private FireNationAmbushers(final FireNationAmbushers card) { + super(card); + } + + @Override + public FireNationAmbushers copy() { + return new FireNationAmbushers(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 6f18e39972e..ad994b23881 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -41,6 +41,7 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Explore", 259, Rarity.COMMON, mage.cards.e.Explore.class)); 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 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)); From dd6321abec60931a20d71503109f6a4991abeff7 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:40:53 -0400 Subject: [PATCH 56/68] [TLA] update spoiler and reprints --- .../src/mage/sets/AvatarTheLastAirbender.java | 6 ++- Utils/mtg-cards-data.txt | 49 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 84104be5e87..55a8b82f1b6 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -12,7 +12,7 @@ import java.util.List; */ public final class AvatarTheLastAirbender extends ExpansionSet { - private static final List unfinished = Arrays.asList("Aang's Iceberg", "Avatar Aang", "Aang, Master of Elements", "Katara, Water Tribe's Hope", "Yue, the Moon Spirit"); + private static final List unfinished = Arrays.asList("Aang's Iceberg", "Avatar Aang", "Aang, Master of Elements", "Flexible Waterbender", "Geyser Leaper", "Giant Koi", "Katara, Bending Prodigy", "Katara, Water Tribe's Hope", "Waterbending Lesson", "Watery Grasp", "Yue, the Moon Spirit"); private static final AvatarTheLastAirbender instance = new AvatarTheLastAirbender(); public static AvatarTheLastAirbender getInstance() { @@ -44,12 +44,14 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Bender's Waterskin", 255, Rarity.COMMON, mage.cards.b.BendersWaterskin.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)); cards.add(new SetCardInfo("Dai Li Indoctrination", 93, Rarity.COMMON, mage.cards.d.DaiLiIndoctrination.class)); cards.add(new SetCardInfo("Deserter's Disciple", 131, Rarity.COMMON, mage.cards.d.DesertersDisciple.class)); cards.add(new SetCardInfo("Earth Kingdom Soldier", 216, Rarity.COMMON, mage.cards.e.EarthKingdomSoldier.class)); cards.add(new SetCardInfo("Earth Rumble", 174, Rarity.UNCOMMON, mage.cards.e.EarthRumble.class)); cards.add(new SetCardInfo("Earth Village Ruffians", 219, Rarity.COMMON, mage.cards.e.EarthVillageRuffians.class)); cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); + cards.add(new SetCardInfo("Epic Downfall", 96, Rarity.UNCOMMON, mage.cards.e.EpicDownfall.class)); cards.add(new SetCardInfo("Fated Firepower", 132, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fated Firepower", 341, Rarity.MYTHIC, mage.cards.f.FatedFirepower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fire Lord Zuko", 221, Rarity.RARE, mage.cards.f.FireLordZuko.class, NON_FULL_USE_VARIOUS)); @@ -57,12 +59,14 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Fire Nation Attacks", 133, Rarity.UNCOMMON, mage.cards.f.FireNationAttacks.class)); cards.add(new SetCardInfo("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); 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("Island", 288, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); 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)); 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("Mountain", 290, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Redirect Lightning", 151, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 651a936f871..902175316da 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -59724,24 +59724,67 @@ Aang's Iceberg|Avatar: The Last Airbender|5|R|{2}{W}|Enchantment|||Flash$When th Airbending Lesson|Avatar: The Last Airbender|8|C|{2}{W}|Instant - Lesson|||Airbend target nonland permanent.$Draw a card.| Appa, Steadfast Guardian|Avatar: The Last Airbender|10|M|{2}{W}{W}|Legendary Creature - Bison Ally|3|4|Flash$Flying$When Appa enters, airbend any number of other target nonland permanents you control.$Whenever you cast a spell from exile, create a 1/1 white Ally creature token.| Avatar Enthusiasts|Avatar: The Last Airbender|11|C|{2}{W}|Creature - Human Peasant Ally|2|2|Whenever another Ally you control enters, put a +1/+1 counter on this creature.| +Glider Kids|Avatar: The Last Airbender|21|C|{2}{W}|Creature - Human Pilot Ally|2|3|Flying$When this creature enters, scry 1.| +Jeong Jeong's Deserters|Avatar: The Last Airbender|25|C|{1}{W}|Creature - Human Rebel Ally|1|2|When this creature enters, put a +1/+1 counter on target creature.| +Master Piandao|Avatar: The Last Airbender|28|U|{4}{W}|Legendary Creature - Human Warrior Ally|4|4|First strike$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.| Momo, Friendly Flier|Avatar: The Last Airbender|29|R|{W}|Legendary Creature - Lemur Bat Ally|1|1|Flying$The first non-Lemur creature spell with flying you cast during each of your turns costs {1} less to cast.$Whenever another creature you control with flying enters, Momo gets +1/+1 until end of turn.| +Path to Redemption|Avatar: The Last Airbender|31|C|{1}{W}|Enchantment - Aura|||Enchant creature$Enchanted creature can't attack or block.${5}, Sacrifice this Aura: Exile enchanted creature. Create a 1/1 white Ally creature token. Activate only during your turn.| +Rabaroo Troop|Avatar: The Last Airbender|32|C|{3}{W}{W}|Creature - Rabbit Kangaroo|3|5|Landfall -- Whenever a land you control enters, this creature gains flying until end of turn and you gain 1 life.$Plainscycling {2}| +Razor Rings|Avatar: The Last Airbender|33|C|{1}{W}|Instant|||Razor Rings deals 4 damage to target attacking or blocking creature. You gain life equal to the excess damage dealt this way.| Southern Air Temple|Avatar: The Last Airbender|36|U|{3}{W}|Legendary Enchantment - Shrine|||When Southern Air Temple enters, put X +1/+1 counters on each creature you control, where X is the number of Shrines you control.$Whenever another Shrine you control enters, put a +1/+1 counter on each creature you control.| +First-Time Flyer|Avatar: The Last Airbender|49|C|{1}{U}|Creature - Human Pilot Ally|1|2|Flying$This creature gets +1/+1 as long as there's a Lesson card in your graveyard.| +Flexible Waterbender|Avatar: The Last Airbender|50|C|{3}{U}|Creature - Human Warrior Ally|2|5|Vigilance$Waterbend {3}: This creature has base power and toughness 5/2 until end of turn.| +Geyser Leaper|Avatar: The Last Airbender|52|C|{4}{U}|Creature - Human Warrior Ally|4|3|Flying$Waterbend {4}: Draw a card, then discard a card.| +Giant Koi|Avatar: The Last Airbender|53|C|{4}{U}{U}|Creature - Fish|5|7|Waterbend {3}: This creature can't be blocked this turn.$Islandcycling {2}| +Iguana Parrot|Avatar: The Last Airbender|56|C|{2}{U}|Creature - Lizard Bird Pirate|2|2|Flying, vigilance$Prowess| +It'll Quench Ya!|Avatar: The Last Airbender|58|C|{1}{U}|Instant - Lesson|||Counter target spell unless its controller pays 2.| +Katara, Bending Prodigy|Avatar: The Last Airbender|59|U|{2}{U}|Legendary Creature - Human Warrior Ally|2|3|At the beginning of your end step, if Katara is tapped, put a +1/+1 counter on her.$Waterbend {6}: Draw a card.| +Master Pakku|Avatar: The Last Airbender|63|U|{1}{U}|Legendary Creature - Human Advisor Ally|1|3|Prowess$Whenever Master Pakku becomes tapped, target player mills X cards, where X is the number of Lesson cards in your graveyard.| +Otter-Penguin|Avatar: The Last Airbender|67|C|{1}{U}|Creature - Otter Bird|2|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.| +Rowdy Snowballers|Avatar: The Last Airbender|68|C|{2}{U}|Creature - Human Peasant Ally|2|2|When this creature enters, tap target creature an opponent controls and put a stun counter on it.| +Serpent of the Pass|Avatar: The Last Airbender|70|U|{5}{U}{U}|Creature - Serpent|6|5|If there are three or more Lesson cards in your graveyard, you may cast this spell as though it had flash.$This spell costs {1} less to cast for each noncreature, nonland card in your graveyard.| Sokka's Haiku|Avatar: The Last Airbender|71|U|{3}{U}{U}|Instant - Lesson|||Counter target spell.$Draw a card, then mill three cards.$Untap target land.| +Waterbending Lesson|Avatar: The Last Airbender|80|C|{3}{U}|Sorcery - Lesson|||Draw three cards. Then discard a card unless you waterbend {2}.| +Watery Grasp|Avatar: The Last Airbender|82|C|{U}|Enchantment - Aura|||Enchant creature$Enchanted creature doesn't untap during its controller's untap step.$Waterbend {5}: Enchanted creature's owner shuffles it into their library.| Yue, the Moon Spirit|Avatar: The Last Airbender|83|R|{3}{U}|Legendary Creature - Spirit Ally|3|3|Flying, vigilance$Waterbend {5}, {T}: You may cast a noncreature spell from your hand without paying its mana cost.| Azula Always Lies|Avatar: The Last Airbender|84|C|{1}{B}|Instant - Lesson|||Choose one or both --$* Target creature gets -1/-1 until end of turn.$* Put a +1/+1 counter on target creature.| Beetle-Headed Merchants|Avatar: The Last Airbender|86|C|{4}{B}|Creature - Human Citizen|5|4|Whenever this creature attacks, you may sacrifice another creature or artifact. If you do, draw a card and put a +1/+1 counter on this creature.| Buzzard-Wasp Colony|Avatar: The Last Airbender|88|U|{3}{B}|Creature - Bird Insect|2|2|Flying$When this creature enters, you may sacrifice an artifact or creature. If you do, draw a card.$Whenever another creature you control dies, if it had counters on it, put its counters on this creature.| Cat-Gator|Avatar: The Last Airbender|91|U|{6}{B}|Creature - Fish Crocodile|3|2|Lifelink$When this creature enters, it deals damage equal to the number of Swamps you control to any target.| +Corrupt Court Official|Avatar: The Last Airbender|92|C|{1}{B}|Creature - Human Advisor|1|1|When this creature enters, target opponent discards a card.| Dai Li Indoctrination|Avatar: The Last Airbender|93|C|{1}{B}|Sorcery - Lesson|||Choose one --$* Target opponent reveals their hand. You choose a nonland permanent card from it. That player discards that card.$* Earthbend 2.| +Epic Downfall|Avatar: The Last Airbender|96|U|{1}{B}|Sorcery|||Exile target creature with mana value 3 or greater.| +Fire Nation Engineer|Avatar: The Last Airbender|99|U|{2}{B}|Creature - Human Artificer|2|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.| +Heartless Act|Avatar: The Last Airbender|103|U|{1}{B}|Instant|||Choose one --$* Destroy target creature with no counters on it.$* Remove up to three counters from target creature.| +Hog-Monkey|Avatar: The Last Airbender|104|C|{2}{B}|Creature - Boar Monkey|3|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.$Exhaust -- {5}: Put two +1/+1 counters on this creature.| +Merchant of Many Hats|Avatar: The Last Airbender|110|C|{1}{B}|Creature - Human Peasant Ally|2|2|{2}{B}: Return this card from your graveyard to your hand.| +Ozai's Cruelty|Avatar: The Last Airbender|113|U|{2}{B}|Sorcery - Lesson|||Ozai's Cruelty deals 2 damage to target player. That player discards two cards.| The Rise of Sozin|Avatar: The Last Airbender|117|M|{4}{B}{B}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter.)$I -- Destroy all creatures.$II -- Choose a card name. Search target opponent's graveyard, hand, and library for up to four cards with that name and exile them. Then that player shuffles.$III -- Exile this Saga, then return it to the battlefield transformed under your control.| Fire Lord Sozin|Avatar: The Last Airbender|117|M||Legendary Creature - Human Noble|5|5|Menace, firebending 3$Whenever Fire Lord Sozin deals combat damage to a player, you may pay {X}. When you do, put any number of target creature cards with total mana value X or less from that player's graveyard onto the battlefield under your control.| Deserter's Disciple|Avatar: The Last Airbender|131|C|{1}{R}|Creature - Human Rebel Ally|2|2|{T}: Another target creature you control with power 2 or less can't be blocked this turn.| Fated Firepower|Avatar: The Last Airbender|132|M|{X}{R}{R}{R}|Enchantment|||Flash$This enchantment enters with X fire counters on it.$If a source you control would deal damage to an opponent or a permanent an opponent controls, it deals that much damage plus an amount of damage equal to the number of fire counters on this enchantment instead.| Fire Nation Attacks|Avatar: The Last Airbender|133|U|{4}{R}|Instant|||Create two 2/2 red Soldier creature tokens with firebending 1.$Flashback {8}{R}| +Fire Sages|Avatar: The Last Airbender|136|U|{1}{R}|Creature - Human Cleric|2|2|Firebending 1${1}{R}{R}: Put a +1/+1 counter on this creature.| +How to Start a Riot|Avatar: The Last Airbender|140|C|{2}{R}|Instant - Lesson|||Target creature gains menace until end of turn.$Creatures target player controls get +2/+0 until end of turn.| +Lightning Strike|Avatar: The Last Airbender|146|C|{1}{R}|Instant|||Lightning Strike deals 3 damage to any target.| +Mongoose Lizard|Avatar: The Last Airbender|148|C|{4}{R}{R}|Creature - Mongoose Lizard|5|6|Menace$When this creature enters, it deals 1 damage to any target.$Mountaincycling {2}| Redirect Lightning|Avatar: The Last Airbender|151|R|{R}|Instant - Lesson|||As an additional cost to cast this spell, pay 5 life or pay {2}.$Change the target of target spell or ability with a single target.| +Rough Rhino Cavalry|Avatar: The Last Airbender|152|C|{4}{R}|Creature - Human Mercenary|5|5|Firebending 2$Exhaust -- {8}: Put two +1/+1 counters on this creature. It gains trample until end of turn.| +Yuyan Archers|Avatar: The Last Airbender|161|C|{1}{R}|Creature - Human Archer|3|1|Reach$When this creature enters, you may discard a card. If you do, draw a card.| +Zuko, Exiled Prince|Avatar: The Last Airbender|163|U|{3}{R}|Legendary Creature - Human Noble|4|3|Firebending 3${3}: Exile the top card of your library. You may play that card this turn.| Badgermole|Avatar: The Last Airbender|166|C|{4}{G}|Creature - Badger Mole|4|4|When this creature enters, earthbend 2.$Creatures you control with +1/+1 counters on them have trample.| Earth Rumble|Avatar: The Last Airbender|174|U|{3}{G}|Sorcery|||Earthbend 2. When you do, up to one target creature you control fights target creature an opponent controls.| Earthbending Lesson|Avatar: The Last Airbender|176|C|{3}{G}|Sorcery - Lesson|||Earthbend 4.| +Flopsie, Bumi's Buddy|Avatar: The Last Airbender|179|U|{4}{G}{G}|Legendary Creature - Ape Goat|4|4|When Flopsie enters, put a +1/+1 counter on each creature you control.$Each creature you control with power 4 or greater can't be blocked by more than one creature.| +Haru, Hidden Talent|Avatar: The Last Airbender|182|U|{1}{G}|Legendary Creature - Human Peasant Ally|1|1|Whenever another Ally you control enters, earthbend 1.| +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.| +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.| +Turtle-Duck|Avatar: The Last Airbender|200|C|{G}|Creature - Turtle Bird|0|4|{3}: Until end of turn, this creature has base power 4 and gains trample.| Abandon Attachments|Avatar: The Last Airbender|205|C|{1}{U/R}|Instant - Lesson|||You may discard a card. If you do, draw two cards.| Avatar Aang|Avatar: The Last Airbender|207|M|{R}{G}{W}{U}|Legendary Creature - Human Avatar Ally|4|4|Flying, firebending 2$Whenever you waterbend, earthbend, firebend, or airbend, draw a card. Then if you've done all four this turn, transform Avatar Aang.| Aang, Master of Elements|Avatar: The Last Airbender|207|M||Legendary Creature - Avatar Ally|6|6|Flying$Spells you cast cost {W}{U}{B}{R}{G} less to cast.$At the beginning of each upkeep, you may transform Aang, Master of Elements. If you do, you gain 4 life, draw four cards, put four +1/+1 counters on him, and he deals 4 damage to each opponent.| @@ -59749,10 +59792,16 @@ Cat-Owl|Avatar: The Last Airbender|212|C|{3}{W/U}|Creature - Cat Bird|3|3|Flying Earth Kingdom Soldier|Avatar: The Last Airbender|216|C|{4}{G/W}|Creature - Human Soldier|3|4|Vigilance$When this creature enters, put a +1/+1 counter on each of up to two target creatures you control.| Earth Village Ruffians|Avatar: The Last Airbender|219|C|{2}{B/G}|Creature - Human Soldier Rogue|3|1|When this creature dies, earthbend 2.| Fire Lord Zuko|Avatar: The Last Airbender|221|R|{R}{W}{B}|Legendary Creature - Human Noble Ally|2|4|Firebending X, where X is Fire Lord Zuko's power.$Whenever you cast a spell from exile and whenever a permanent you control enters from exile, put a +1/+1 counter on each creature you control.| +Hei Bai, Spirit of Balance|Avatar: The Last Airbender|225|U|{2}{W/B}{W/B}|Legendary Creature - Bear Spirit|3|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.$When Hei Bai leaves the battlefield, put its counters on target creature you control.| Katara, the Fearless|Avatar: The Last Airbender|230|R|{G}{W}{U}|Legendary Creature - Human Warrior Ally|3|3|If a triggered ability of an Ally you control triggers, that ability triggers an additional time.| Katara, Water Tribe's Hope|Avatar: The Last Airbender|231|R|{2}{W}{U}{U}|Legendary Creature - Human Warrior Ally|3|3|Vigilance$When Katara enters, create a 1/1 white Ally creature token.$Waterbend {X}: Creatures you control have base power and toughness X/X until end of turn. X can't be 0. Activate only during your turn.| +Long Feng, Grand Secretariat|Avatar: The Last Airbender|233|U|{1}{B/G}{B/G}|Legendary Creature - Human Advisor|2|3|Whenever another creature you control or a land you control is put into a graveyard from the battlefield, put a +1/+1 counter on target creature you control.| +Pretending Poxbearers|Avatar: The Last Airbender|237|C|{1}{W/B}|Creature - Human Citizen Ally|2|1|When this creature dies, create a 1/1 white Ally creature token.| Sokka, Bold Boomeranger|Avatar: The Last Airbender|240|R|{U}{R}|Legendary Creature - Human Warrior Ally|1|1|When Sokka enters, discard up to two cards, then draw that many cards.$Whenever you cast an artifact or Lesson spell, put a +1/+1 counter on Sokka.| +Sokka, Lateral Strategist|Avatar: The Last Airbender|241|U|{1}{W/U}{W/U}|Legendary Creature - Human Warrior Ally|2|4|Vigilance$Whenever Sokka and at least one other creature attack, draw a card.| +Suki, Kyoshi Warrior|Avatar: The Last Airbender|243|U|{2}{G/W}{G/W}|Legendary Creature - Human Warrior Ally|*|4|Suki's power is equal to the number of creatures you control.$Whenever Suki attacks, create a 1/1 white Ally creature token that's tapped and attacking.| Toph, the First Metalbender|Avatar: The Last Airbender|247|R|{1}{R}{G}{W}|Legendary Creature - Human Warrior Ally|3|3|Nontoken artifacts you control are lands in addition to their other types.$At the beginning of your end step, earthbend 2.| +Vindictive Warden|Avatar: The Last Airbender|249|C|{2}{B/R}|Creature - Human Soldier|2|3|Menace$Firebending 1${3}: This creature deals 1 damage to each opponent.| Barrels of Blasting Jelly|Avatar: The Last Airbender|254|C|{1}|Artifact|||{1}: Add one mana of any color. Activate only once each turn.${5}, {T}, Sacrifice this artifact: It deals 5 damage to target creature.| Bender's Waterskin|Avatar: The Last Airbender|255|C|{3}|Artifact|||Untap this artifact during each other player's untap step.${T}: Add one mana of any color.| Plains|Avatar: The Last Airbender|287|C||Basic Land - Plains|||({T}: Add {W}.)| From 009298d1f160505a67c6df1dd293d0b2475d2141 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:42:10 -0400 Subject: [PATCH 57/68] [TLA] Implement Zuko, Exiled Prince --- .../src/mage/cards/z/ZukoExiledPrince.java | 48 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 49 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/z/ZukoExiledPrince.java diff --git a/Mage.Sets/src/mage/cards/z/ZukoExiledPrince.java b/Mage.Sets/src/mage/cards/z/ZukoExiledPrince.java new file mode 100644 index 00000000000..e6c4e755d54 --- /dev/null +++ b/Mage.Sets/src/mage/cards/z/ZukoExiledPrince.java @@ -0,0 +1,48 @@ +package mage.cards.z; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect; +import mage.abilities.keyword.FirebendingAbility; +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 java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ZukoExiledPrince extends CardImpl { + + public ZukoExiledPrince(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{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(3); + + // Firebending 3 + this.addAbility(new FirebendingAbility(3)); + + // {3}: Exile the top card of your library. You may play that card this turn. + this.addAbility(new SimpleActivatedAbility( + new ExileTopXMayPlayUntilEffect(1, Duration.EndOfTurn), new GenericManaCost(3) + )); + } + + private ZukoExiledPrince(final ZukoExiledPrince card) { + super(card); + } + + @Override + public ZukoExiledPrince copy() { + return new ZukoExiledPrince(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 55a8b82f1b6..de92b5e4c72 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("Toph, the First Metalbender", 362, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS)); 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("Zuko, Exiled Prince", 163, Rarity.UNCOMMON, mage.cards.z.ZukoExiledPrince.class)); cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName())); } From 69de331df03772e25deb45607e37725cb4235bfb Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:42:54 -0400 Subject: [PATCH 58/68] [TLA] Implement Saber-Tooth Moose-Lion --- .../src/mage/cards/s/SaberToothMooseLion.java | 42 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 43 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SaberToothMooseLion.java diff --git a/Mage.Sets/src/mage/cards/s/SaberToothMooseLion.java b/Mage.Sets/src/mage/cards/s/SaberToothMooseLion.java new file mode 100644 index 00000000000..1b88e2c992c --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SaberToothMooseLion.java @@ -0,0 +1,42 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.ForestcyclingAbility; +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 SaberToothMooseLion extends CardImpl { + + public SaberToothMooseLion(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); + + this.subtype.add(SubType.ELK); + this.subtype.add(SubType.CAT); + this.power = new MageInt(7); + this.toughness = new MageInt(7); + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // Forestcycling {2} + this.addAbility(new ForestcyclingAbility(new ManaCostsImpl<>("{2}"))); + } + + private SaberToothMooseLion(final SaberToothMooseLion card) { + super(card); + } + + @Override + public SaberToothMooseLion copy() { + return new SaberToothMooseLion(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index de92b5e4c72..c54d77c53d0 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("Plains", 287, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); 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)); 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)); cards.add(new SetCardInfo("Sokka, Bold Boomeranger", 383, Rarity.RARE, mage.cards.s.SokkaBoldBoomeranger.class, NON_FULL_USE_VARIOUS)); From 8ff46a2b40b82d7410aa3dba7b89a690ba76850d Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:44:01 -0400 Subject: [PATCH 59/68] [TLA] Implement Pretending Poxbearers --- .../mage/cards/p/PretendingPoxbearers.java | 40 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 41 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PretendingPoxbearers.java diff --git a/Mage.Sets/src/mage/cards/p/PretendingPoxbearers.java b/Mage.Sets/src/mage/cards/p/PretendingPoxbearers.java new file mode 100644 index 00000000000..8c63e454914 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PretendingPoxbearers.java @@ -0,0 +1,40 @@ +package mage.cards.p; + +import mage.MageInt; +import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +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 PretendingPoxbearers extends CardImpl { + + public PretendingPoxbearers(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W/B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CITIZEN); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // When this creature dies, create a 1/1 white Ally creature token. + this.addAbility(new DiesSourceTriggeredAbility(new CreateTokenEffect(new AllyToken()))); + } + + private PretendingPoxbearers(final PretendingPoxbearers card) { + super(card); + } + + @Override + public PretendingPoxbearers copy() { + return new PretendingPoxbearers(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index c54d77c53d0..211ee5c6028 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -69,6 +69,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("Mountain", 290, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); 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("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)); From b457a2e5594e0af0be4757372e2031d3b19977a8 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:45:17 -0400 Subject: [PATCH 60/68] [TLA] Implement Ozai's Cruelty --- Mage.Sets/src/mage/cards/o/OzaisCruelty.java | 37 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 38 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/o/OzaisCruelty.java diff --git a/Mage.Sets/src/mage/cards/o/OzaisCruelty.java b/Mage.Sets/src/mage/cards/o/OzaisCruelty.java new file mode 100644 index 00000000000..eecca5ff057 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OzaisCruelty.java @@ -0,0 +1,37 @@ +package mage.cards.o; + +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.TargetPlayer; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class OzaisCruelty extends CardImpl { + + public OzaisCruelty(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}"); + + this.subtype.add(SubType.LESSON); + + // Ozai's Cruelty deals 2 damage to target player. That player discards two cards. + this.getSpellAbility().addEffect(new DamageTargetEffect(2)); + this.getSpellAbility().addEffect(new DiscardTargetEffect(2).setText("That player discards two cards")); + this.getSpellAbility().addTarget(new TargetPlayer()); + } + + private OzaisCruelty(final OzaisCruelty card) { + super(card); + } + + @Override + public OzaisCruelty copy() { + return new OzaisCruelty(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 211ee5c6028..e1b4d9f535f 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -68,6 +68,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("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)); cards.add(new SetCardInfo("Pretending Poxbearers", 237, Rarity.COMMON, mage.cards.p.PretendingPoxbearers.class)); cards.add(new SetCardInfo("Redirect Lightning", 151, Rarity.RARE, mage.cards.r.RedirectLightning.class, NON_FULL_USE_VARIOUS)); From 5b2944a2139c5eeca2e287a050fd79c3dc3d729f Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:46:15 -0400 Subject: [PATCH 61/68] [TLA] Implement It'll Quench Ya! --- Mage.Sets/src/mage/cards/i/ItllQuenchYa.java | 36 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 37 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/ItllQuenchYa.java diff --git a/Mage.Sets/src/mage/cards/i/ItllQuenchYa.java b/Mage.Sets/src/mage/cards/i/ItllQuenchYa.java new file mode 100644 index 00000000000..8564c1ce5ea --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/ItllQuenchYa.java @@ -0,0 +1,36 @@ +package mage.cards.i; + +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.CounterUnlessPaysEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.TargetSpell; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ItllQuenchYa extends CardImpl { + + public ItllQuenchYa(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); + + this.subtype.add(SubType.LESSON); + + // Counter target spell unless its controller pays {2}. + this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new GenericManaCost(2))); + this.getSpellAbility().addTarget(new TargetSpell()); + } + + private ItllQuenchYa(final ItllQuenchYa card) { + super(card); + } + + @Override + public ItllQuenchYa copy() { + return new ItllQuenchYa(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index e1b4d9f535f..0a7e76378f5 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("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("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("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 4286704c5a28e3c5cbe020c9215c59654826fbe8 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:46:40 -0400 Subject: [PATCH 62/68] [TLA] Implement Iguana Parrot --- Mage.Sets/src/mage/cards/i/IguanaParrot.java | 46 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/IguanaParrot.java diff --git a/Mage.Sets/src/mage/cards/i/IguanaParrot.java b/Mage.Sets/src/mage/cards/i/IguanaParrot.java new file mode 100644 index 00000000000..ad7c9131c72 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IguanaParrot.java @@ -0,0 +1,46 @@ +package mage.cards.i; + +import mage.MageInt; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.ProwessAbility; +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 IguanaParrot extends CardImpl { + + public IguanaParrot(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.LIZARD); + this.subtype.add(SubType.BIRD); + this.subtype.add(SubType.PIRATE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Prowess + this.addAbility(new ProwessAbility()); + } + + private IguanaParrot(final IguanaParrot card) { + super(card); + } + + @Override + public IguanaParrot copy() { + return new IguanaParrot(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 0a7e76378f5..678b8510aac 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("Forest", 291, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); 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("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("Katara, Water Tribe's Hope", 231, Rarity.RARE, mage.cards.k.KataraWaterTribesHope.class, NON_FULL_USE_VARIOUS)); From f293ff51d9a263d832935d7d5331132fe93a8b96 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:47:14 -0400 Subject: [PATCH 63/68] [TLA] Implement Glider Kids --- Mage.Sets/src/mage/cards/g/GliderKids.java | 43 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 44 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GliderKids.java diff --git a/Mage.Sets/src/mage/cards/g/GliderKids.java b/Mage.Sets/src/mage/cards/g/GliderKids.java new file mode 100644 index 00000000000..aa5785f7dae --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GliderKids.java @@ -0,0 +1,43 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.keyword.ScryEffect; +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 GliderKids extends CardImpl { + + public GliderKids(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.PILOT); + this.subtype.add(SubType.ALLY); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When this creature enters, scry 1. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ScryEffect(1))); + } + + private GliderKids(final GliderKids card) { + super(card); + } + + @Override + public GliderKids copy() { + return new GliderKids(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 678b8510aac..01380ecbce6 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("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)); cards.add(new SetCardInfo("Heartless Act", 103, Rarity.UNCOMMON, mage.cards.h.HeartlessAct.class)); cards.add(new SetCardInfo("Iguana Parrot", 56, Rarity.COMMON, mage.cards.i.IguanaParrot.class)); From 5bede15130b0d50a7b3dfa4647b56c13e57b5d38 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Thu, 14 Aug 2025 22:49:06 -0400 Subject: [PATCH 64/68] [TLA] Implement Yuyan Archers --- Mage.Sets/src/mage/cards/y/YuyanArchers.java | 46 +++++++++++++++++++ .../src/mage/sets/AvatarTheLastAirbender.java | 1 + 2 files changed, 47 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/y/YuyanArchers.java diff --git a/Mage.Sets/src/mage/cards/y/YuyanArchers.java b/Mage.Sets/src/mage/cards/y/YuyanArchers.java new file mode 100644 index 00000000000..ef4bb7af854 --- /dev/null +++ b/Mage.Sets/src/mage/cards/y/YuyanArchers.java @@ -0,0 +1,46 @@ +package mage.cards.y; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +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 YuyanArchers extends CardImpl { + + public YuyanArchers(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ARCHER); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // When this creature enters, you may discard a card. If you do, draw a card. + this.addAbility(new EntersBattlefieldTriggeredAbility( + new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new DiscardCardCost()) + )); + } + + private YuyanArchers(final YuyanArchers card) { + super(card); + } + + @Override + public YuyanArchers copy() { + return new YuyanArchers(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 01380ecbce6..2362c1b005b 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("Toph, the First Metalbender", 362, Rarity.RARE, mage.cards.t.TophTheFirstMetalbender.class, NON_FULL_USE_VARIOUS)); 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)); cards.add(new SetCardInfo("Zuko, Exiled Prince", 163, Rarity.UNCOMMON, mage.cards.z.ZukoExiledPrince.class)); cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName())); From aa1915cd131ca2d0ac01969b2a47c5c221224502 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Fri, 15 Aug 2025 08:14:51 +0400 Subject: [PATCH 65/68] deck: added old promo sets with boosters: Renaissance and Rinascimento (close #13906); --- .../dl/sources/ScryfallImageSupportCards.java | 2 + Mage.Sets/src/mage/sets/Renaissance.java | 152 ++++++++++++++++++ Mage.Sets/src/mage/sets/Rinascimento.java | 99 ++++++++++++ .../java/mage/verify/VerifyCardDataTest.java | 1 + 4 files changed, 254 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/Renaissance.java create mode 100644 Mage.Sets/src/mage/sets/Rinascimento.java diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java index 2e0cb302e98..e91491d577f 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java @@ -28,6 +28,8 @@ public class ScryfallImageSupportCards { add("2ED"); // Unlimited Edition //add("CEI"); // Intl. Collectors’ Edition //add("CED"); // Collectors’ Edition + add("RIN"); // Rinascimento + add("REN"); // Renaissance add("ARN"); // Arabian Nights add("ATQ"); // Antiquities //add("FBB"); // Foreign Black Border diff --git a/Mage.Sets/src/mage/sets/Renaissance.java b/Mage.Sets/src/mage/sets/Renaissance.java new file mode 100644 index 00000000000..037abc04598 --- /dev/null +++ b/Mage.Sets/src/mage/sets/Renaissance.java @@ -0,0 +1,152 @@ +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * German and French versions of Renaissance + *

+ * https://scryfall.com/sets/rin + * https://mtg.wiki/page/Renaissance + * + * @author JayDi85 + */ +public final class Renaissance extends ExpansionSet { + + private static final Renaissance instance = new Renaissance(); + + public static Renaissance getInstance() { + return instance; + } + + private Renaissance() { + super("Renaissance", "REN", ExpansionSet.buildDate(1995, 8, 1), SetType.SUPPLEMENTAL); + this.hasBasicLands = true; + + this.enableCollectorBooster(Integer.MAX_VALUE, 0, 6, 2, 0); + + cards.add(new SetCardInfo("Abomination", 46, Rarity.UNCOMMON, mage.cards.a.Abomination.class)); + cards.add(new SetCardInfo("Alabaster Potion", 2, Rarity.COMMON, mage.cards.a.AlabasterPotion.class)); + cards.add(new SetCardInfo("Ali Baba", 71, Rarity.UNCOMMON, mage.cards.a.AliBaba.class)); + cards.add(new SetCardInfo("Amrou Kithkin", 3, Rarity.COMMON, mage.cards.a.AmrouKithkin.class)); + cards.add(new SetCardInfo("Amulet of Kroog", 99, Rarity.COMMON, mage.cards.a.AmuletOfKroog.class)); + cards.add(new SetCardInfo("Angry Mob", 4, Rarity.UNCOMMON, mage.cards.a.AngryMob.class)); + cards.add(new SetCardInfo("Apprentice Wizard", 23, Rarity.UNCOMMON, mage.cards.a.ApprenticeWizard.class)); + cards.add(new SetCardInfo("Ashes to Ashes", 47, Rarity.COMMON, mage.cards.a.AshesToAshes.class)); + cards.add(new SetCardInfo("Ashnod's Battle Gear", 104, Rarity.UNCOMMON, mage.cards.a.AshnodsBattleGear.class)); + cards.add(new SetCardInfo("Backfire", 24, Rarity.UNCOMMON, mage.cards.b.Backfire.class)); + cards.add(new SetCardInfo("Ball Lightning", 73, Rarity.UNCOMMON, mage.cards.b.BallLightning.class)); + cards.add(new SetCardInfo("Battering Ram", 107, Rarity.COMMON, mage.cards.b.BatteringRam.class)); + cards.add(new SetCardInfo("Bird Maiden", 74, Rarity.COMMON, mage.cards.b.BirdMaiden.class)); + cards.add(new SetCardInfo("Black Mana Battery", 108, Rarity.UNCOMMON, mage.cards.b.BlackManaBattery.class)); + cards.add(new SetCardInfo("Blight", 48, Rarity.UNCOMMON, mage.cards.b.Blight.class)); + cards.add(new SetCardInfo("Blood Lust", 75, Rarity.UNCOMMON, mage.cards.b.BloodLust.class)); + cards.add(new SetCardInfo("Blue Mana Battery", 112, Rarity.UNCOMMON, mage.cards.b.BlueManaBattery.class)); + cards.add(new SetCardInfo("Bog Imp", 49, Rarity.COMMON, mage.cards.b.BogImp.class)); + cards.add(new SetCardInfo("Brainwash", 6, Rarity.COMMON, mage.cards.b.Brainwash.class)); + //cards.add(new SetCardInfo("Bronze Tablet", 115, Rarity.UNCOMMON, mage.cards.b.BronzeTablet.class)); + cards.add(new SetCardInfo("Brothers of Fire", 76, Rarity.UNCOMMON, mage.cards.b.BrothersOfFire.class)); + cards.add(new SetCardInfo("Carnivorous Plant", 117, Rarity.COMMON, mage.cards.c.CarnivorousPlant.class)); + cards.add(new SetCardInfo("Carrion Ants", 51, Rarity.UNCOMMON, mage.cards.c.CarrionAnts.class)); + cards.add(new SetCardInfo("Cave People", 78, Rarity.UNCOMMON, mage.cards.c.CavePeople.class)); + cards.add(new SetCardInfo("Circle of Protection: Artifacts", 7, Rarity.UNCOMMON, mage.cards.c.CircleOfProtectionArtifacts.class)); + cards.add(new SetCardInfo("Clay Statue", 120, Rarity.COMMON, mage.cards.c.ClayStatue.class)); + cards.add(new SetCardInfo("Clockwork Avian", 122, Rarity.UNCOMMON, mage.cards.c.ClockworkAvian.class)); + cards.add(new SetCardInfo("Colossus of Sardia", 123, Rarity.UNCOMMON, mage.cards.c.ColossusOfSardia.class)); + cards.add(new SetCardInfo("Coral Helm", 124, Rarity.UNCOMMON, mage.cards.c.CoralHelm.class)); + cards.add(new SetCardInfo("Cosmic Horror", 52, Rarity.UNCOMMON, mage.cards.c.CosmicHorror.class)); + cards.add(new SetCardInfo("Crimson Manticore", 80, Rarity.UNCOMMON, mage.cards.c.CrimsonManticore.class)); + cards.add(new SetCardInfo("Cursed Rack", 126, Rarity.COMMON, mage.cards.c.CursedRack.class)); + cards.add(new SetCardInfo("Cyclopean Mummy", 54, Rarity.COMMON, mage.cards.c.CyclopeanMummy.class)); + cards.add(new SetCardInfo("Detonate", 83, Rarity.UNCOMMON, mage.cards.d.Detonate.class)); + cards.add(new SetCardInfo("Diabolic Machine", 129, Rarity.UNCOMMON, mage.cards.d.DiabolicMachine.class)); + cards.add(new SetCardInfo("Divine Transformation", 8, Rarity.UNCOMMON, mage.cards.d.DivineTransformation.class)); + cards.add(new SetCardInfo("Durkwood Boars", 131, Rarity.COMMON, mage.cards.d.DurkwoodBoars.class)); + cards.add(new SetCardInfo("Elder Land Wurm", 9, Rarity.UNCOMMON, mage.cards.e.ElderLandWurm.class)); + cards.add(new SetCardInfo("Elven Riders", 133, Rarity.UNCOMMON, mage.cards.e.ElvenRiders.class)); + cards.add(new SetCardInfo("Energy Tap", 28, Rarity.COMMON, mage.cards.e.EnergyTap.class)); + cards.add(new SetCardInfo("Erosion", 29, Rarity.COMMON, mage.cards.e.Erosion.class)); + cards.add(new SetCardInfo("Eternal Warrior", 84, Rarity.UNCOMMON, mage.cards.e.EternalWarrior.class)); + cards.add(new SetCardInfo("Fellwar Stone", 136, Rarity.UNCOMMON, mage.cards.f.FellwarStone.class)); + cards.add(new SetCardInfo("Fissure", 85, Rarity.COMMON, mage.cards.f.Fissure.class)); + cards.add(new SetCardInfo("Flood", 30, Rarity.UNCOMMON, mage.cards.f.Flood.class)); + cards.add(new SetCardInfo("Fortified Area", 11, Rarity.UNCOMMON, mage.cards.f.FortifiedArea.class)); + cards.add(new SetCardInfo("Gaseous Form", 32, Rarity.COMMON, mage.cards.g.GaseousForm.class)); + cards.add(new SetCardInfo("Ghost Ship", 33, Rarity.COMMON, mage.cards.g.GhostShip.class)); + cards.add(new SetCardInfo("Giant Strength", 86, Rarity.COMMON, mage.cards.g.GiantStrength.class)); + cards.add(new SetCardInfo("Giant Tortoise", 34, Rarity.COMMON, mage.cards.g.GiantTortoise.class)); + cards.add(new SetCardInfo("Goblin Rock Sled", 87, Rarity.COMMON, mage.cards.g.GoblinRockSled.class)); + cards.add(new SetCardInfo("Grapeshot Catapult", 143, Rarity.COMMON, mage.cards.g.GrapeshotCatapult.class)); + cards.add(new SetCardInfo("Greed", 56, Rarity.UNCOMMON, mage.cards.g.Greed.class)); + cards.add(new SetCardInfo("Green Mana Battery", 145, Rarity.UNCOMMON, mage.cards.g.GreenManaBattery.class)); + cards.add(new SetCardInfo("Hurr Jackal", 88, Rarity.COMMON, mage.cards.h.HurrJackal.class)); + cards.add(new SetCardInfo("Immolation", 89, Rarity.COMMON, mage.cards.i.Immolation.class)); + cards.add(new SetCardInfo("Inferno", 90, Rarity.UNCOMMON, mage.cards.i.Inferno.class)); + cards.add(new SetCardInfo("Ironclaw Orcs", 91, Rarity.COMMON, mage.cards.i.IronclawOrcs.class)); + cards.add(new SetCardInfo("Junun Efreet", 57, Rarity.UNCOMMON, mage.cards.j.JununEfreet.class)); + cards.add(new SetCardInfo("Killer Bees", 146, Rarity.UNCOMMON, mage.cards.k.KillerBees.class)); + cards.add(new SetCardInfo("Kismet", 12, Rarity.UNCOMMON, mage.cards.k.Kismet.class)); + cards.add(new SetCardInfo("Land Leeches", 147, Rarity.COMMON, mage.cards.l.LandLeeches.class)); + cards.add(new SetCardInfo("Land Tax", 13, Rarity.UNCOMMON, mage.cards.l.LandTax.class)); + cards.add(new SetCardInfo("Leviathan", 36, Rarity.UNCOMMON, mage.cards.l.Leviathan.class)); + cards.add(new SetCardInfo("Lost Soul", 58, Rarity.COMMON, mage.cards.l.LostSoul.class)); + cards.add(new SetCardInfo("Mana Clash", 92, Rarity.UNCOMMON, mage.cards.m.ManaClash.class)); + cards.add(new SetCardInfo("Marsh Gas", 59, Rarity.COMMON, mage.cards.m.MarshGas.class)); + cards.add(new SetCardInfo("Marsh Viper", 149, Rarity.COMMON, mage.cards.m.MarshViper.class)); + cards.add(new SetCardInfo("Mind Bomb", 37, Rarity.UNCOMMON, mage.cards.m.MindBomb.class)); + cards.add(new SetCardInfo("Mishra's Factory", 187, Rarity.UNCOMMON, mage.cards.m.MishrasFactory.class)); + cards.add(new SetCardInfo("Morale", 15, Rarity.COMMON, mage.cards.m.Morale.class)); + cards.add(new SetCardInfo("Murk Dwellers", 62, Rarity.COMMON, mage.cards.m.MurkDwellers.class)); + cards.add(new SetCardInfo("Nafs Asp", 151, Rarity.COMMON, mage.cards.n.NafsAsp.class)); + cards.add(new SetCardInfo("Oasis", 188, Rarity.UNCOMMON, mage.cards.o.Oasis.class)); + cards.add(new SetCardInfo("Osai Vultures", 16, Rarity.COMMON, mage.cards.o.OsaiVultures.class)); + cards.add(new SetCardInfo("Piety", 17, Rarity.COMMON, mage.cards.p.Piety.class)); + cards.add(new SetCardInfo("Pikemen", 18, Rarity.COMMON, mage.cards.p.Pikemen.class)); + cards.add(new SetCardInfo("Pit Scorpion", 63, Rarity.COMMON, mage.cards.p.PitScorpion.class)); + cards.add(new SetCardInfo("Pradesh Gypsies", 152, Rarity.UNCOMMON, mage.cards.p.PradeshGypsies.class)); + cards.add(new SetCardInfo("Psionic Entity", 38, Rarity.UNCOMMON, mage.cards.p.PsionicEntity.class)); + cards.add(new SetCardInfo("Pyrotechnics", 93, Rarity.COMMON, mage.cards.p.Pyrotechnics.class)); + cards.add(new SetCardInfo("Radjan Spirit", 153, Rarity.UNCOMMON, mage.cards.r.RadjanSpirit.class)); + cards.add(new SetCardInfo("Rag Man", 64, Rarity.UNCOMMON, mage.cards.r.RagMan.class)); + //cards.add(new SetCardInfo("Rebirth", 154, Rarity.UNCOMMON, mage.cards.r.Rebirth.class)); + cards.add(new SetCardInfo("Red Mana Battery", 155, Rarity.UNCOMMON, mage.cards.r.RedManaBattery.class)); + cards.add(new SetCardInfo("Relic Bind", 39, Rarity.UNCOMMON, mage.cards.r.RelicBind.class)); + cards.add(new SetCardInfo("Sandstorm", 156, Rarity.COMMON, mage.cards.s.Sandstorm.class)); + cards.add(new SetCardInfo("Seeker", 19, Rarity.UNCOMMON, mage.cards.s.Seeker.class)); + cards.add(new SetCardInfo("Segovian Leviathan", 40, Rarity.UNCOMMON, mage.cards.s.SegovianLeviathan.class)); + cards.add(new SetCardInfo("Shapeshifter", 157, Rarity.UNCOMMON, mage.cards.s.Shapeshifter.class)); + cards.add(new SetCardInfo("Sindbad", 41, Rarity.UNCOMMON, mage.cards.s.Sindbad.class)); + cards.add(new SetCardInfo("Sisters of the Flame", 94, Rarity.UNCOMMON, mage.cards.s.SistersOfTheFlame.class)); + cards.add(new SetCardInfo("Spirit Link", 20, Rarity.UNCOMMON, mage.cards.s.SpiritLink.class)); + cards.add(new SetCardInfo("Spirit Shackle", 65, Rarity.COMMON, mage.cards.s.SpiritShackle.class)); + cards.add(new SetCardInfo("Strip Mine", 189, Rarity.UNCOMMON, mage.cards.s.StripMine.class)); + cards.add(new SetCardInfo("Sunken City", 42, Rarity.COMMON, mage.cards.s.SunkenCity.class)); + cards.add(new SetCardInfo("Sylvan Library", 158, Rarity.UNCOMMON, mage.cards.s.SylvanLibrary.class)); + cards.add(new SetCardInfo("Tawnos's Wand", 159, Rarity.UNCOMMON, mage.cards.t.TawnossWand.class)); + cards.add(new SetCardInfo("Tawnos's Weaponry", 160, Rarity.UNCOMMON, mage.cards.t.TawnossWeaponry.class)); + //cards.add(new SetCardInfo("Tempest Efreet", 95, Rarity.UNCOMMON, mage.cards.t.TempestEfreet.class)); + cards.add(new SetCardInfo("Tetravus", 161, Rarity.UNCOMMON, mage.cards.t.Tetravus.class)); + cards.add(new SetCardInfo("The Brute", 96, Rarity.COMMON, mage.cards.t.TheBrute.class)); + cards.add(new SetCardInfo("Time Elemental", 43, Rarity.UNCOMMON, mage.cards.t.TimeElemental.class)); + cards.add(new SetCardInfo("Triskelion", 162, Rarity.UNCOMMON, mage.cards.t.Triskelion.class)); + cards.add(new SetCardInfo("Tundra Wolves", 21, Rarity.COMMON, mage.cards.t.TundraWolves.class)); + cards.add(new SetCardInfo("Twiddle", 44, Rarity.COMMON, mage.cards.t.Twiddle.class)); + cards.add(new SetCardInfo("Uncle Istvan", 66, Rarity.UNCOMMON, mage.cards.u.UncleIstvan.class)); + cards.add(new SetCardInfo("Untamed Wilds", 163, Rarity.UNCOMMON, mage.cards.u.UntamedWilds.class)); + cards.add(new SetCardInfo("Urza's Avenger", 164, Rarity.UNCOMMON, mage.cards.u.UrzasAvenger.class)); + cards.add(new SetCardInfo("Vampire Bats", 67, Rarity.COMMON, mage.cards.v.VampireBats.class)); + cards.add(new SetCardInfo("Venom", 165, Rarity.COMMON, mage.cards.v.Venom.class)); + cards.add(new SetCardInfo("Visions", 22, Rarity.UNCOMMON, mage.cards.v.Visions.class)); + cards.add(new SetCardInfo("Wall of Dust", 97, Rarity.UNCOMMON, mage.cards.w.WallOfDust.class)); + cards.add(new SetCardInfo("Wall of Spears", 166, Rarity.UNCOMMON, mage.cards.w.WallOfSpears.class)); + cards.add(new SetCardInfo("Whirling Dervish", 167, Rarity.UNCOMMON, mage.cards.w.WhirlingDervish.class)); + cards.add(new SetCardInfo("White Mana Battery", 168, Rarity.UNCOMMON, mage.cards.w.WhiteManaBattery.class)); + cards.add(new SetCardInfo("Winds of Change", 98, Rarity.UNCOMMON, mage.cards.w.WindsOfChange.class)); + cards.add(new SetCardInfo("Winter Blast", 169, Rarity.UNCOMMON, mage.cards.w.WinterBlast.class)); + cards.add(new SetCardInfo("Word of Binding", 68, Rarity.COMMON, mage.cards.w.WordOfBinding.class)); + cards.add(new SetCardInfo("Xenic Poltergeist", 69, Rarity.UNCOMMON, mage.cards.x.XenicPoltergeist.class)); + cards.add(new SetCardInfo("Yotian Soldier", 170, Rarity.COMMON, mage.cards.y.YotianSoldier.class)); + cards.add(new SetCardInfo("Zephyr Falcon", 45, Rarity.COMMON, mage.cards.z.ZephyrFalcon.class)); + } +} diff --git a/Mage.Sets/src/mage/sets/Rinascimento.java b/Mage.Sets/src/mage/sets/Rinascimento.java new file mode 100644 index 00000000000..b2ebbd0e8d2 --- /dev/null +++ b/Mage.Sets/src/mage/sets/Rinascimento.java @@ -0,0 +1,99 @@ +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * Italian version of Renaissance + *

+ * https://scryfall.com/sets/ren + * https://mtg.wiki/page/Renaissance + * + * @author JayDi85 + */ +public final class Rinascimento extends ExpansionSet { + + private static final Rinascimento instance = new Rinascimento(); + + public static Rinascimento getInstance() { + return instance; + } + + private Rinascimento() { + super("Rinascimento", "RIN", ExpansionSet.buildDate(1995, 8, 1), SetType.SUPPLEMENTAL); + this.hasBasicLands = true; + + this.enableCollectorBooster(Integer.MAX_VALUE, 0, 6, 2, 0); + + cards.add(new SetCardInfo("Abu Ja'far", 1, Rarity.UNCOMMON, mage.cards.a.AbuJafar.class)); + cards.add(new SetCardInfo("Aladdin", 70, Rarity.UNCOMMON, mage.cards.a.Aladdin.class)); + cards.add(new SetCardInfo("Ali Baba", 71, Rarity.UNCOMMON, mage.cards.a.AliBaba.class)); + cards.add(new SetCardInfo("Amulet of Kroog", 99, Rarity.COMMON, mage.cards.a.AmuletOfKroog.class)); + cards.add(new SetCardInfo("Argothian Pixies", 100, Rarity.COMMON, mage.cards.a.ArgothianPixies.class)); + cards.add(new SetCardInfo("Ashnod's Altar", 101, Rarity.UNCOMMON, mage.cards.a.AshnodsAltar.class)); + cards.add(new SetCardInfo("Ashnod's Battle Gear", 102, Rarity.UNCOMMON, mage.cards.a.AshnodsBattleGear.class)); + cards.add(new SetCardInfo("Ashnod's Transmogrant", 103, Rarity.UNCOMMON, mage.cards.a.AshnodsTransmogrant.class)); + cards.add(new SetCardInfo("Battering Ram", 105, Rarity.COMMON, mage.cards.b.BatteringRam.class)); + cards.add(new SetCardInfo("Bird Maiden", 72, Rarity.COMMON, mage.cards.b.BirdMaiden.class)); + //cards.add(new SetCardInfo("Bronze Tablet", 106, Rarity.UNCOMMON, mage.cards.b.BronzeTablet.class)); + cards.add(new SetCardInfo("Circle of Protection: Artifacts", 5, Rarity.UNCOMMON, mage.cards.c.CircleOfProtectionArtifacts.class)); + cards.add(new SetCardInfo("City of Brass", 171, Rarity.UNCOMMON, mage.cards.c.CityOfBrass.class)); + cards.add(new SetCardInfo("Clay Statue", 109, Rarity.COMMON, mage.cards.c.ClayStatue.class)); + cards.add(new SetCardInfo("Clockwork Avian", 110, Rarity.UNCOMMON, mage.cards.c.ClockworkAvian.class)); + cards.add(new SetCardInfo("Colossus of Sardia", 111, Rarity.UNCOMMON, mage.cards.c.ColossusOfSardia.class)); + cards.add(new SetCardInfo("Coral Helm", 113, Rarity.UNCOMMON, mage.cards.c.CoralHelm.class)); + cards.add(new SetCardInfo("Cuombajj Witches", 50, Rarity.COMMON, mage.cards.c.CuombajjWitches.class)); + cards.add(new SetCardInfo("Cursed Rack", 114, Rarity.COMMON, mage.cards.c.CursedRack.class)); + cards.add(new SetCardInfo("Cyclone", 116, Rarity.UNCOMMON, mage.cards.c.Cyclone.class)); + cards.add(new SetCardInfo("Dandan", 25, Rarity.COMMON, mage.cards.d.Dandan.class)); + cards.add(new SetCardInfo("Detonate", 77, Rarity.UNCOMMON, mage.cards.d.Detonate.class)); + cards.add(new SetCardInfo("Erhnam Djinn", 118, Rarity.UNCOMMON, mage.cards.e.ErhnamDjinn.class)); + cards.add(new SetCardInfo("Feldon's Cane", 119, Rarity.COMMON, mage.cards.f.FeldonsCane.class)); + cards.add(new SetCardInfo("Fishliver Oil", 26, Rarity.COMMON, mage.cards.f.FishliverOil.class)); + cards.add(new SetCardInfo("Ghazban Ogre", 121, Rarity.COMMON, mage.cards.g.GhazbanOgre.class)); + cards.add(new SetCardInfo("Giant Tortoise", 27, Rarity.COMMON, mage.cards.g.GiantTortoise.class)); + cards.add(new SetCardInfo("Goblin Artisans", 79, Rarity.UNCOMMON, mage.cards.g.GoblinArtisans.class)); + cards.add(new SetCardInfo("Grapeshot Catapult", 125, Rarity.COMMON, mage.cards.g.GrapeshotCatapult.class)); + cards.add(new SetCardInfo("Hasran Ogress", 53, Rarity.COMMON, mage.cards.h.HasranOgress.class)); + cards.add(new SetCardInfo("Hurr Jackal", 81, Rarity.COMMON, mage.cards.h.HurrJackal.class)); + cards.add(new SetCardInfo("Ironclaw Orcs", 82, Rarity.COMMON, mage.cards.i.IronclawOrcs.class)); + cards.add(new SetCardInfo("Jalum Tome", 127, Rarity.UNCOMMON, mage.cards.j.JalumTome.class)); + //cards.add(new SetCardInfo("Jeweled Bird", 128, Rarity.UNCOMMON, mage.cards.j.JeweledBird.class)); + cards.add(new SetCardInfo("Junun Efreet", 55, Rarity.UNCOMMON, mage.cards.j.JununEfreet.class)); + cards.add(new SetCardInfo("Metamorphosis", 130, Rarity.COMMON, mage.cards.m.Metamorphosis.class)); + cards.add(new SetCardInfo("Mishra's Factory", 172, Rarity.UNCOMMON, mage.cards.m.MishrasFactory.class)); + cards.add(new SetCardInfo("Nafs Asp", 132, Rarity.COMMON, mage.cards.n.NafsAsp.class)); + cards.add(new SetCardInfo("Oasis", 173, Rarity.UNCOMMON, mage.cards.o.Oasis.class)); + cards.add(new SetCardInfo("Obelisk of Undoing", 134, Rarity.UNCOMMON, mage.cards.o.ObeliskOfUndoing.class)); + cards.add(new SetCardInfo("Rakalite", 135, Rarity.UNCOMMON, mage.cards.r.Rakalite.class)); + cards.add(new SetCardInfo("Repentant Blacksmith", 10, Rarity.UNCOMMON, mage.cards.r.RepentantBlacksmith.class)); + cards.add(new SetCardInfo("Sandstorm", 137, Rarity.COMMON, mage.cards.s.Sandstorm.class)); + cards.add(new SetCardInfo("Shapeshifter", 138, Rarity.UNCOMMON, mage.cards.s.Shapeshifter.class)); + cards.add(new SetCardInfo("Sindbad", 31, Rarity.UNCOMMON, mage.cards.s.Sindbad.class)); + cards.add(new SetCardInfo("Strip Mine", 174, Rarity.UNCOMMON, mage.cards.s.StripMine.class)); + cards.add(new SetCardInfo("Tawnos's Wand", 139, Rarity.UNCOMMON, mage.cards.t.TawnossWand.class)); + cards.add(new SetCardInfo("Tawnos's Weaponry", 140, Rarity.UNCOMMON, mage.cards.t.TawnossWeaponry.class)); + cards.add(new SetCardInfo("Tetravus", 141, Rarity.UNCOMMON, mage.cards.t.Tetravus.class)); + cards.add(new SetCardInfo("Triskelion", 142, Rarity.UNCOMMON, mage.cards.t.Triskelion.class)); + cards.add(new SetCardInfo("Twiddle", 35, Rarity.COMMON, mage.cards.t.Twiddle.class)); + cards.add(new SetCardInfo("Urza's Avenger", 144, Rarity.UNCOMMON, mage.cards.u.UrzasAvenger.class)); + cards.add(new SetCardInfo("Urza's Mine", 175, Rarity.COMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Mine", 176, Rarity.COMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Mine", 177, Rarity.COMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Mine", 178, Rarity.COMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Power Plant", 179, Rarity.COMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Power Plant", 180, Rarity.COMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Power Plant", 181, Rarity.COMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Power Plant", 182, Rarity.COMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Tower", 183, Rarity.COMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Tower", 184, Rarity.COMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Tower", 185, Rarity.COMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Tower", 186, Rarity.COMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Wall of Spears", 148, Rarity.UNCOMMON, mage.cards.w.WallOfSpears.class)); + cards.add(new SetCardInfo("War Elephant", 14, Rarity.COMMON, mage.cards.w.WarElephant.class)); + cards.add(new SetCardInfo("Xenic Poltergeist", 60, Rarity.UNCOMMON, mage.cards.x.XenicPoltergeist.class)); + cards.add(new SetCardInfo("Yawgmoth Demon", 61, Rarity.UNCOMMON, mage.cards.y.YawgmothDemon.class)); + cards.add(new SetCardInfo("Yotian Soldier", 150, Rarity.COMMON, mage.cards.y.YotianSoldier.class)); + } +} diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index f7b6493ce98..d205547d0a7 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -1121,6 +1121,7 @@ public class VerifyCardDataTest { Set implementedSets = sets.stream().map(ExpansionSet::getCode).collect(Collectors.toSet()); MtgJsonService.sets().values().forEach(jsonSet -> { if (jsonSet.booster != null && !jsonSet.booster.isEmpty() && !implementedSets.contains(jsonSet.code)) { + // how-to fix: it's miss promo sets with boosters, so just add/generate it in most use cases errorsList.add(String.format("Error: missing set implementation (important for draft format) - %s - %s - boosters: %s", jsonSet.code, jsonSet.name, From 7644d1895cdd31b5a779ccf0c0c835d90828ed8b Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Fri, 15 Aug 2025 08:18:46 +0400 Subject: [PATCH 66/68] merge fix --- Mage.Sets/src/mage/sets/Renaissance.java | 2 +- Mage.Sets/src/mage/sets/Rinascimento.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Renaissance.java b/Mage.Sets/src/mage/sets/Renaissance.java index 037abc04598..ac0c6334772 100644 --- a/Mage.Sets/src/mage/sets/Renaissance.java +++ b/Mage.Sets/src/mage/sets/Renaissance.java @@ -7,7 +7,7 @@ import mage.constants.SetType; /** * German and French versions of Renaissance *

- * https://scryfall.com/sets/rin + * https://scryfall.com/sets/ren * https://mtg.wiki/page/Renaissance * * @author JayDi85 diff --git a/Mage.Sets/src/mage/sets/Rinascimento.java b/Mage.Sets/src/mage/sets/Rinascimento.java index b2ebbd0e8d2..b7b66201152 100644 --- a/Mage.Sets/src/mage/sets/Rinascimento.java +++ b/Mage.Sets/src/mage/sets/Rinascimento.java @@ -7,7 +7,7 @@ import mage.constants.SetType; /** * Italian version of Renaissance *

- * https://scryfall.com/sets/ren + * https://scryfall.com/sets/rin * https://mtg.wiki/page/Renaissance * * @author JayDi85 From bfe218dd05e3a1e9fd2e7bc92842884509916e4c Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Fri, 15 Aug 2025 08:41:15 +0400 Subject: [PATCH 67/68] tests: disabled randomly failed AI test --- .../Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java | 2 +- .../org/mage/test/AI/basic/SimulationPerformanceAITest.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java index 5ab8241d41c..24f62353adf 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java @@ -502,7 +502,7 @@ public class ComputerPlayer6 extends ComputerPlayer { } logger.warn("Possible freeze chain:"); if (root != null && chain.isEmpty()) { - logger.warn(" - unknown use case (too many possible targets?)"); // maybe can't finish any calc, maybe related to target options, I don't know + logger.warn(" - unknown use case (too many possible targets?)"); // maybe can't finish any calc, maybe related to target options } chain.forEach(s -> { logger.warn(" - " + s); diff --git a/Mage.Tests/src/test/java/org/mage/test/AI/basic/SimulationPerformanceAITest.java b/Mage.Tests/src/test/java/org/mage/test/AI/basic/SimulationPerformanceAITest.java index b0fd1385fc5..268335e360b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/AI/basic/SimulationPerformanceAITest.java +++ b/Mage.Tests/src/test/java/org/mage/test/AI/basic/SimulationPerformanceAITest.java @@ -216,6 +216,7 @@ public class SimulationPerformanceAITest extends CardTestPlayerBaseAI { } @Test + @Ignore // TODO: enable and fix random error with too many sim nodes (depends on machine performance?) public void test_ElderDeepFiend_TooManyUpToChoices() { // bug: game freeze with 100% CPU usage // https://github.com/magefree/mage/issues/9518 From 82a8d3655839d98bde4db3d9867535b7c85302e4 Mon Sep 17 00:00:00 2001 From: ReSech Date: Fri, 15 Aug 2025 15:12:47 +1000 Subject: [PATCH 68/68] images: fixed retro frame style for REN and RIN sets (#13908) --- Mage.Sets/src/mage/sets/Renaissance.java | 244 +++++++++++----------- Mage.Sets/src/mage/sets/Rinascimento.java | 138 ++++++------ 2 files changed, 191 insertions(+), 191 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Renaissance.java b/Mage.Sets/src/mage/sets/Renaissance.java index ac0c6334772..52fdb54e148 100644 --- a/Mage.Sets/src/mage/sets/Renaissance.java +++ b/Mage.Sets/src/mage/sets/Renaissance.java @@ -26,127 +26,127 @@ public final class Renaissance extends ExpansionSet { this.enableCollectorBooster(Integer.MAX_VALUE, 0, 6, 2, 0); - cards.add(new SetCardInfo("Abomination", 46, Rarity.UNCOMMON, mage.cards.a.Abomination.class)); - cards.add(new SetCardInfo("Alabaster Potion", 2, Rarity.COMMON, mage.cards.a.AlabasterPotion.class)); - cards.add(new SetCardInfo("Ali Baba", 71, Rarity.UNCOMMON, mage.cards.a.AliBaba.class)); - cards.add(new SetCardInfo("Amrou Kithkin", 3, Rarity.COMMON, mage.cards.a.AmrouKithkin.class)); - cards.add(new SetCardInfo("Amulet of Kroog", 99, Rarity.COMMON, mage.cards.a.AmuletOfKroog.class)); - cards.add(new SetCardInfo("Angry Mob", 4, Rarity.UNCOMMON, mage.cards.a.AngryMob.class)); - cards.add(new SetCardInfo("Apprentice Wizard", 23, Rarity.UNCOMMON, mage.cards.a.ApprenticeWizard.class)); - cards.add(new SetCardInfo("Ashes to Ashes", 47, Rarity.COMMON, mage.cards.a.AshesToAshes.class)); - cards.add(new SetCardInfo("Ashnod's Battle Gear", 104, Rarity.UNCOMMON, mage.cards.a.AshnodsBattleGear.class)); - cards.add(new SetCardInfo("Backfire", 24, Rarity.UNCOMMON, mage.cards.b.Backfire.class)); - cards.add(new SetCardInfo("Ball Lightning", 73, Rarity.UNCOMMON, mage.cards.b.BallLightning.class)); - cards.add(new SetCardInfo("Battering Ram", 107, Rarity.COMMON, mage.cards.b.BatteringRam.class)); - cards.add(new SetCardInfo("Bird Maiden", 74, Rarity.COMMON, mage.cards.b.BirdMaiden.class)); - cards.add(new SetCardInfo("Black Mana Battery", 108, Rarity.UNCOMMON, mage.cards.b.BlackManaBattery.class)); - cards.add(new SetCardInfo("Blight", 48, Rarity.UNCOMMON, mage.cards.b.Blight.class)); - cards.add(new SetCardInfo("Blood Lust", 75, Rarity.UNCOMMON, mage.cards.b.BloodLust.class)); - cards.add(new SetCardInfo("Blue Mana Battery", 112, Rarity.UNCOMMON, mage.cards.b.BlueManaBattery.class)); - cards.add(new SetCardInfo("Bog Imp", 49, Rarity.COMMON, mage.cards.b.BogImp.class)); - cards.add(new SetCardInfo("Brainwash", 6, Rarity.COMMON, mage.cards.b.Brainwash.class)); - //cards.add(new SetCardInfo("Bronze Tablet", 115, Rarity.UNCOMMON, mage.cards.b.BronzeTablet.class)); - cards.add(new SetCardInfo("Brothers of Fire", 76, Rarity.UNCOMMON, mage.cards.b.BrothersOfFire.class)); - cards.add(new SetCardInfo("Carnivorous Plant", 117, Rarity.COMMON, mage.cards.c.CarnivorousPlant.class)); - cards.add(new SetCardInfo("Carrion Ants", 51, Rarity.UNCOMMON, mage.cards.c.CarrionAnts.class)); - cards.add(new SetCardInfo("Cave People", 78, Rarity.UNCOMMON, mage.cards.c.CavePeople.class)); - cards.add(new SetCardInfo("Circle of Protection: Artifacts", 7, Rarity.UNCOMMON, mage.cards.c.CircleOfProtectionArtifacts.class)); - cards.add(new SetCardInfo("Clay Statue", 120, Rarity.COMMON, mage.cards.c.ClayStatue.class)); - cards.add(new SetCardInfo("Clockwork Avian", 122, Rarity.UNCOMMON, mage.cards.c.ClockworkAvian.class)); - cards.add(new SetCardInfo("Colossus of Sardia", 123, Rarity.UNCOMMON, mage.cards.c.ColossusOfSardia.class)); - cards.add(new SetCardInfo("Coral Helm", 124, Rarity.UNCOMMON, mage.cards.c.CoralHelm.class)); - cards.add(new SetCardInfo("Cosmic Horror", 52, Rarity.UNCOMMON, mage.cards.c.CosmicHorror.class)); - cards.add(new SetCardInfo("Crimson Manticore", 80, Rarity.UNCOMMON, mage.cards.c.CrimsonManticore.class)); - cards.add(new SetCardInfo("Cursed Rack", 126, Rarity.COMMON, mage.cards.c.CursedRack.class)); - cards.add(new SetCardInfo("Cyclopean Mummy", 54, Rarity.COMMON, mage.cards.c.CyclopeanMummy.class)); - cards.add(new SetCardInfo("Detonate", 83, Rarity.UNCOMMON, mage.cards.d.Detonate.class)); - cards.add(new SetCardInfo("Diabolic Machine", 129, Rarity.UNCOMMON, mage.cards.d.DiabolicMachine.class)); - cards.add(new SetCardInfo("Divine Transformation", 8, Rarity.UNCOMMON, mage.cards.d.DivineTransformation.class)); - cards.add(new SetCardInfo("Durkwood Boars", 131, Rarity.COMMON, mage.cards.d.DurkwoodBoars.class)); - cards.add(new SetCardInfo("Elder Land Wurm", 9, Rarity.UNCOMMON, mage.cards.e.ElderLandWurm.class)); - cards.add(new SetCardInfo("Elven Riders", 133, Rarity.UNCOMMON, mage.cards.e.ElvenRiders.class)); - cards.add(new SetCardInfo("Energy Tap", 28, Rarity.COMMON, mage.cards.e.EnergyTap.class)); - cards.add(new SetCardInfo("Erosion", 29, Rarity.COMMON, mage.cards.e.Erosion.class)); - cards.add(new SetCardInfo("Eternal Warrior", 84, Rarity.UNCOMMON, mage.cards.e.EternalWarrior.class)); - cards.add(new SetCardInfo("Fellwar Stone", 136, Rarity.UNCOMMON, mage.cards.f.FellwarStone.class)); - cards.add(new SetCardInfo("Fissure", 85, Rarity.COMMON, mage.cards.f.Fissure.class)); - cards.add(new SetCardInfo("Flood", 30, Rarity.UNCOMMON, mage.cards.f.Flood.class)); - cards.add(new SetCardInfo("Fortified Area", 11, Rarity.UNCOMMON, mage.cards.f.FortifiedArea.class)); - cards.add(new SetCardInfo("Gaseous Form", 32, Rarity.COMMON, mage.cards.g.GaseousForm.class)); - cards.add(new SetCardInfo("Ghost Ship", 33, Rarity.COMMON, mage.cards.g.GhostShip.class)); - cards.add(new SetCardInfo("Giant Strength", 86, Rarity.COMMON, mage.cards.g.GiantStrength.class)); - cards.add(new SetCardInfo("Giant Tortoise", 34, Rarity.COMMON, mage.cards.g.GiantTortoise.class)); - cards.add(new SetCardInfo("Goblin Rock Sled", 87, Rarity.COMMON, mage.cards.g.GoblinRockSled.class)); - cards.add(new SetCardInfo("Grapeshot Catapult", 143, Rarity.COMMON, mage.cards.g.GrapeshotCatapult.class)); - cards.add(new SetCardInfo("Greed", 56, Rarity.UNCOMMON, mage.cards.g.Greed.class)); - cards.add(new SetCardInfo("Green Mana Battery", 145, Rarity.UNCOMMON, mage.cards.g.GreenManaBattery.class)); - cards.add(new SetCardInfo("Hurr Jackal", 88, Rarity.COMMON, mage.cards.h.HurrJackal.class)); - cards.add(new SetCardInfo("Immolation", 89, Rarity.COMMON, mage.cards.i.Immolation.class)); - cards.add(new SetCardInfo("Inferno", 90, Rarity.UNCOMMON, mage.cards.i.Inferno.class)); - cards.add(new SetCardInfo("Ironclaw Orcs", 91, Rarity.COMMON, mage.cards.i.IronclawOrcs.class)); - cards.add(new SetCardInfo("Junun Efreet", 57, Rarity.UNCOMMON, mage.cards.j.JununEfreet.class)); - cards.add(new SetCardInfo("Killer Bees", 146, Rarity.UNCOMMON, mage.cards.k.KillerBees.class)); - cards.add(new SetCardInfo("Kismet", 12, Rarity.UNCOMMON, mage.cards.k.Kismet.class)); - cards.add(new SetCardInfo("Land Leeches", 147, Rarity.COMMON, mage.cards.l.LandLeeches.class)); - cards.add(new SetCardInfo("Land Tax", 13, Rarity.UNCOMMON, mage.cards.l.LandTax.class)); - cards.add(new SetCardInfo("Leviathan", 36, Rarity.UNCOMMON, mage.cards.l.Leviathan.class)); - cards.add(new SetCardInfo("Lost Soul", 58, Rarity.COMMON, mage.cards.l.LostSoul.class)); - cards.add(new SetCardInfo("Mana Clash", 92, Rarity.UNCOMMON, mage.cards.m.ManaClash.class)); - cards.add(new SetCardInfo("Marsh Gas", 59, Rarity.COMMON, mage.cards.m.MarshGas.class)); - cards.add(new SetCardInfo("Marsh Viper", 149, Rarity.COMMON, mage.cards.m.MarshViper.class)); - cards.add(new SetCardInfo("Mind Bomb", 37, Rarity.UNCOMMON, mage.cards.m.MindBomb.class)); - cards.add(new SetCardInfo("Mishra's Factory", 187, Rarity.UNCOMMON, mage.cards.m.MishrasFactory.class)); - cards.add(new SetCardInfo("Morale", 15, Rarity.COMMON, mage.cards.m.Morale.class)); - cards.add(new SetCardInfo("Murk Dwellers", 62, Rarity.COMMON, mage.cards.m.MurkDwellers.class)); - cards.add(new SetCardInfo("Nafs Asp", 151, Rarity.COMMON, mage.cards.n.NafsAsp.class)); - cards.add(new SetCardInfo("Oasis", 188, Rarity.UNCOMMON, mage.cards.o.Oasis.class)); - cards.add(new SetCardInfo("Osai Vultures", 16, Rarity.COMMON, mage.cards.o.OsaiVultures.class)); - cards.add(new SetCardInfo("Piety", 17, Rarity.COMMON, mage.cards.p.Piety.class)); - cards.add(new SetCardInfo("Pikemen", 18, Rarity.COMMON, mage.cards.p.Pikemen.class)); - cards.add(new SetCardInfo("Pit Scorpion", 63, Rarity.COMMON, mage.cards.p.PitScorpion.class)); - cards.add(new SetCardInfo("Pradesh Gypsies", 152, Rarity.UNCOMMON, mage.cards.p.PradeshGypsies.class)); - cards.add(new SetCardInfo("Psionic Entity", 38, Rarity.UNCOMMON, mage.cards.p.PsionicEntity.class)); - cards.add(new SetCardInfo("Pyrotechnics", 93, Rarity.COMMON, mage.cards.p.Pyrotechnics.class)); - cards.add(new SetCardInfo("Radjan Spirit", 153, Rarity.UNCOMMON, mage.cards.r.RadjanSpirit.class)); - cards.add(new SetCardInfo("Rag Man", 64, Rarity.UNCOMMON, mage.cards.r.RagMan.class)); - //cards.add(new SetCardInfo("Rebirth", 154, Rarity.UNCOMMON, mage.cards.r.Rebirth.class)); - cards.add(new SetCardInfo("Red Mana Battery", 155, Rarity.UNCOMMON, mage.cards.r.RedManaBattery.class)); - cards.add(new SetCardInfo("Relic Bind", 39, Rarity.UNCOMMON, mage.cards.r.RelicBind.class)); - cards.add(new SetCardInfo("Sandstorm", 156, Rarity.COMMON, mage.cards.s.Sandstorm.class)); - cards.add(new SetCardInfo("Seeker", 19, Rarity.UNCOMMON, mage.cards.s.Seeker.class)); - cards.add(new SetCardInfo("Segovian Leviathan", 40, Rarity.UNCOMMON, mage.cards.s.SegovianLeviathan.class)); - cards.add(new SetCardInfo("Shapeshifter", 157, Rarity.UNCOMMON, mage.cards.s.Shapeshifter.class)); - cards.add(new SetCardInfo("Sindbad", 41, Rarity.UNCOMMON, mage.cards.s.Sindbad.class)); - cards.add(new SetCardInfo("Sisters of the Flame", 94, Rarity.UNCOMMON, mage.cards.s.SistersOfTheFlame.class)); - cards.add(new SetCardInfo("Spirit Link", 20, Rarity.UNCOMMON, mage.cards.s.SpiritLink.class)); - cards.add(new SetCardInfo("Spirit Shackle", 65, Rarity.COMMON, mage.cards.s.SpiritShackle.class)); - cards.add(new SetCardInfo("Strip Mine", 189, Rarity.UNCOMMON, mage.cards.s.StripMine.class)); - cards.add(new SetCardInfo("Sunken City", 42, Rarity.COMMON, mage.cards.s.SunkenCity.class)); - cards.add(new SetCardInfo("Sylvan Library", 158, Rarity.UNCOMMON, mage.cards.s.SylvanLibrary.class)); - cards.add(new SetCardInfo("Tawnos's Wand", 159, Rarity.UNCOMMON, mage.cards.t.TawnossWand.class)); - cards.add(new SetCardInfo("Tawnos's Weaponry", 160, Rarity.UNCOMMON, mage.cards.t.TawnossWeaponry.class)); - //cards.add(new SetCardInfo("Tempest Efreet", 95, Rarity.UNCOMMON, mage.cards.t.TempestEfreet.class)); - cards.add(new SetCardInfo("Tetravus", 161, Rarity.UNCOMMON, mage.cards.t.Tetravus.class)); - cards.add(new SetCardInfo("The Brute", 96, Rarity.COMMON, mage.cards.t.TheBrute.class)); - cards.add(new SetCardInfo("Time Elemental", 43, Rarity.UNCOMMON, mage.cards.t.TimeElemental.class)); - cards.add(new SetCardInfo("Triskelion", 162, Rarity.UNCOMMON, mage.cards.t.Triskelion.class)); - cards.add(new SetCardInfo("Tundra Wolves", 21, Rarity.COMMON, mage.cards.t.TundraWolves.class)); - cards.add(new SetCardInfo("Twiddle", 44, Rarity.COMMON, mage.cards.t.Twiddle.class)); - cards.add(new SetCardInfo("Uncle Istvan", 66, Rarity.UNCOMMON, mage.cards.u.UncleIstvan.class)); - cards.add(new SetCardInfo("Untamed Wilds", 163, Rarity.UNCOMMON, mage.cards.u.UntamedWilds.class)); - cards.add(new SetCardInfo("Urza's Avenger", 164, Rarity.UNCOMMON, mage.cards.u.UrzasAvenger.class)); - cards.add(new SetCardInfo("Vampire Bats", 67, Rarity.COMMON, mage.cards.v.VampireBats.class)); - cards.add(new SetCardInfo("Venom", 165, Rarity.COMMON, mage.cards.v.Venom.class)); - cards.add(new SetCardInfo("Visions", 22, Rarity.UNCOMMON, mage.cards.v.Visions.class)); - cards.add(new SetCardInfo("Wall of Dust", 97, Rarity.UNCOMMON, mage.cards.w.WallOfDust.class)); - cards.add(new SetCardInfo("Wall of Spears", 166, Rarity.UNCOMMON, mage.cards.w.WallOfSpears.class)); - cards.add(new SetCardInfo("Whirling Dervish", 167, Rarity.UNCOMMON, mage.cards.w.WhirlingDervish.class)); - cards.add(new SetCardInfo("White Mana Battery", 168, Rarity.UNCOMMON, mage.cards.w.WhiteManaBattery.class)); - cards.add(new SetCardInfo("Winds of Change", 98, Rarity.UNCOMMON, mage.cards.w.WindsOfChange.class)); - cards.add(new SetCardInfo("Winter Blast", 169, Rarity.UNCOMMON, mage.cards.w.WinterBlast.class)); - cards.add(new SetCardInfo("Word of Binding", 68, Rarity.COMMON, mage.cards.w.WordOfBinding.class)); - cards.add(new SetCardInfo("Xenic Poltergeist", 69, Rarity.UNCOMMON, mage.cards.x.XenicPoltergeist.class)); - cards.add(new SetCardInfo("Yotian Soldier", 170, Rarity.COMMON, mage.cards.y.YotianSoldier.class)); - cards.add(new SetCardInfo("Zephyr Falcon", 45, Rarity.COMMON, mage.cards.z.ZephyrFalcon.class)); + cards.add(new SetCardInfo("Abomination", 46, Rarity.UNCOMMON, mage.cards.a.Abomination.class, RETRO_ART)); + cards.add(new SetCardInfo("Alabaster Potion", 2, Rarity.COMMON, mage.cards.a.AlabasterPotion.class, RETRO_ART)); + cards.add(new SetCardInfo("Ali Baba", 71, Rarity.UNCOMMON, mage.cards.a.AliBaba.class, RETRO_ART)); + cards.add(new SetCardInfo("Amrou Kithkin", 3, Rarity.COMMON, mage.cards.a.AmrouKithkin.class, RETRO_ART)); + cards.add(new SetCardInfo("Amulet of Kroog", 99, Rarity.COMMON, mage.cards.a.AmuletOfKroog.class, RETRO_ART)); + cards.add(new SetCardInfo("Angry Mob", 4, Rarity.UNCOMMON, mage.cards.a.AngryMob.class, RETRO_ART)); + cards.add(new SetCardInfo("Apprentice Wizard", 23, Rarity.UNCOMMON, mage.cards.a.ApprenticeWizard.class, RETRO_ART)); + cards.add(new SetCardInfo("Ashes to Ashes", 47, Rarity.COMMON, mage.cards.a.AshesToAshes.class, RETRO_ART)); + cards.add(new SetCardInfo("Ashnod's Battle Gear", 104, Rarity.UNCOMMON, mage.cards.a.AshnodsBattleGear.class, RETRO_ART)); + cards.add(new SetCardInfo("Backfire", 24, Rarity.UNCOMMON, mage.cards.b.Backfire.class, RETRO_ART)); + cards.add(new SetCardInfo("Ball Lightning", 73, Rarity.UNCOMMON, mage.cards.b.BallLightning.class, RETRO_ART)); + cards.add(new SetCardInfo("Battering Ram", 107, Rarity.COMMON, mage.cards.b.BatteringRam.class, RETRO_ART)); + cards.add(new SetCardInfo("Bird Maiden", 74, Rarity.COMMON, mage.cards.b.BirdMaiden.class, RETRO_ART)); + cards.add(new SetCardInfo("Black Mana Battery", 108, Rarity.UNCOMMON, mage.cards.b.BlackManaBattery.class, RETRO_ART)); + cards.add(new SetCardInfo("Blight", 48, Rarity.UNCOMMON, mage.cards.b.Blight.class, RETRO_ART)); + cards.add(new SetCardInfo("Blood Lust", 75, Rarity.UNCOMMON, mage.cards.b.BloodLust.class, RETRO_ART)); + cards.add(new SetCardInfo("Blue Mana Battery", 112, Rarity.UNCOMMON, mage.cards.b.BlueManaBattery.class, RETRO_ART)); + cards.add(new SetCardInfo("Bog Imp", 49, Rarity.COMMON, mage.cards.b.BogImp.class, RETRO_ART)); + cards.add(new SetCardInfo("Brainwash", 6, Rarity.COMMON, mage.cards.b.Brainwash.class, RETRO_ART)); + //cards.add(new SetCardInfo("Bronze Tablet", 115, Rarity.UNCOMMON, mage.cards.b.BronzeTablet.class, RETRO_ART)); + cards.add(new SetCardInfo("Brothers of Fire", 76, Rarity.UNCOMMON, mage.cards.b.BrothersOfFire.class, RETRO_ART)); + cards.add(new SetCardInfo("Carnivorous Plant", 117, Rarity.COMMON, mage.cards.c.CarnivorousPlant.class, RETRO_ART)); + cards.add(new SetCardInfo("Carrion Ants", 51, Rarity.UNCOMMON, mage.cards.c.CarrionAnts.class, RETRO_ART)); + cards.add(new SetCardInfo("Cave People", 78, Rarity.UNCOMMON, mage.cards.c.CavePeople.class, RETRO_ART)); + cards.add(new SetCardInfo("Circle of Protection: Artifacts", 7, Rarity.UNCOMMON, mage.cards.c.CircleOfProtectionArtifacts.class, RETRO_ART)); + cards.add(new SetCardInfo("Clay Statue", 120, Rarity.COMMON, mage.cards.c.ClayStatue.class, RETRO_ART)); + cards.add(new SetCardInfo("Clockwork Avian", 122, Rarity.UNCOMMON, mage.cards.c.ClockworkAvian.class, RETRO_ART)); + cards.add(new SetCardInfo("Colossus of Sardia", 123, Rarity.UNCOMMON, mage.cards.c.ColossusOfSardia.class, RETRO_ART)); + cards.add(new SetCardInfo("Coral Helm", 124, Rarity.UNCOMMON, mage.cards.c.CoralHelm.class, RETRO_ART)); + cards.add(new SetCardInfo("Cosmic Horror", 52, Rarity.UNCOMMON, mage.cards.c.CosmicHorror.class, RETRO_ART)); + cards.add(new SetCardInfo("Crimson Manticore", 80, Rarity.UNCOMMON, mage.cards.c.CrimsonManticore.class, RETRO_ART)); + cards.add(new SetCardInfo("Cursed Rack", 126, Rarity.COMMON, mage.cards.c.CursedRack.class, RETRO_ART)); + cards.add(new SetCardInfo("Cyclopean Mummy", 54, Rarity.COMMON, mage.cards.c.CyclopeanMummy.class, RETRO_ART)); + cards.add(new SetCardInfo("Detonate", 83, Rarity.UNCOMMON, mage.cards.d.Detonate.class, RETRO_ART)); + cards.add(new SetCardInfo("Diabolic Machine", 129, Rarity.UNCOMMON, mage.cards.d.DiabolicMachine.class, RETRO_ART)); + cards.add(new SetCardInfo("Divine Transformation", 8, Rarity.UNCOMMON, mage.cards.d.DivineTransformation.class, RETRO_ART)); + cards.add(new SetCardInfo("Durkwood Boars", 131, Rarity.COMMON, mage.cards.d.DurkwoodBoars.class, RETRO_ART)); + cards.add(new SetCardInfo("Elder Land Wurm", 9, Rarity.UNCOMMON, mage.cards.e.ElderLandWurm.class, RETRO_ART)); + cards.add(new SetCardInfo("Elven Riders", 133, Rarity.UNCOMMON, mage.cards.e.ElvenRiders.class, RETRO_ART)); + cards.add(new SetCardInfo("Energy Tap", 28, Rarity.COMMON, mage.cards.e.EnergyTap.class, RETRO_ART)); + cards.add(new SetCardInfo("Erosion", 29, Rarity.COMMON, mage.cards.e.Erosion.class, RETRO_ART)); + cards.add(new SetCardInfo("Eternal Warrior", 84, Rarity.UNCOMMON, mage.cards.e.EternalWarrior.class, RETRO_ART)); + cards.add(new SetCardInfo("Fellwar Stone", 136, Rarity.UNCOMMON, mage.cards.f.FellwarStone.class, RETRO_ART)); + cards.add(new SetCardInfo("Fissure", 85, Rarity.COMMON, mage.cards.f.Fissure.class, RETRO_ART)); + cards.add(new SetCardInfo("Flood", 30, Rarity.UNCOMMON, mage.cards.f.Flood.class, RETRO_ART)); + cards.add(new SetCardInfo("Fortified Area", 11, Rarity.UNCOMMON, mage.cards.f.FortifiedArea.class, RETRO_ART)); + cards.add(new SetCardInfo("Gaseous Form", 32, Rarity.COMMON, mage.cards.g.GaseousForm.class, RETRO_ART)); + cards.add(new SetCardInfo("Ghost Ship", 33, Rarity.COMMON, mage.cards.g.GhostShip.class, RETRO_ART)); + cards.add(new SetCardInfo("Giant Strength", 86, Rarity.COMMON, mage.cards.g.GiantStrength.class, RETRO_ART)); + cards.add(new SetCardInfo("Giant Tortoise", 34, Rarity.COMMON, mage.cards.g.GiantTortoise.class, RETRO_ART)); + cards.add(new SetCardInfo("Goblin Rock Sled", 87, Rarity.COMMON, mage.cards.g.GoblinRockSled.class, RETRO_ART)); + cards.add(new SetCardInfo("Grapeshot Catapult", 143, Rarity.COMMON, mage.cards.g.GrapeshotCatapult.class, RETRO_ART)); + cards.add(new SetCardInfo("Greed", 56, Rarity.UNCOMMON, mage.cards.g.Greed.class, RETRO_ART)); + cards.add(new SetCardInfo("Green Mana Battery", 145, Rarity.UNCOMMON, mage.cards.g.GreenManaBattery.class, RETRO_ART)); + cards.add(new SetCardInfo("Hurr Jackal", 88, Rarity.COMMON, mage.cards.h.HurrJackal.class, RETRO_ART)); + cards.add(new SetCardInfo("Immolation", 89, Rarity.COMMON, mage.cards.i.Immolation.class, RETRO_ART)); + cards.add(new SetCardInfo("Inferno", 90, Rarity.UNCOMMON, mage.cards.i.Inferno.class, RETRO_ART)); + cards.add(new SetCardInfo("Ironclaw Orcs", 91, Rarity.COMMON, mage.cards.i.IronclawOrcs.class, RETRO_ART)); + cards.add(new SetCardInfo("Junun Efreet", 57, Rarity.UNCOMMON, mage.cards.j.JununEfreet.class, RETRO_ART)); + cards.add(new SetCardInfo("Killer Bees", 146, Rarity.UNCOMMON, mage.cards.k.KillerBees.class, RETRO_ART)); + cards.add(new SetCardInfo("Kismet", 12, Rarity.UNCOMMON, mage.cards.k.Kismet.class, RETRO_ART)); + cards.add(new SetCardInfo("Land Leeches", 147, Rarity.COMMON, mage.cards.l.LandLeeches.class, RETRO_ART)); + cards.add(new SetCardInfo("Land Tax", 13, Rarity.UNCOMMON, mage.cards.l.LandTax.class, RETRO_ART)); + cards.add(new SetCardInfo("Leviathan", 36, Rarity.UNCOMMON, mage.cards.l.Leviathan.class, RETRO_ART)); + cards.add(new SetCardInfo("Lost Soul", 58, Rarity.COMMON, mage.cards.l.LostSoul.class, RETRO_ART)); + cards.add(new SetCardInfo("Mana Clash", 92, Rarity.UNCOMMON, mage.cards.m.ManaClash.class, RETRO_ART)); + cards.add(new SetCardInfo("Marsh Gas", 59, Rarity.COMMON, mage.cards.m.MarshGas.class, RETRO_ART)); + cards.add(new SetCardInfo("Marsh Viper", 149, Rarity.COMMON, mage.cards.m.MarshViper.class, RETRO_ART)); + cards.add(new SetCardInfo("Mind Bomb", 37, Rarity.UNCOMMON, mage.cards.m.MindBomb.class, RETRO_ART)); + cards.add(new SetCardInfo("Mishra's Factory", 187, Rarity.UNCOMMON, mage.cards.m.MishrasFactory.class, RETRO_ART)); + cards.add(new SetCardInfo("Morale", 15, Rarity.COMMON, mage.cards.m.Morale.class, RETRO_ART)); + cards.add(new SetCardInfo("Murk Dwellers", 62, Rarity.COMMON, mage.cards.m.MurkDwellers.class, RETRO_ART)); + cards.add(new SetCardInfo("Nafs Asp", 151, Rarity.COMMON, mage.cards.n.NafsAsp.class, RETRO_ART)); + cards.add(new SetCardInfo("Oasis", 188, Rarity.UNCOMMON, mage.cards.o.Oasis.class, RETRO_ART)); + cards.add(new SetCardInfo("Osai Vultures", 16, Rarity.COMMON, mage.cards.o.OsaiVultures.class, RETRO_ART)); + cards.add(new SetCardInfo("Piety", 17, Rarity.COMMON, mage.cards.p.Piety.class, RETRO_ART)); + cards.add(new SetCardInfo("Pikemen", 18, Rarity.COMMON, mage.cards.p.Pikemen.class, RETRO_ART)); + cards.add(new SetCardInfo("Pit Scorpion", 63, Rarity.COMMON, mage.cards.p.PitScorpion.class, RETRO_ART)); + cards.add(new SetCardInfo("Pradesh Gypsies", 152, Rarity.UNCOMMON, mage.cards.p.PradeshGypsies.class, RETRO_ART)); + cards.add(new SetCardInfo("Psionic Entity", 38, Rarity.UNCOMMON, mage.cards.p.PsionicEntity.class, RETRO_ART)); + cards.add(new SetCardInfo("Pyrotechnics", 93, Rarity.COMMON, mage.cards.p.Pyrotechnics.class, RETRO_ART)); + cards.add(new SetCardInfo("Radjan Spirit", 153, Rarity.UNCOMMON, mage.cards.r.RadjanSpirit.class, RETRO_ART)); + cards.add(new SetCardInfo("Rag Man", 64, Rarity.UNCOMMON, mage.cards.r.RagMan.class, RETRO_ART)); + //cards.add(new SetCardInfo("Rebirth", 154, Rarity.UNCOMMON, mage.cards.r.Rebirth.class, RETRO_ART)); + cards.add(new SetCardInfo("Red Mana Battery", 155, Rarity.UNCOMMON, mage.cards.r.RedManaBattery.class, RETRO_ART)); + cards.add(new SetCardInfo("Relic Bind", 39, Rarity.UNCOMMON, mage.cards.r.RelicBind.class, RETRO_ART)); + cards.add(new SetCardInfo("Sandstorm", 156, Rarity.COMMON, mage.cards.s.Sandstorm.class, RETRO_ART)); + cards.add(new SetCardInfo("Seeker", 19, Rarity.UNCOMMON, mage.cards.s.Seeker.class, RETRO_ART)); + cards.add(new SetCardInfo("Segovian Leviathan", 40, Rarity.UNCOMMON, mage.cards.s.SegovianLeviathan.class, RETRO_ART)); + cards.add(new SetCardInfo("Shapeshifter", 157, Rarity.UNCOMMON, mage.cards.s.Shapeshifter.class, RETRO_ART)); + cards.add(new SetCardInfo("Sindbad", 41, Rarity.UNCOMMON, mage.cards.s.Sindbad.class, RETRO_ART)); + cards.add(new SetCardInfo("Sisters of the Flame", 94, Rarity.UNCOMMON, mage.cards.s.SistersOfTheFlame.class, RETRO_ART)); + cards.add(new SetCardInfo("Spirit Link", 20, Rarity.UNCOMMON, mage.cards.s.SpiritLink.class, RETRO_ART)); + cards.add(new SetCardInfo("Spirit Shackle", 65, Rarity.COMMON, mage.cards.s.SpiritShackle.class, RETRO_ART)); + cards.add(new SetCardInfo("Strip Mine", 189, Rarity.UNCOMMON, mage.cards.s.StripMine.class, RETRO_ART)); + cards.add(new SetCardInfo("Sunken City", 42, Rarity.COMMON, mage.cards.s.SunkenCity.class, RETRO_ART)); + cards.add(new SetCardInfo("Sylvan Library", 158, Rarity.UNCOMMON, mage.cards.s.SylvanLibrary.class, RETRO_ART)); + cards.add(new SetCardInfo("Tawnos's Wand", 159, Rarity.UNCOMMON, mage.cards.t.TawnossWand.class, RETRO_ART)); + cards.add(new SetCardInfo("Tawnos's Weaponry", 160, Rarity.UNCOMMON, mage.cards.t.TawnossWeaponry.class, RETRO_ART)); + //cards.add(new SetCardInfo("Tempest Efreet", 95, Rarity.UNCOMMON, mage.cards.t.TempestEfreet.class, RETRO_ART)); + cards.add(new SetCardInfo("Tetravus", 161, Rarity.UNCOMMON, mage.cards.t.Tetravus.class, RETRO_ART)); + cards.add(new SetCardInfo("The Brute", 96, Rarity.COMMON, mage.cards.t.TheBrute.class, RETRO_ART)); + cards.add(new SetCardInfo("Time Elemental", 43, Rarity.UNCOMMON, mage.cards.t.TimeElemental.class, RETRO_ART)); + cards.add(new SetCardInfo("Triskelion", 162, Rarity.UNCOMMON, mage.cards.t.Triskelion.class, RETRO_ART)); + cards.add(new SetCardInfo("Tundra Wolves", 21, Rarity.COMMON, mage.cards.t.TundraWolves.class, RETRO_ART)); + cards.add(new SetCardInfo("Twiddle", 44, Rarity.COMMON, mage.cards.t.Twiddle.class, RETRO_ART)); + cards.add(new SetCardInfo("Uncle Istvan", 66, Rarity.UNCOMMON, mage.cards.u.UncleIstvan.class, RETRO_ART)); + cards.add(new SetCardInfo("Untamed Wilds", 163, Rarity.UNCOMMON, mage.cards.u.UntamedWilds.class, RETRO_ART)); + cards.add(new SetCardInfo("Urza's Avenger", 164, Rarity.UNCOMMON, mage.cards.u.UrzasAvenger.class, RETRO_ART)); + cards.add(new SetCardInfo("Vampire Bats", 67, Rarity.COMMON, mage.cards.v.VampireBats.class, RETRO_ART)); + cards.add(new SetCardInfo("Venom", 165, Rarity.COMMON, mage.cards.v.Venom.class, RETRO_ART)); + cards.add(new SetCardInfo("Visions", 22, Rarity.UNCOMMON, mage.cards.v.Visions.class, RETRO_ART)); + cards.add(new SetCardInfo("Wall of Dust", 97, Rarity.UNCOMMON, mage.cards.w.WallOfDust.class, RETRO_ART)); + cards.add(new SetCardInfo("Wall of Spears", 166, Rarity.UNCOMMON, mage.cards.w.WallOfSpears.class, RETRO_ART)); + cards.add(new SetCardInfo("Whirling Dervish", 167, Rarity.UNCOMMON, mage.cards.w.WhirlingDervish.class, RETRO_ART)); + cards.add(new SetCardInfo("White Mana Battery", 168, Rarity.UNCOMMON, mage.cards.w.WhiteManaBattery.class, RETRO_ART)); + cards.add(new SetCardInfo("Winds of Change", 98, Rarity.UNCOMMON, mage.cards.w.WindsOfChange.class, RETRO_ART)); + cards.add(new SetCardInfo("Winter Blast", 169, Rarity.UNCOMMON, mage.cards.w.WinterBlast.class, RETRO_ART)); + cards.add(new SetCardInfo("Word of Binding", 68, Rarity.COMMON, mage.cards.w.WordOfBinding.class, RETRO_ART)); + cards.add(new SetCardInfo("Xenic Poltergeist", 69, Rarity.UNCOMMON, mage.cards.x.XenicPoltergeist.class, RETRO_ART)); + cards.add(new SetCardInfo("Yotian Soldier", 170, Rarity.COMMON, mage.cards.y.YotianSoldier.class, RETRO_ART)); + cards.add(new SetCardInfo("Zephyr Falcon", 45, Rarity.COMMON, mage.cards.z.ZephyrFalcon.class, RETRO_ART)); } } diff --git a/Mage.Sets/src/mage/sets/Rinascimento.java b/Mage.Sets/src/mage/sets/Rinascimento.java index b7b66201152..8822934f707 100644 --- a/Mage.Sets/src/mage/sets/Rinascimento.java +++ b/Mage.Sets/src/mage/sets/Rinascimento.java @@ -26,74 +26,74 @@ public final class Rinascimento extends ExpansionSet { this.enableCollectorBooster(Integer.MAX_VALUE, 0, 6, 2, 0); - cards.add(new SetCardInfo("Abu Ja'far", 1, Rarity.UNCOMMON, mage.cards.a.AbuJafar.class)); - cards.add(new SetCardInfo("Aladdin", 70, Rarity.UNCOMMON, mage.cards.a.Aladdin.class)); - cards.add(new SetCardInfo("Ali Baba", 71, Rarity.UNCOMMON, mage.cards.a.AliBaba.class)); - cards.add(new SetCardInfo("Amulet of Kroog", 99, Rarity.COMMON, mage.cards.a.AmuletOfKroog.class)); - cards.add(new SetCardInfo("Argothian Pixies", 100, Rarity.COMMON, mage.cards.a.ArgothianPixies.class)); - cards.add(new SetCardInfo("Ashnod's Altar", 101, Rarity.UNCOMMON, mage.cards.a.AshnodsAltar.class)); - cards.add(new SetCardInfo("Ashnod's Battle Gear", 102, Rarity.UNCOMMON, mage.cards.a.AshnodsBattleGear.class)); - cards.add(new SetCardInfo("Ashnod's Transmogrant", 103, Rarity.UNCOMMON, mage.cards.a.AshnodsTransmogrant.class)); - cards.add(new SetCardInfo("Battering Ram", 105, Rarity.COMMON, mage.cards.b.BatteringRam.class)); - cards.add(new SetCardInfo("Bird Maiden", 72, Rarity.COMMON, mage.cards.b.BirdMaiden.class)); - //cards.add(new SetCardInfo("Bronze Tablet", 106, Rarity.UNCOMMON, mage.cards.b.BronzeTablet.class)); - cards.add(new SetCardInfo("Circle of Protection: Artifacts", 5, Rarity.UNCOMMON, mage.cards.c.CircleOfProtectionArtifacts.class)); - cards.add(new SetCardInfo("City of Brass", 171, Rarity.UNCOMMON, mage.cards.c.CityOfBrass.class)); - cards.add(new SetCardInfo("Clay Statue", 109, Rarity.COMMON, mage.cards.c.ClayStatue.class)); - cards.add(new SetCardInfo("Clockwork Avian", 110, Rarity.UNCOMMON, mage.cards.c.ClockworkAvian.class)); - cards.add(new SetCardInfo("Colossus of Sardia", 111, Rarity.UNCOMMON, mage.cards.c.ColossusOfSardia.class)); - cards.add(new SetCardInfo("Coral Helm", 113, Rarity.UNCOMMON, mage.cards.c.CoralHelm.class)); - cards.add(new SetCardInfo("Cuombajj Witches", 50, Rarity.COMMON, mage.cards.c.CuombajjWitches.class)); - cards.add(new SetCardInfo("Cursed Rack", 114, Rarity.COMMON, mage.cards.c.CursedRack.class)); - cards.add(new SetCardInfo("Cyclone", 116, Rarity.UNCOMMON, mage.cards.c.Cyclone.class)); - cards.add(new SetCardInfo("Dandan", 25, Rarity.COMMON, mage.cards.d.Dandan.class)); - cards.add(new SetCardInfo("Detonate", 77, Rarity.UNCOMMON, mage.cards.d.Detonate.class)); - cards.add(new SetCardInfo("Erhnam Djinn", 118, Rarity.UNCOMMON, mage.cards.e.ErhnamDjinn.class)); - cards.add(new SetCardInfo("Feldon's Cane", 119, Rarity.COMMON, mage.cards.f.FeldonsCane.class)); - cards.add(new SetCardInfo("Fishliver Oil", 26, Rarity.COMMON, mage.cards.f.FishliverOil.class)); - cards.add(new SetCardInfo("Ghazban Ogre", 121, Rarity.COMMON, mage.cards.g.GhazbanOgre.class)); - cards.add(new SetCardInfo("Giant Tortoise", 27, Rarity.COMMON, mage.cards.g.GiantTortoise.class)); - cards.add(new SetCardInfo("Goblin Artisans", 79, Rarity.UNCOMMON, mage.cards.g.GoblinArtisans.class)); - cards.add(new SetCardInfo("Grapeshot Catapult", 125, Rarity.COMMON, mage.cards.g.GrapeshotCatapult.class)); - cards.add(new SetCardInfo("Hasran Ogress", 53, Rarity.COMMON, mage.cards.h.HasranOgress.class)); - cards.add(new SetCardInfo("Hurr Jackal", 81, Rarity.COMMON, mage.cards.h.HurrJackal.class)); - cards.add(new SetCardInfo("Ironclaw Orcs", 82, Rarity.COMMON, mage.cards.i.IronclawOrcs.class)); - cards.add(new SetCardInfo("Jalum Tome", 127, Rarity.UNCOMMON, mage.cards.j.JalumTome.class)); - //cards.add(new SetCardInfo("Jeweled Bird", 128, Rarity.UNCOMMON, mage.cards.j.JeweledBird.class)); - cards.add(new SetCardInfo("Junun Efreet", 55, Rarity.UNCOMMON, mage.cards.j.JununEfreet.class)); - cards.add(new SetCardInfo("Metamorphosis", 130, Rarity.COMMON, mage.cards.m.Metamorphosis.class)); - cards.add(new SetCardInfo("Mishra's Factory", 172, Rarity.UNCOMMON, mage.cards.m.MishrasFactory.class)); - cards.add(new SetCardInfo("Nafs Asp", 132, Rarity.COMMON, mage.cards.n.NafsAsp.class)); - cards.add(new SetCardInfo("Oasis", 173, Rarity.UNCOMMON, mage.cards.o.Oasis.class)); - cards.add(new SetCardInfo("Obelisk of Undoing", 134, Rarity.UNCOMMON, mage.cards.o.ObeliskOfUndoing.class)); - cards.add(new SetCardInfo("Rakalite", 135, Rarity.UNCOMMON, mage.cards.r.Rakalite.class)); - cards.add(new SetCardInfo("Repentant Blacksmith", 10, Rarity.UNCOMMON, mage.cards.r.RepentantBlacksmith.class)); - cards.add(new SetCardInfo("Sandstorm", 137, Rarity.COMMON, mage.cards.s.Sandstorm.class)); - cards.add(new SetCardInfo("Shapeshifter", 138, Rarity.UNCOMMON, mage.cards.s.Shapeshifter.class)); - cards.add(new SetCardInfo("Sindbad", 31, Rarity.UNCOMMON, mage.cards.s.Sindbad.class)); - cards.add(new SetCardInfo("Strip Mine", 174, Rarity.UNCOMMON, mage.cards.s.StripMine.class)); - cards.add(new SetCardInfo("Tawnos's Wand", 139, Rarity.UNCOMMON, mage.cards.t.TawnossWand.class)); - cards.add(new SetCardInfo("Tawnos's Weaponry", 140, Rarity.UNCOMMON, mage.cards.t.TawnossWeaponry.class)); - cards.add(new SetCardInfo("Tetravus", 141, Rarity.UNCOMMON, mage.cards.t.Tetravus.class)); - cards.add(new SetCardInfo("Triskelion", 142, Rarity.UNCOMMON, mage.cards.t.Triskelion.class)); - cards.add(new SetCardInfo("Twiddle", 35, Rarity.COMMON, mage.cards.t.Twiddle.class)); - cards.add(new SetCardInfo("Urza's Avenger", 144, Rarity.UNCOMMON, mage.cards.u.UrzasAvenger.class)); - cards.add(new SetCardInfo("Urza's Mine", 175, Rarity.COMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Mine", 176, Rarity.COMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Mine", 177, Rarity.COMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Mine", 178, Rarity.COMMON, mage.cards.u.UrzasMine.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Power Plant", 179, Rarity.COMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Power Plant", 180, Rarity.COMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Power Plant", 181, Rarity.COMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Power Plant", 182, Rarity.COMMON, mage.cards.u.UrzasPowerPlant.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Tower", 183, Rarity.COMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Tower", 184, Rarity.COMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Tower", 185, Rarity.COMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Urza's Tower", 186, Rarity.COMMON, mage.cards.u.UrzasTower.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Wall of Spears", 148, Rarity.UNCOMMON, mage.cards.w.WallOfSpears.class)); - cards.add(new SetCardInfo("War Elephant", 14, Rarity.COMMON, mage.cards.w.WarElephant.class)); - cards.add(new SetCardInfo("Xenic Poltergeist", 60, Rarity.UNCOMMON, mage.cards.x.XenicPoltergeist.class)); - cards.add(new SetCardInfo("Yawgmoth Demon", 61, Rarity.UNCOMMON, mage.cards.y.YawgmothDemon.class)); - cards.add(new SetCardInfo("Yotian Soldier", 150, Rarity.COMMON, mage.cards.y.YotianSoldier.class)); + cards.add(new SetCardInfo("Abu Ja'far", 1, Rarity.UNCOMMON, mage.cards.a.AbuJafar.class, RETRO_ART)); + cards.add(new SetCardInfo("Aladdin", 70, Rarity.UNCOMMON, mage.cards.a.Aladdin.class, RETRO_ART)); + cards.add(new SetCardInfo("Ali Baba", 71, Rarity.UNCOMMON, mage.cards.a.AliBaba.class, RETRO_ART)); + cards.add(new SetCardInfo("Amulet of Kroog", 99, Rarity.COMMON, mage.cards.a.AmuletOfKroog.class, RETRO_ART)); + cards.add(new SetCardInfo("Argothian Pixies", 100, Rarity.COMMON, mage.cards.a.ArgothianPixies.class, RETRO_ART)); + cards.add(new SetCardInfo("Ashnod's Altar", 101, Rarity.UNCOMMON, mage.cards.a.AshnodsAltar.class, RETRO_ART)); + cards.add(new SetCardInfo("Ashnod's Battle Gear", 102, Rarity.UNCOMMON, mage.cards.a.AshnodsBattleGear.class, RETRO_ART)); + cards.add(new SetCardInfo("Ashnod's Transmogrant", 103, Rarity.UNCOMMON, mage.cards.a.AshnodsTransmogrant.class, RETRO_ART)); + cards.add(new SetCardInfo("Battering Ram", 105, Rarity.COMMON, mage.cards.b.BatteringRam.class, RETRO_ART)); + cards.add(new SetCardInfo("Bird Maiden", 72, Rarity.COMMON, mage.cards.b.BirdMaiden.class, RETRO_ART)); + //cards.add(new SetCardInfo("Bronze Tablet", 106, Rarity.UNCOMMON, mage.cards.b.BronzeTablet.class, RETRO_ART)); + cards.add(new SetCardInfo("Circle of Protection: Artifacts", 5, Rarity.UNCOMMON, mage.cards.c.CircleOfProtectionArtifacts.class, RETRO_ART)); + cards.add(new SetCardInfo("City of Brass", 171, Rarity.UNCOMMON, mage.cards.c.CityOfBrass.class, RETRO_ART)); + cards.add(new SetCardInfo("Clay Statue", 109, Rarity.COMMON, mage.cards.c.ClayStatue.class, RETRO_ART)); + cards.add(new SetCardInfo("Clockwork Avian", 110, Rarity.UNCOMMON, mage.cards.c.ClockworkAvian.class, RETRO_ART)); + cards.add(new SetCardInfo("Colossus of Sardia", 111, Rarity.UNCOMMON, mage.cards.c.ColossusOfSardia.class, RETRO_ART)); + cards.add(new SetCardInfo("Coral Helm", 113, Rarity.UNCOMMON, mage.cards.c.CoralHelm.class, RETRO_ART)); + cards.add(new SetCardInfo("Cuombajj Witches", 50, Rarity.COMMON, mage.cards.c.CuombajjWitches.class, RETRO_ART)); + cards.add(new SetCardInfo("Cursed Rack", 114, Rarity.COMMON, mage.cards.c.CursedRack.class, RETRO_ART)); + cards.add(new SetCardInfo("Cyclone", 116, Rarity.UNCOMMON, mage.cards.c.Cyclone.class, RETRO_ART)); + cards.add(new SetCardInfo("Dandan", 25, Rarity.COMMON, mage.cards.d.Dandan.class, RETRO_ART)); + cards.add(new SetCardInfo("Detonate", 77, Rarity.UNCOMMON, mage.cards.d.Detonate.class, RETRO_ART)); + cards.add(new SetCardInfo("Erhnam Djinn", 118, Rarity.UNCOMMON, mage.cards.e.ErhnamDjinn.class, RETRO_ART)); + cards.add(new SetCardInfo("Feldon's Cane", 119, Rarity.COMMON, mage.cards.f.FeldonsCane.class, RETRO_ART)); + cards.add(new SetCardInfo("Fishliver Oil", 26, Rarity.COMMON, mage.cards.f.FishliverOil.class, RETRO_ART)); + cards.add(new SetCardInfo("Ghazban Ogre", 121, Rarity.COMMON, mage.cards.g.GhazbanOgre.class, RETRO_ART)); + cards.add(new SetCardInfo("Giant Tortoise", 27, Rarity.COMMON, mage.cards.g.GiantTortoise.class, RETRO_ART)); + cards.add(new SetCardInfo("Goblin Artisans", 79, Rarity.UNCOMMON, mage.cards.g.GoblinArtisans.class, RETRO_ART)); + cards.add(new SetCardInfo("Grapeshot Catapult", 125, Rarity.COMMON, mage.cards.g.GrapeshotCatapult.class, RETRO_ART)); + cards.add(new SetCardInfo("Hasran Ogress", 53, Rarity.COMMON, mage.cards.h.HasranOgress.class, RETRO_ART)); + cards.add(new SetCardInfo("Hurr Jackal", 81, Rarity.COMMON, mage.cards.h.HurrJackal.class, RETRO_ART)); + cards.add(new SetCardInfo("Ironclaw Orcs", 82, Rarity.COMMON, mage.cards.i.IronclawOrcs.class, RETRO_ART)); + cards.add(new SetCardInfo("Jalum Tome", 127, Rarity.UNCOMMON, mage.cards.j.JalumTome.class, RETRO_ART)); + //cards.add(new SetCardInfo("Jeweled Bird", 128, Rarity.UNCOMMON, mage.cards.j.JeweledBird.class, RETRO_ART)); + cards.add(new SetCardInfo("Junun Efreet", 55, Rarity.UNCOMMON, mage.cards.j.JununEfreet.class, RETRO_ART)); + cards.add(new SetCardInfo("Metamorphosis", 130, Rarity.COMMON, mage.cards.m.Metamorphosis.class, RETRO_ART)); + cards.add(new SetCardInfo("Mishra's Factory", 172, Rarity.UNCOMMON, mage.cards.m.MishrasFactory.class, RETRO_ART)); + cards.add(new SetCardInfo("Nafs Asp", 132, Rarity.COMMON, mage.cards.n.NafsAsp.class, RETRO_ART)); + cards.add(new SetCardInfo("Oasis", 173, Rarity.UNCOMMON, mage.cards.o.Oasis.class, RETRO_ART)); + cards.add(new SetCardInfo("Obelisk of Undoing", 134, Rarity.UNCOMMON, mage.cards.o.ObeliskOfUndoing.class, RETRO_ART)); + cards.add(new SetCardInfo("Rakalite", 135, Rarity.UNCOMMON, mage.cards.r.Rakalite.class, RETRO_ART)); + cards.add(new SetCardInfo("Repentant Blacksmith", 10, Rarity.UNCOMMON, mage.cards.r.RepentantBlacksmith.class, RETRO_ART)); + cards.add(new SetCardInfo("Sandstorm", 137, Rarity.COMMON, mage.cards.s.Sandstorm.class, RETRO_ART)); + cards.add(new SetCardInfo("Shapeshifter", 138, Rarity.UNCOMMON, mage.cards.s.Shapeshifter.class, RETRO_ART)); + cards.add(new SetCardInfo("Sindbad", 31, Rarity.UNCOMMON, mage.cards.s.Sindbad.class, RETRO_ART)); + cards.add(new SetCardInfo("Strip Mine", 174, Rarity.UNCOMMON, mage.cards.s.StripMine.class, RETRO_ART)); + cards.add(new SetCardInfo("Tawnos's Wand", 139, Rarity.UNCOMMON, mage.cards.t.TawnossWand.class, RETRO_ART)); + cards.add(new SetCardInfo("Tawnos's Weaponry", 140, Rarity.UNCOMMON, mage.cards.t.TawnossWeaponry.class, RETRO_ART)); + cards.add(new SetCardInfo("Tetravus", 141, Rarity.UNCOMMON, mage.cards.t.Tetravus.class, RETRO_ART)); + cards.add(new SetCardInfo("Triskelion", 142, Rarity.UNCOMMON, mage.cards.t.Triskelion.class, RETRO_ART)); + cards.add(new SetCardInfo("Twiddle", 35, Rarity.COMMON, mage.cards.t.Twiddle.class, RETRO_ART)); + cards.add(new SetCardInfo("Urza's Avenger", 144, Rarity.UNCOMMON, mage.cards.u.UrzasAvenger.class, RETRO_ART)); + cards.add(new SetCardInfo("Urza's Mine", 175, Rarity.COMMON, mage.cards.u.UrzasMine.class, RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Mine", 176, Rarity.COMMON, mage.cards.u.UrzasMine.class, RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Mine", 177, Rarity.COMMON, mage.cards.u.UrzasMine.class, RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Mine", 178, Rarity.COMMON, mage.cards.u.UrzasMine.class, RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Power Plant", 179, Rarity.COMMON, mage.cards.u.UrzasPowerPlant.class, RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Power Plant", 180, Rarity.COMMON, mage.cards.u.UrzasPowerPlant.class, RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Power Plant", 181, Rarity.COMMON, mage.cards.u.UrzasPowerPlant.class, RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Power Plant", 182, Rarity.COMMON, mage.cards.u.UrzasPowerPlant.class, RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Tower", 183, Rarity.COMMON, mage.cards.u.UrzasTower.class, RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Tower", 184, Rarity.COMMON, mage.cards.u.UrzasTower.class, RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Tower", 185, Rarity.COMMON, mage.cards.u.UrzasTower.class, RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Urza's Tower", 186, Rarity.COMMON, mage.cards.u.UrzasTower.class, RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Wall of Spears", 148, Rarity.UNCOMMON, mage.cards.w.WallOfSpears.class, RETRO_ART)); + cards.add(new SetCardInfo("War Elephant", 14, Rarity.COMMON, mage.cards.w.WarElephant.class, RETRO_ART)); + cards.add(new SetCardInfo("Xenic Poltergeist", 60, Rarity.UNCOMMON, mage.cards.x.XenicPoltergeist.class, RETRO_ART)); + cards.add(new SetCardInfo("Yawgmoth Demon", 61, Rarity.UNCOMMON, mage.cards.y.YawgmothDemon.class, RETRO_ART)); + cards.add(new SetCardInfo("Yotian Soldier", 150, Rarity.COMMON, mage.cards.y.YotianSoldier.class, RETRO_ART)); } }