From c602edeca3e868aaba5e98f4afa29a493fc8624f Mon Sep 17 00:00:00 2001 From: theelk801 Date: Wed, 12 Nov 2025 10:10:03 -0500 Subject: [PATCH] [TLA] Implement Kyoshi Island Plaza --- .../mage/cards/g/GoShintaiOfAncientWars.java | 19 ++--- .../cards/g/GoShintaiOfBoundlessVigor.java | 24 ++---- .../cards/g/GoShintaiOfHiddenCruelty.java | 15 +--- .../mage/cards/g/GoShintaiOfLostWisdom.java | 17 +---- .../cards/g/GoShintaiOfSharedPurpose.java | 22 ++---- .../mage/cards/h/HondenOfCleansingFire.java | 19 ++--- .../mage/cards/h/HondenOfInfiniteRage.java | 22 ++---- .../src/mage/cards/h/HondenOfLifesWeb.java | 21 ++--- .../src/mage/cards/h/HondenOfNightsReach.java | 18 ++--- .../src/mage/cards/h/HondenOfSeeingWinds.java | 20 +---- .../src/mage/cards/k/KyoshiIslandPlaza.java | 76 +++++++++++++++++++ .../src/mage/cards/n/NorthernAirTemple.java | 25 ++---- Mage.Sets/src/mage/cards/s/SanctumOfAll.java | 22 ++---- .../src/mage/cards/s/SanctumOfCalmWaters.java | 22 ++---- .../cards/s/SanctumOfFruitfulHarvest.java | 29 ++----- .../cards/s/SanctumOfShatteredHeights.java | 24 +++--- .../src/mage/cards/s/SanctumOfStoneFangs.java | 24 ++---- .../mage/cards/s/SanctumOfTranquilLight.java | 19 +---- .../src/mage/cards/s/SouthernAirTemple.java | 22 +----- .../src/mage/cards/t/TheSpiritOasis.java | 21 +---- .../src/mage/sets/AvatarTheLastAirbender.java | 1 + .../common/ShrinesYouControlCount.java | 55 ++++++++++++++ .../effects/common/GainLifeEffect.java | 1 + .../main/java/mage/filter/StaticFilters.java | 7 ++ 24 files changed, 243 insertions(+), 302 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/k/KyoshiIslandPlaza.java create mode 100644 Mage/src/main/java/mage/abilities/dynamicvalue/common/ShrinesYouControlCount.java diff --git a/Mage.Sets/src/mage/cards/g/GoShintaiOfAncientWars.java b/Mage.Sets/src/mage/cards/g/GoShintaiOfAncientWars.java index 01011d968ac..6640e0dd927 100644 --- a/Mage.Sets/src/mage/cards/g/GoShintaiOfAncientWars.java +++ b/Mage.Sets/src/mage/cards/g/GoShintaiOfAncientWars.java @@ -1,22 +1,18 @@ package mage.cards.g; import mage.MageInt; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.DoWhenCostPaid; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.filter.common.FilterControlledPermanent; import mage.target.common.TargetPlayerOrPlaneswalker; import java.util.UUID; @@ -26,11 +22,6 @@ import java.util.UUID; */ public final class GoShintaiOfAncientWars extends CardImpl { - private static final DynamicValue xValue = new PermanentsOnBattlefieldCount( - new FilterControlledPermanent(SubType.SHRINE) - ); - private static final Hint hint = new ValueHint("Shrines you control", xValue); - public GoShintaiOfAncientWars(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{2}{R}"); @@ -44,13 +35,13 @@ public final class GoShintaiOfAncientWars extends CardImpl { // At the beginning of your end step, you may pay {1}. When you do, Go-Shintai of Ancient Wars deals X damage to target player or planeswalker, where X is the number of Shrines you control. ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility( - new DamageTargetEffect(xValue), false, "{this} deals X damage to target " + - "player or planeswalker, where X is the number of Shrines you control" + new DamageTargetEffect(ShrinesYouControlCount.WHERE_X), false, "{this} deals X damage " + + "to target player or planeswalker, where X is the number of Shrines you control" ); ability.addTarget(new TargetPlayerOrPlaneswalker()); this.addAbility(new BeginningOfEndStepTriggeredAbility( new DoWhenCostPaid(ability, new GenericManaCost(1), "Pay {1}?") - ).addHint(hint)); + ).addHint(ShrinesYouControlCount.getHint())); } private GoShintaiOfAncientWars(final GoShintaiOfAncientWars card) { diff --git a/Mage.Sets/src/mage/cards/g/GoShintaiOfBoundlessVigor.java b/Mage.Sets/src/mage/cards/g/GoShintaiOfBoundlessVigor.java index 6c50c66c30e..6f3af4a118b 100644 --- a/Mage.Sets/src/mage/cards/g/GoShintaiOfBoundlessVigor.java +++ b/Mage.Sets/src/mage/cards/g/GoShintaiOfBoundlessVigor.java @@ -1,16 +1,13 @@ package mage.cards.g; import mage.MageInt; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.DoWhenCostPaid; import mage.abilities.effects.common.counter.AddCountersTargetEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; import mage.abilities.keyword.TrampleAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -18,7 +15,6 @@ import mage.constants.SubType; import mage.constants.SuperType; import mage.counters.CounterType; import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; import mage.target.TargetPermanent; import java.util.UUID; @@ -28,11 +24,7 @@ import java.util.UUID; */ public final class GoShintaiOfBoundlessVigor extends CardImpl { - private static final FilterPermanent filter - = new FilterPermanent(SubType.SHRINE, "Shrine"); - private static final DynamicValue xValue - = new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.SHRINE)); - private static final Hint hint = new ValueHint("Shrines you control", xValue); + private static final FilterPermanent filter = new FilterPermanent(SubType.SHRINE, "Shrine"); public GoShintaiOfBoundlessVigor(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{G}"); @@ -46,15 +38,13 @@ public final class GoShintaiOfBoundlessVigor extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // At the beginning of your end step, you may pay {1}. When you do, put a +1/+1 counter on target Shrine for each Shrine you control. - ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility( - new AddCountersTargetEffect( - CounterType.P1P1.createInstance(0), xValue - ), false - ); + ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new AddCountersTargetEffect( + CounterType.P1P1.createInstance(0), ShrinesYouControlCount.FOR_EACH + ), false); ability.addTarget(new TargetPermanent(filter)); this.addAbility(new BeginningOfEndStepTriggeredAbility(new DoWhenCostPaid( ability, new GenericManaCost(1), "Pay {1}?" - )).addHint(hint)); + )).addHint(ShrinesYouControlCount.getHint())); } private GoShintaiOfBoundlessVigor(final GoShintaiOfBoundlessVigor card) { diff --git a/Mage.Sets/src/mage/cards/g/GoShintaiOfHiddenCruelty.java b/Mage.Sets/src/mage/cards/g/GoShintaiOfHiddenCruelty.java index 38c76716b3f..4a4fd0f0c5b 100644 --- a/Mage.Sets/src/mage/cards/g/GoShintaiOfHiddenCruelty.java +++ b/Mage.Sets/src/mage/cards/g/GoShintaiOfHiddenCruelty.java @@ -1,15 +1,13 @@ package mage.cards.g; import mage.MageInt; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DoWhenCostPaid; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -58,7 +56,7 @@ public final class GoShintaiOfHiddenCruelty extends CardImpl { ability.addTarget(new TargetPermanent(filter)); this.addAbility(new BeginningOfEndStepTriggeredAbility( new DoWhenCostPaid(ability, new GenericManaCost(1), "Pay {1}?") - ).addHint(GoShintaiOfHiddenCrueltyPredicate.getHint())); + ).addHint(ShrinesYouControlCount.getHint())); } private GoShintaiOfHiddenCruelty(final GoShintaiOfHiddenCruelty card) { @@ -74,13 +72,6 @@ public final class GoShintaiOfHiddenCruelty extends CardImpl { enum GoShintaiOfHiddenCrueltyPredicate implements ObjectSourcePlayerPredicate { instance; private static final FilterPermanent filter = new FilterControlledPermanent(SubType.SHRINE); - private static final Hint hint = new ValueHint( - "Shrines you control", new PermanentsOnBattlefieldCount(filter) - ); - - public static Hint getHint() { - return hint; - } @Override public boolean apply(ObjectSourcePlayer input, Game game) { diff --git a/Mage.Sets/src/mage/cards/g/GoShintaiOfLostWisdom.java b/Mage.Sets/src/mage/cards/g/GoShintaiOfLostWisdom.java index aee2e8ce8a9..efdf3706723 100644 --- a/Mage.Sets/src/mage/cards/g/GoShintaiOfLostWisdom.java +++ b/Mage.Sets/src/mage/cards/g/GoShintaiOfLostWisdom.java @@ -1,22 +1,18 @@ package mage.cards.g; import mage.MageInt; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.DoWhenCostPaid; import mage.abilities.effects.common.MillCardsTargetEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; import mage.abilities.keyword.FlyingAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.filter.common.FilterControlledPermanent; import mage.target.TargetPlayer; import java.util.UUID; @@ -26,11 +22,6 @@ import java.util.UUID; */ public final class GoShintaiOfLostWisdom extends CardImpl { - private static final DynamicValue xValue = new PermanentsOnBattlefieldCount( - new FilterControlledPermanent(SubType.SHRINE) - ); - private static final Hint hint = new ValueHint("Shrines you control", xValue); - public GoShintaiOfLostWisdom(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{U}"); @@ -44,13 +35,13 @@ public final class GoShintaiOfLostWisdom extends CardImpl { // At the beginning of your end step, you may pay {1}. When you do, target player mills X cards, where X is the number of Shrines you control. ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility( - new MillCardsTargetEffect(xValue), false, + new MillCardsTargetEffect(ShrinesYouControlCount.WHERE_X), false, "target player mills X cards, where X is the number of Shrines you control" ); ability.addTarget(new TargetPlayer()); this.addAbility(new BeginningOfEndStepTriggeredAbility(new DoWhenCostPaid( ability, new GenericManaCost(1), "Pay {1}?" - )).addHint(hint)); + )).addHint(ShrinesYouControlCount.getHint())); } private GoShintaiOfLostWisdom(final GoShintaiOfLostWisdom card) { diff --git a/Mage.Sets/src/mage/cards/g/GoShintaiOfSharedPurpose.java b/Mage.Sets/src/mage/cards/g/GoShintaiOfSharedPurpose.java index f565593f6bd..66c1398927c 100644 --- a/Mage.Sets/src/mage/cards/g/GoShintaiOfSharedPurpose.java +++ b/Mage.Sets/src/mage/cards/g/GoShintaiOfSharedPurpose.java @@ -1,21 +1,17 @@ package mage.cards.g; import mage.MageInt; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; import mage.abilities.keyword.VigilanceAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.filter.common.FilterControlledPermanent; import mage.game.permanent.token.SpiritToken; import java.util.UUID; @@ -25,11 +21,6 @@ import java.util.UUID; */ public final class GoShintaiOfSharedPurpose extends CardImpl { - private static final DynamicValue xValue = new PermanentsOnBattlefieldCount( - new FilterControlledPermanent(SubType.SHRINE) - ); - private static final Hint hint = new ValueHint("Shrines you control", xValue); - public GoShintaiOfSharedPurpose(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{3}{W}"); @@ -42,12 +33,9 @@ public final class GoShintaiOfSharedPurpose extends CardImpl { this.addAbility(VigilanceAbility.getInstance()); // At the beginning of your end step, you may pay {1}. If you do, create a 1/1 colorless Spirit creature token for each Shrine you control. - this.addAbility(new BeginningOfEndStepTriggeredAbility( - new DoIfCostPaid( - new CreateTokenEffect(new SpiritToken(), xValue), - new GenericManaCost(1) - ) - ).addHint(hint)); + this.addAbility(new BeginningOfEndStepTriggeredAbility(new DoIfCostPaid( + new CreateTokenEffect(new SpiritToken(), ShrinesYouControlCount.FOR_EACH), new GenericManaCost(1) + )).addHint(ShrinesYouControlCount.getHint())); } private GoShintaiOfSharedPurpose(final GoShintaiOfSharedPurpose card) { diff --git a/Mage.Sets/src/mage/cards/h/HondenOfCleansingFire.java b/Mage.Sets/src/mage/cards/h/HondenOfCleansingFire.java index 33833f95671..e2a8022bcc2 100644 --- a/Mage.Sets/src/mage/cards/h/HondenOfCleansingFire.java +++ b/Mage.Sets/src/mage/cards/h/HondenOfCleansingFire.java @@ -1,20 +1,15 @@ - - package mage.cards.h; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.MultipliedValue; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.filter.common.FilterControlledPermanent; import java.util.UUID; @@ -23,19 +18,15 @@ import java.util.UUID; */ public final class HondenOfCleansingFire extends CardImpl { - private static final DynamicValue xValue = new PermanentsOnBattlefieldCount( - new FilterControlledPermanent(SubType.SHRINE) - ); - private static final Hint hint = new ValueHint("Shrines you control", xValue); + private static final DynamicValue xValue = new MultipliedValue(ShrinesYouControlCount.FOR_EACH, 2); public HondenOfCleansingFire(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); this.supertype.add(SuperType.LEGENDARY); this.subtype.add(SubType.SHRINE); - // At the beginning of your upkeep, you gain 2 life for each Shrine you control. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new GainLifeEffect(new MultipliedValue(xValue, 2))).addHint(hint)); + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new GainLifeEffect(xValue)).addHint(ShrinesYouControlCount.getHint())); } private HondenOfCleansingFire(final HondenOfCleansingFire card) { diff --git a/Mage.Sets/src/mage/cards/h/HondenOfInfiniteRage.java b/Mage.Sets/src/mage/cards/h/HondenOfInfiniteRage.java index aba3e7383c7..d3951458985 100644 --- a/Mage.Sets/src/mage/cards/h/HondenOfInfiniteRage.java +++ b/Mage.Sets/src/mage/cards/h/HondenOfInfiniteRage.java @@ -1,39 +1,33 @@ package mage.cards.h; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.filter.common.FilterControlledPermanent; import mage.target.common.TargetAnyTarget; +import java.util.UUID; + /** - * * @author Loki */ public final class HondenOfInfiniteRage extends CardImpl { - private static final DynamicValue xValue = new PermanentsOnBattlefieldCount( - new FilterControlledPermanent(SubType.SHRINE) - ); - private static final Hint hint = new ValueHint("Shrines you control", xValue); - public HondenOfInfiniteRage(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); this.supertype.add(SuperType.LEGENDARY); this.subtype.add(SubType.SHRINE); // At the beginning of your upkeep, Honden of Infinite Rage deals damage to any target equal to the number of Shrines you control. - Ability ability = new BeginningOfUpkeepTriggeredAbility(new DamageTargetEffect(xValue)).addHint(hint); + Ability ability = new BeginningOfUpkeepTriggeredAbility( + new DamageTargetEffect(ShrinesYouControlCount.WHERE_X) + .setText("{this} deals damage to any target equal to the number of Shrines you control") + ).addHint(ShrinesYouControlCount.getHint()); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HondenOfLifesWeb.java b/Mage.Sets/src/mage/cards/h/HondenOfLifesWeb.java index a454a61824e..e387bb9e671 100644 --- a/Mage.Sets/src/mage/cards/h/HondenOfLifesWeb.java +++ b/Mage.Sets/src/mage/cards/h/HondenOfLifesWeb.java @@ -1,19 +1,13 @@ - - package mage.cards.h; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.filter.common.FilterControlledPermanent; import mage.game.permanent.token.SpiritToken; import java.util.UUID; @@ -23,17 +17,14 @@ import java.util.UUID; */ public final class HondenOfLifesWeb extends CardImpl { - private static final DynamicValue xValue = new PermanentsOnBattlefieldCount( - new FilterControlledPermanent(SubType.SHRINE) - ); - private static final Hint hint = new ValueHint("Shrines you control", xValue); - public HondenOfLifesWeb(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}"); this.supertype.add(SuperType.LEGENDARY); this.subtype.add(SubType.SHRINE); - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CreateTokenEffect(new SpiritToken(), xValue)).addHint(hint)); + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + new CreateTokenEffect(new SpiritToken(), ShrinesYouControlCount.FOR_EACH) + ).addHint(ShrinesYouControlCount.getHint())); } private HondenOfLifesWeb(final HondenOfLifesWeb card) { diff --git a/Mage.Sets/src/mage/cards/h/HondenOfNightsReach.java b/Mage.Sets/src/mage/cards/h/HondenOfNightsReach.java index 6741ac4a502..eebc9b261c6 100644 --- a/Mage.Sets/src/mage/cards/h/HondenOfNightsReach.java +++ b/Mage.Sets/src/mage/cards/h/HondenOfNightsReach.java @@ -1,38 +1,30 @@ package mage.cards.h; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.discard.DiscardTargetEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.filter.common.FilterControlledPermanent; import mage.target.common.TargetOpponent; +import java.util.UUID; + /** * @author Loki */ public final class HondenOfNightsReach extends CardImpl { - private static final DynamicValue xValue = new PermanentsOnBattlefieldCount( - new FilterControlledPermanent(SubType.SHRINE) - ); - private static final Hint hint = new ValueHint("Shrines you control", xValue); - public HondenOfNightsReach(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}"); this.supertype.add(SuperType.LEGENDARY); this.subtype.add(SubType.SHRINE); // At the beginning of your upkeep, target opponent discards a card for each Shrine you control. - Ability ability = new BeginningOfUpkeepTriggeredAbility(new DiscardTargetEffect(xValue)).addHint(hint); + Ability ability = new BeginningOfUpkeepTriggeredAbility(new DiscardTargetEffect(ShrinesYouControlCount.FOR_EACH)).addHint(ShrinesYouControlCount.getHint()); ability.addTarget(new TargetOpponent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HondenOfSeeingWinds.java b/Mage.Sets/src/mage/cards/h/HondenOfSeeingWinds.java index b033db25dbe..2b096f91c2f 100644 --- a/Mage.Sets/src/mage/cards/h/HondenOfSeeingWinds.java +++ b/Mage.Sets/src/mage/cards/h/HondenOfSeeingWinds.java @@ -1,19 +1,13 @@ - - package mage.cards.h; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.filter.common.FilterControlledPermanent; import java.util.UUID; @@ -22,19 +16,13 @@ import java.util.UUID; */ public final class HondenOfSeeingWinds extends CardImpl { - private static final DynamicValue xValue = new PermanentsOnBattlefieldCount( - new FilterControlledPermanent(SubType.SHRINE) - ); - private static final Hint hint = new ValueHint("Shrines you control", xValue); - public HondenOfSeeingWinds(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{U}"); this.supertype.add(SuperType.LEGENDARY); this.subtype.add(SubType.SHRINE); - // At the beginning of your upkeep, draw a card for each Shrine you control. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DrawCardSourceControllerEffect(xValue)).addHint(hint)); + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DrawCardSourceControllerEffect(ShrinesYouControlCount.FOR_EACH)).addHint(ShrinesYouControlCount.getHint())); } private HondenOfSeeingWinds(final HondenOfSeeingWinds card) { diff --git a/Mage.Sets/src/mage/cards/k/KyoshiIslandPlaza.java b/Mage.Sets/src/mage/cards/k/KyoshiIslandPlaza.java new file mode 100644 index 00000000000..6bfd4c5fe3c --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KyoshiIslandPlaza.java @@ -0,0 +1,76 @@ +package mage.cards.k; + +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class KyoshiIslandPlaza extends CardImpl { + + public KyoshiIslandPlaza(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.SHRINE); + + // When Kyoshi Island Plaza enters, search your library for up to X basic land cards, where X is the number of Shrines you control. Put those cards onto the battlefield tapped, then shuffle. + this.addAbility(new EntersBattlefieldTriggeredAbility(new KyoshiIslandPlazaEffect()) + .addHint(ShrinesYouControlCount.getHint())); + + // Whenever another Shrine you control enters, search your library for a basic land card, put it onto the battlefield tapped, then shuffle. + this.addAbility(new EntersBattlefieldAllTriggeredAbility(new SearchLibraryPutInPlayEffect( + new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true + ), StaticFilters.FILTER_ANOTHER_CONTROLLED_SHRINE)); + } + + private KyoshiIslandPlaza(final KyoshiIslandPlaza card) { + super(card); + } + + @Override + public KyoshiIslandPlaza copy() { + return new KyoshiIslandPlaza(this); + } +} + +class KyoshiIslandPlazaEffect extends OneShotEffect { + + KyoshiIslandPlazaEffect() { + super(Outcome.Benefit); + staticText = "search your library for up to X basic land cards, where X is the number of Shrines you control. " + + "Put those cards onto the battlefield tapped, then shuffle"; + } + + private KyoshiIslandPlazaEffect(final KyoshiIslandPlazaEffect effect) { + super(effect); + } + + @Override + public KyoshiIslandPlazaEffect copy() { + return new KyoshiIslandPlazaEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + int count = ShrinesYouControlCount.WHERE_X.calculate(game, source, this); + return new SearchLibraryPutInPlayEffect( + new TargetCardInLibrary(0, count, StaticFilters.FILTER_CARD_BASIC_LANDS), true + ).apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/cards/n/NorthernAirTemple.java b/Mage.Sets/src/mage/cards/n/NorthernAirTemple.java index 6187b83987f..6f92b379e66 100644 --- a/Mage.Sets/src/mage/cards/n/NorthernAirTemple.java +++ b/Mage.Sets/src/mage/cards/n/NorthernAirTemple.java @@ -3,20 +3,15 @@ package mage.cards.n; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.LoseLifeOpponentsEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.filter.StaticFilters; import java.util.UUID; @@ -25,14 +20,6 @@ import java.util.UUID; */ public final class NorthernAirTemple extends CardImpl { - private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.SHRINE), null); - private static final Hint hint = new ValueHint("Shrines you control", xValue); - private static final FilterPermanent filter = new FilterControlledPermanent(SubType.SHRINE, "another Shrine you control"); - - static { - filter.add(AnotherPredicate.instance); - } - public NorthernAirTemple(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}"); @@ -40,13 +27,13 @@ public final class NorthernAirTemple extends CardImpl { this.subtype.add(SubType.SHRINE); // When Northern Air Temple enters, each opponent loses X life and you gain X life, where X is the number of Shrines you control. - Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeOpponentsEffect(xValue) + Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeOpponentsEffect(ShrinesYouControlCount.WHERE_X) .setText("each opponent loses X life")); - ability.addEffect(new GainLifeEffect(xValue).concatBy("and")); - this.addAbility(ability.addHint(hint)); + ability.addEffect(new GainLifeEffect(ShrinesYouControlCount.WHERE_X).setText("and you gain X life, where X is the number of Shrines you control")); + this.addAbility(ability.addHint(ShrinesYouControlCount.getHint())); // Whenever another Shrine you control enters, each opponent loses 1 life and you gain 1 life. - ability = new EntersBattlefieldAllTriggeredAbility(new LoseLifeOpponentsEffect(1), filter); + ability = new EntersBattlefieldAllTriggeredAbility(new LoseLifeOpponentsEffect(1), StaticFilters.FILTER_ANOTHER_CONTROLLED_SHRINE); ability.addEffect(new GainLifeEffect(1).concatBy("and")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SanctumOfAll.java b/Mage.Sets/src/mage/cards/s/SanctumOfAll.java index c82143cf4e6..ddbfa2bead4 100644 --- a/Mage.Sets/src/mage/cards/s/SanctumOfAll.java +++ b/Mage.Sets/src/mage/cards/s/SanctumOfAll.java @@ -1,22 +1,15 @@ package mage.cards.s; import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.search.SearchLibraryGraveyardPutOntoBattlefieldEffect; -import mage.abilities.hint.ValueHint; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; 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.SuperType; +import mage.constants.*; import mage.filter.FilterCard; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -24,18 +17,13 @@ import mage.game.permanent.Permanent; import java.util.UUID; /** - * * @author htrajan */ public final class SanctumOfAll extends CardImpl { - private static final FilterPermanent filter = new FilterControlledPermanent(); private static final FilterCard filterCard = new FilterCard("Shrine card"); - static final PermanentsOnBattlefieldCount count = new PermanentsOnBattlefieldCount(filter); - static { - filter.add(SubType.SHRINE.getPredicate()); filterCard.add(SubType.SHRINE.getPredicate()); } @@ -49,7 +37,7 @@ public final class SanctumOfAll extends CardImpl { this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SearchLibraryGraveyardPutOntoBattlefieldEffect(filterCard), true)); // If an ability of another Shrine you control triggers while you control six or more Shrines, that ability triggers an additional time. - this.addAbility(new SimpleStaticAbility(new SanctumOfAllTriggerEffect()).addHint(new ValueHint("Shrines you control", count))); + this.addAbility(new SimpleStaticAbility(new SanctumOfAllTriggerEffect()).addHint(ShrinesYouControlCount.getHint())); } private SanctumOfAll(final SanctumOfAll card) { @@ -94,7 +82,7 @@ class SanctumOfAllTriggerEffect extends ReplacementEffectImpl { // Only triggers of the controller of Sanctum of All if (source.isControlledBy(event.getPlayerId())) { // Only trigger while you control six or more Shrines - int numShrines = SanctumOfAll.count.calculate(game, source, this); + int numShrines = ShrinesYouControlCount.FOR_EACH.calculate(game, source, this); if (numShrines >= 6) { // Only for triggers of other Shrines Permanent permanent = game.getPermanent(event.getSourceId()); diff --git a/Mage.Sets/src/mage/cards/s/SanctumOfCalmWaters.java b/Mage.Sets/src/mage/cards/s/SanctumOfCalmWaters.java index 1f4696f4578..e4c6560fe95 100644 --- a/Mage.Sets/src/mage/cards/s/SanctumOfCalmWaters.java +++ b/Mage.Sets/src/mage/cards/s/SanctumOfCalmWaters.java @@ -1,34 +1,23 @@ package mage.cards.s; import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.discard.DiscardControllerEffect; -import mage.abilities.hint.ValueHint; +import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; 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.FilterControlledPermanent; import java.util.UUID; /** * @author jmharmon */ - public final class SanctumOfCalmWaters extends CardImpl { - private static final FilterPermanent filter = new FilterControlledPermanent(); - private static final PermanentsOnBattlefieldCount xValue = new PermanentsOnBattlefieldCount(filter); - - static { - filter.add(SubType.SHRINE.getPredicate()); - } - public SanctumOfCalmWaters(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}"); @@ -36,10 +25,9 @@ public final class SanctumOfCalmWaters extends CardImpl { this.subtype.add(SubType.SHRINE); // At the beginning of your precombat main phase, you may draw X cards, where X is the number of Shrines you control. If you do, discard a card. - Ability ability = new BeginningOfFirstMainTriggeredAbility(new DrawCardSourceControllerEffect(xValue) - .setText("you may draw X cards, where X is the number of Shrines you control"), true - ) - .addHint(new ValueHint("Shrines you control", xValue)); + Ability ability = new BeginningOfFirstMainTriggeredAbility( + new DrawCardSourceControllerEffect(ShrinesYouControlCount.WHERE_X), true + ).addHint(ShrinesYouControlCount.getHint()); ability.addEffect(new DiscardControllerEffect(1).setText("If you do, discard a card")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SanctumOfFruitfulHarvest.java b/Mage.Sets/src/mage/cards/s/SanctumOfFruitfulHarvest.java index 049e03d2f0f..8e8767a1feb 100644 --- a/Mage.Sets/src/mage/cards/s/SanctumOfFruitfulHarvest.java +++ b/Mage.Sets/src/mage/cards/s/SanctumOfFruitfulHarvest.java @@ -1,48 +1,33 @@ package mage.cards.s; import mage.Mana; -import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.mana.DynamicManaEffect; -import mage.abilities.hint.ValueHint; +import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; 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.FilterControlledPermanent; import java.util.UUID; /** - * * @author htrajan */ public final class SanctumOfFruitfulHarvest extends CardImpl { - private static final FilterPermanent filter = new FilterControlledPermanent(); - private static final PermanentsOnBattlefieldCount xValue = new PermanentsOnBattlefieldCount(filter); - - static { - filter.add(SubType.SHRINE.getPredicate()); - } - public SanctumOfFruitfulHarvest(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); - + this.supertype.add(SuperType.LEGENDARY); this.subtype.add(SubType.SHRINE); // At the beginning of your precombat main phase, add X mana of any one color, where X is the number of Shrines you control. - this.addAbility(new BeginningOfFirstMainTriggeredAbility( - new DynamicManaEffect( - Mana.AnyMana(1), - xValue, - "add X mana of any one color, where X is the number of Shrines you control", - true) - ) - .addHint(new ValueHint("Shrines you control", xValue))); + this.addAbility(new BeginningOfFirstMainTriggeredAbility(new DynamicManaEffect( + Mana.AnyMana(1), ShrinesYouControlCount.WHERE_X, + "add X mana of any one color, where X is the number of Shrines you control", true + )).addHint(ShrinesYouControlCount.getHint())); } private SanctumOfFruitfulHarvest(final SanctumOfFruitfulHarvest card) { diff --git a/Mage.Sets/src/mage/cards/s/SanctumOfShatteredHeights.java b/Mage.Sets/src/mage/cards/s/SanctumOfShatteredHeights.java index cfaafbf6305..6f62d277894 100644 --- a/Mage.Sets/src/mage/cards/s/SanctumOfShatteredHeights.java +++ b/Mage.Sets/src/mage/cards/s/SanctumOfShatteredHeights.java @@ -3,18 +3,15 @@ package mage.cards.s; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.DiscardTargetCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.hint.ValueHint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; import mage.filter.FilterCard; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.target.common.TargetCardInHand; import mage.target.common.TargetCreatureOrPlaneswalker; @@ -28,12 +25,12 @@ import java.util.UUID; public final class SanctumOfShatteredHeights extends CardImpl { private static final FilterCard filter = new FilterCard("a land card or Shrine card"); - private static final FilterPermanent filterShrinesOnly = new FilterControlledPermanent("Shrine you control"); - private static final PermanentsOnBattlefieldCount xValue = new PermanentsOnBattlefieldCount(filterShrinesOnly); static { - filter.add(Predicates.or(CardType.LAND.getPredicate(), SubType.SHRINE.getPredicate())); - filterShrinesOnly.add(SubType.SHRINE.getPredicate()); + filter.add(Predicates.or( + CardType.LAND.getPredicate(), + SubType.SHRINE.getPredicate() + )); } public SanctumOfShatteredHeights(UUID ownerId, CardSetInfo setInfo) { @@ -43,10 +40,11 @@ public final class SanctumOfShatteredHeights extends CardImpl { this.subtype.add(SubType.SHRINE); // {1}, Discard a land card or Shrine card: Sanctum of Shattered Heights deals X damage to target creature or planeswalker, where X is the number of Shrines you control. - Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(xValue) - .setText("{this} deals X damage to target creature or planeswalker, where X is the number of Shrines you control"), - new ManaCostsImpl<>("{1}")) - .addHint(new ValueHint("Shrines you control", xValue)); + Ability ability = new SimpleActivatedAbility( + new DamageTargetEffect(ShrinesYouControlCount.WHERE_X) + .setText("{this} deals X damage to target creature or planeswalker, where X is the number of Shrines you control"), + new GenericManaCost(1) + ).addHint(ShrinesYouControlCount.getHint()); ability.addCost(new DiscardTargetCost(new TargetCardInHand(filter))); ability.addTarget(new TargetCreatureOrPlaneswalker()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/s/SanctumOfStoneFangs.java b/Mage.Sets/src/mage/cards/s/SanctumOfStoneFangs.java index b21aa11d119..b88130ad6f5 100644 --- a/Mage.Sets/src/mage/cards/s/SanctumOfStoneFangs.java +++ b/Mage.Sets/src/mage/cards/s/SanctumOfStoneFangs.java @@ -1,46 +1,34 @@ package mage.cards.s; import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.LoseLifeOpponentsEffect; -import mage.abilities.hint.ValueHint; +import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; 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.FilterControlledPermanent; import java.util.UUID; /** - * * @author htrajan */ public final class SanctumOfStoneFangs extends CardImpl { - private static final FilterPermanent filter = new FilterControlledPermanent(""); - private static final PermanentsOnBattlefieldCount xValue = new PermanentsOnBattlefieldCount(filter, null); - - static { - filter.add(SubType.SHRINE.getPredicate()); - } - public SanctumOfStoneFangs(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}"); - + this.supertype.add(SuperType.LEGENDARY); this.subtype.add(SubType.SHRINE); // At the beginning of your precombat main phase, each opponent loses X life and you gain X life, where X is the number of Shrines you control. Ability ability = new BeginningOfFirstMainTriggeredAbility( - new LoseLifeOpponentsEffect(xValue).setText("each opponent loses X life") - ) - .addHint(new ValueHint("Shrines you control", xValue)); - ability.addEffect(new GainLifeEffect(xValue).setText("and you gain X life, where X is the number of Shrines you control")); + new LoseLifeOpponentsEffect(ShrinesYouControlCount.WHERE_X).setText("each opponent loses X life") + ).addHint(ShrinesYouControlCount.getHint()); + ability.addEffect(new GainLifeEffect(ShrinesYouControlCount.WHERE_X).setText("and you gain X life, where X is the number of Shrines you control")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SanctumOfTranquilLight.java b/Mage.Sets/src/mage/cards/s/SanctumOfTranquilLight.java index ab18f92bf92..3edd1fe5766 100644 --- a/Mage.Sets/src/mage/cards/s/SanctumOfTranquilLight.java +++ b/Mage.Sets/src/mage/cards/s/SanctumOfTranquilLight.java @@ -4,19 +4,14 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.CostAdjuster; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.TapTargetEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; @@ -40,7 +35,7 @@ public final class SanctumOfTranquilLight extends CardImpl { ability.addEffect(new InfoEffect("This ability costs {1} less to activate for each Shrine you control")); ability.addTarget(new TargetCreaturePermanent()); ability.setCostAdjuster(SanctumOfTranquilLightAdjuster.instance); - this.addAbility(ability.addHint(SanctumOfTranquilLightAdjuster.getHint())); + this.addAbility(ability.addHint(ShrinesYouControlCount.getHint())); } private SanctumOfTranquilLight(final SanctumOfTranquilLight card) { @@ -56,19 +51,11 @@ public final class SanctumOfTranquilLight extends CardImpl { enum SanctumOfTranquilLightAdjuster implements CostAdjuster { instance; - private static final FilterPermanent filter = new FilterControlledPermanent(SubType.SHRINE); - private static final DynamicValue count = new PermanentsOnBattlefieldCount(filter); - private static final Hint hint = new ValueHint("Shrines you control", count); - - public static Hint getHint() { - return hint; - } - @Override public void reduceCost(Ability ability, Game game) { Player controller = game.getPlayer(ability.getControllerId()); if (controller != null) { - CardUtil.reduceCost(ability, count.calculate(game, ability, null)); + CardUtil.reduceCost(ability, ShrinesYouControlCount.FOR_EACH.calculate(game, ability, null)); } } } diff --git a/Mage.Sets/src/mage/cards/s/SouthernAirTemple.java b/Mage.Sets/src/mage/cards/s/SouthernAirTemple.java index ce184fcb615..b73e9dd010f 100644 --- a/Mage.Sets/src/mage/cards/s/SouthernAirTemple.java +++ b/Mage.Sets/src/mage/cards/s/SouthernAirTemple.java @@ -2,21 +2,15 @@ package mage.cards.s; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.counter.AddCountersAllEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; import mage.counters.CounterType; -import mage.filter.FilterPermanent; import mage.filter.StaticFilters; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.mageobject.AnotherPredicate; import java.util.UUID; @@ -25,14 +19,6 @@ import java.util.UUID; */ public final class SouthernAirTemple extends CardImpl { - private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.SHRINE)); - private static final Hint hint = new ValueHint("Shrines you control", xValue); - private static final FilterPermanent filter = new FilterControlledPermanent(SubType.SHRINE, "another Shrine you control"); - - static { - filter.add(AnotherPredicate.instance); - } - public SouthernAirTemple(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); @@ -41,13 +27,13 @@ public final class SouthernAirTemple extends CardImpl { // When Southern Air Temple enters, put X +1/+1 counters on each creature you control, where X is the number of Shrines you control. this.addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersAllEffect( - CounterType.P1P1.createInstance(), xValue, StaticFilters.FILTER_CONTROLLED_CREATURE - ).setText("put X +1/+1 counters on each creature you control, where X is the number of Shrines you control")).addHint(hint)); + CounterType.P1P1.createInstance(), ShrinesYouControlCount.WHERE_X, StaticFilters.FILTER_CONTROLLED_CREATURE + ).setText("put X +1/+1 counters on each creature you control, where X is the number of Shrines you control")).addHint(ShrinesYouControlCount.getHint())); // Whenever another Shrine you control enters, put a +1/+1 counter on each creature you control. this.addAbility(new EntersBattlefieldAllTriggeredAbility(new AddCountersAllEffect( CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE - ), filter)); + ), StaticFilters.FILTER_ANOTHER_CONTROLLED_SHRINE)); } private SouthernAirTemple(final SouthernAirTemple card) { diff --git a/Mage.Sets/src/mage/cards/t/TheSpiritOasis.java b/Mage.Sets/src/mage/cards/t/TheSpiritOasis.java index 750985f58ae..555db17f626 100644 --- a/Mage.Sets/src/mage/cards/t/TheSpiritOasis.java +++ b/Mage.Sets/src/mage/cards/t/TheSpiritOasis.java @@ -2,19 +2,14 @@ package mage.cards.t; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.ShrinesYouControlCount; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.filter.StaticFilters; import java.util.UUID; @@ -23,14 +18,6 @@ import java.util.UUID; */ public final class TheSpiritOasis extends CardImpl { - private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.SHRINE)); - private static final Hint hint = new ValueHint("Shrines you control", xValue); - private static final FilterPermanent filter = new FilterControlledPermanent(SubType.SHRINE, "another Shrine you control"); - - static { - filter.add(AnotherPredicate.instance); - } - public TheSpiritOasis(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); @@ -38,10 +25,10 @@ public final class TheSpiritOasis extends CardImpl { this.subtype.add(SubType.SHRINE); // When The Spirit Oasis enters, draw a card for each Shrine you control. - this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(xValue))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(ShrinesYouControlCount.FOR_EACH))); // Whenever another Shrine you control enters, draw a card. - this.addAbility(new EntersBattlefieldAllTriggeredAbility(new DrawCardSourceControllerEffect(1), filter)); + this.addAbility(new EntersBattlefieldAllTriggeredAbility(new DrawCardSourceControllerEffect(1), StaticFilters.FILTER_ANOTHER_CONTROLLED_SHRINE)); } private TheSpiritOasis(final TheSpiritOasis card) { diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 4bb14ee9a0f..e6e834b21c0 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -198,6 +198,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("Knowledge Seeker", 60, Rarity.UNCOMMON, mage.cards.k.KnowledgeSeeker.class)); cards.add(new SetCardInfo("Kyoshi Battle Fan", 257, Rarity.COMMON, mage.cards.k.KyoshiBattleFan.class)); + cards.add(new SetCardInfo("Kyoshi Island Plaza", 184, Rarity.UNCOMMON, mage.cards.k.KyoshiIslandPlaza.class)); cards.add(new SetCardInfo("Kyoshi Village", 271, Rarity.COMMON, mage.cards.k.KyoshiVillage.class)); cards.add(new SetCardInfo("Kyoshi Warriors", 26, Rarity.COMMON, mage.cards.k.KyoshiWarriors.class)); cards.add(new SetCardInfo("Leaves from the Vine", 185, Rarity.UNCOMMON, mage.cards.l.LeavesFromTheVine.class)); diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ShrinesYouControlCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ShrinesYouControlCount.java new file mode 100644 index 00000000000..10c4b2ef290 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ShrinesYouControlCount.java @@ -0,0 +1,55 @@ +package mage.abilities.dynamicvalue.common; + +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; + +/** + * @author TheElk801 + */ +public enum ShrinesYouControlCount implements DynamicValue { + WHERE_X("X", "the number of Shrines you control"), + FOR_EACH("1", "Shrine you control"); + + private static final Hint hint = new ValueHint("Shrines you control", WHERE_X); + + public static Hint getHint() { + return hint; + } + + private static final FilterPermanent filter = new FilterControlledPermanent(SubType.SHRINE); + + private final String number; + private final String message; + + ShrinesYouControlCount(String number, String message) { + this.number = number; + this.message = message; + } + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return game.getBattlefield().count(filter, sourceAbility.getControllerId(), sourceAbility, game); + } + + @Override + public ShrinesYouControlCount copy() { + return this; + } + + @Override + public String getMessage() { + return message; + } + + @Override + public String toString() { + return number; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/GainLifeEffect.java b/Mage/src/main/java/mage/abilities/effects/common/GainLifeEffect.java index 67307e1916b..a49c919887c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/GainLifeEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/GainLifeEffect.java @@ -54,6 +54,7 @@ public class GainLifeEffect extends OneShotEffect { @Override public String getText(Mode mode) { + // TODO: this text generation probably needs reworking if (staticText != null && !staticText.isEmpty()) { return staticText; } diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 748c56a2dec..01547efbb0b 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -902,6 +902,13 @@ public final class StaticFilters { FILTER_CONTROLLED_SAMURAI_OR_WARRIOR.setLockedFilter(true); } + public static final FilterControlledPermanent FILTER_ANOTHER_CONTROLLED_SHRINE = new FilterControlledPermanent(SubType.SHRINE, "another Shrine you control"); + + static { + FILTER_ANOTHER_CONTROLLED_SHRINE.add(AnotherPredicate.instance); + FILTER_ANOTHER_CONTROLLED_SHRINE.setLockedFilter(true); + } + public static final FilterPlaneswalkerPermanent FILTER_PERMANENT_PLANESWALKER = new FilterPlaneswalkerPermanent(); static {