From 0b714946b08a3e5a1a02de06b2ca3cbd5908dedb Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 31 May 2025 22:00:13 -0400 Subject: [PATCH] Rework affinity implementation (#13707) * rework affinity implementation * move filters --- .../src/mage/cards/a/AngelicObserver.java | 16 +-- Mage.Sets/src/mage/cards/a/ArchwayAngel.java | 4 +- .../src/mage/cards/a/ArgivianPhalanx.java | 14 +-- .../mage/cards/b/BanishToAnotherUniverse.java | 20 +-- Mage.Sets/src/mage/cards/b/BanquetGuests.java | 18 +-- Mage.Sets/src/mage/cards/b/BartzAndBoko.java | 11 +- Mage.Sets/src/mage/cards/b/BrineGiant.java | 17 +-- Mage.Sets/src/mage/cards/d/DrossGolem.java | 14 +-- Mage.Sets/src/mage/cards/g/GateColossus.java | 14 +-- .../src/mage/cards/g/GatebreakerRam.java | 4 +- .../src/mage/cards/g/GatekeeperGargoyle.java | 4 +- .../mage/cards/g/GlaiveOfTheGuildpact.java | 4 +- .../src/mage/cards/g/GoldwardensGambit.java | 30 ++--- Mage.Sets/src/mage/cards/h/HellspurBrute.java | 22 +--- Mage.Sets/src/mage/cards/h/HoldTheGates.java | 5 +- .../src/mage/cards/i/IcebreakerKraken.java | 14 +-- Mage.Sets/src/mage/cards/j/JunkWinder.java | 25 +--- .../cards/m/MillicentRestlessRevenant.java | 18 +-- .../src/mage/cards/n/NahiriForgedInFury.java | 22 +--- .../src/mage/cards/o/OxiddaFinisher.java | 23 +--- Mage.Sets/src/mage/cards/o/OxiddaGolem.java | 14 +-- .../mage/cards/p/PearlEarImperialAdvisor.java | 19 +-- Mage.Sets/src/mage/cards/p/Polliwallop.java | 17 +-- Mage.Sets/src/mage/cards/r/RazorGolem.java | 13 +- Mage.Sets/src/mage/cards/r/RebelSalvo.java | 19 +-- .../src/mage/cards/r/RidersOfTheMark.java | 19 +-- Mage.Sets/src/mage/cards/s/ScalesOfShale.java | 15 +-- .../src/mage/cards/s/SkyBlessedSamurai.java | 17 +-- Mage.Sets/src/mage/cards/s/SpireGolem.java | 14 +-- Mage.Sets/src/mage/cards/t/TangleGolem.java | 12 +- .../src/mage/cards/t/TheCircleOfLoyalty.java | 16 +-- .../src/mage/cards/t/TheDalekEmperor.java | 8 +- .../src/mage/cards/t/TomikWielderOfLaw.java | 23 +--- .../src/mage/cards/t/TravelTheOverworld.java | 15 +-- .../src/mage/cards/u/UrzaChiefArtificer.java | 21 +--- ...trolHint.java => GatesYouControlHint.java} | 4 +- .../AffinityAbility.java} | 51 ++++++-- .../keyword/AffinityForArtifactsAbility.java | 18 +-- .../keyword/AffinityForLandTypeAbility.java | 42 ------- .../java/mage/constants/AffinityType.java | 119 ++++++++++++++++++ .../main/java/mage/filter/StaticFilters.java | 1 - 41 files changed, 310 insertions(+), 466 deletions(-) rename Mage/src/main/java/mage/abilities/hint/common/{GateYouControlHint.java => GatesYouControlHint.java} (75%) rename Mage/src/main/java/mage/abilities/{effects/common/AffinityEffect.java => keyword/AffinityAbility.java} (50%) delete mode 100644 Mage/src/main/java/mage/abilities/keyword/AffinityForLandTypeAbility.java create mode 100644 Mage/src/main/java/mage/constants/AffinityType.java diff --git a/Mage.Sets/src/mage/cards/a/AngelicObserver.java b/Mage.Sets/src/mage/cards/a/AngelicObserver.java index 9829ad683ef..845b67428cd 100644 --- a/Mage.Sets/src/mage/cards/a/AngelicObserver.java +++ b/Mage.Sets/src/mage/cards/a/AngelicObserver.java @@ -1,18 +1,13 @@ package mage.cards.a; import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; import java.util.UUID; @@ -21,9 +16,6 @@ import java.util.UUID; */ public final class AngelicObserver extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.CITIZEN, "Citizens"); - private static final Hint hint = new ValueHint("Citizens you control", new PermanentsOnBattlefieldCount(filter)); - public AngelicObserver(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}"); @@ -32,8 +24,8 @@ public final class AngelicObserver extends CardImpl { this.power = new MageInt(3); this.toughness = new MageInt(3); - // This spell costs {1} less to cast for each Citizen you control. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).setRuleAtTheTop(true).addHint(hint)); + // Affinity for Citizens + this.addAbility(new AffinityAbility(AffinityType.CITIZENS)); // Flying this.addAbility(FlyingAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/a/ArchwayAngel.java b/Mage.Sets/src/mage/cards/a/ArchwayAngel.java index 03ffedcede5..4f7ef212252 100644 --- a/Mage.Sets/src/mage/cards/a/ArchwayAngel.java +++ b/Mage.Sets/src/mage/cards/a/ArchwayAngel.java @@ -5,7 +5,7 @@ import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.hint.common.GateYouControlHint; +import mage.abilities.hint.common.GatesYouControlHint; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -39,7 +39,7 @@ public final class ArchwayAngel extends CardImpl { // When Archway Angel enters the battlefield, you gain 2 life for each Gate you control. Ability ability = new EntersBattlefieldTriggeredAbility(new GainLifeEffect(new PermanentsOnBattlefieldCount(filter, 2))); - ability.addHint(GateYouControlHint.instance); + ability.addHint(GatesYouControlHint.instance); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/ArgivianPhalanx.java b/Mage.Sets/src/mage/cards/a/ArgivianPhalanx.java index f8c6e515b47..e8d4f6da868 100644 --- a/Mage.Sets/src/mage/cards/a/ArgivianPhalanx.java +++ b/Mage.Sets/src/mage/cards/a/ArgivianPhalanx.java @@ -1,17 +1,13 @@ package mage.cards.a; import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.AffinityEffect; -import mage.abilities.hint.common.CreaturesYouControlHint; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.common.FilterControlledPermanent; import java.util.UUID; @@ -20,8 +16,6 @@ import java.util.UUID; */ public final class ArgivianPhalanx extends CardImpl { - static final FilterControlledPermanent filter = new FilterControlledCreaturePermanent("creatures"); - public ArgivianPhalanx(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}"); @@ -31,8 +25,8 @@ public final class ArgivianPhalanx extends CardImpl { this.power = new MageInt(4); this.toughness = new MageInt(4); - // This spell costs {1} less to cast for each creature you control. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).addHint(CreaturesYouControlHint.instance)); + // Affinity for creatures + this.addAbility(new AffinityAbility(AffinityType.CREATURES)); // Vigilance this.addAbility(VigilanceAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/b/BanishToAnotherUniverse.java b/Mage.Sets/src/mage/cards/b/BanishToAnotherUniverse.java index 50bfd5f4231..0b397fc34f0 100644 --- a/Mage.Sets/src/mage/cards/b/BanishToAnotherUniverse.java +++ b/Mage.Sets/src/mage/cards/b/BanishToAnotherUniverse.java @@ -2,19 +2,13 @@ package mage.cards.b; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; -import mage.constants.Zone; import mage.filter.StaticFilters; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.mageobject.HistoricPredicate; import mage.target.TargetPermanent; import java.util.UUID; @@ -24,19 +18,11 @@ import java.util.UUID; */ public final class BanishToAnotherUniverse extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("historic permanents"); - private static final Hint hint = new ValueHint("historic permanents you control", new PermanentsOnBattlefieldCount(filter)); - - static { - filter.add(HistoricPredicate.instance); - } - public BanishToAnotherUniverse(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{W}"); // Affinity for historic permanents - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)) - .addHint(hint)); + this.addAbility(new AffinityAbility(AffinityType.HISTORIC)); // When Banish to Another Universe enters the battlefield, exile target nonland permanent an opponent controls until Banish to Another Universe leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); diff --git a/Mage.Sets/src/mage/cards/b/BanquetGuests.java b/Mage.Sets/src/mage/cards/b/BanquetGuests.java index 6f58fb799bc..66ec17774b3 100644 --- a/Mage.Sets/src/mage/cards/b/BanquetGuests.java +++ b/Mage.Sets/src/mage/cards/b/BanquetGuests.java @@ -4,26 +4,21 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.IndestructibleAbility; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; -import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.StaticFilters; -import mage.target.common.TargetControlledPermanent; import java.util.UUID; @@ -32,8 +27,6 @@ import java.util.UUID; */ public final class BanquetGuests extends CardImpl { - private static final Hint hint = new ValueHint("Food you control", new PermanentsOnBattlefieldCount(StaticFilters.FILTER_CONTROLLED_FOOD)); - public BanquetGuests(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{X}{G}{W}"); @@ -43,12 +36,7 @@ public final class BanquetGuests extends CardImpl { this.toughness = new MageInt(0); // Affinity for Food - this.addAbility( - new SimpleStaticAbility( - Zone.ALL, - new AffinityEffect(StaticFilters.FILTER_CONTROLLED_FOOD) - ).addHint(hint) - ); + this.addAbility(new AffinityAbility(AffinityType.FOOD)); // Trample this.addAbility(TrampleAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/b/BartzAndBoko.java b/Mage.Sets/src/mage/cards/b/BartzAndBoko.java index 968359caf92..f7f76eb2b8e 100644 --- a/Mage.Sets/src/mage/cards/b/BartzAndBoko.java +++ b/Mage.Sets/src/mage/cards/b/BartzAndBoko.java @@ -3,12 +3,8 @@ package mage.cards.b; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.AffinityEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -26,9 +22,6 @@ import java.util.UUID; */ public final class BartzAndBoko extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.BIRD, "Birds"); - private static final Hint hint = new ValueHint("Birds you control", new PermanentsOnBattlefieldCount(filter)); - public BartzAndBoko(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); @@ -39,7 +32,7 @@ public final class BartzAndBoko extends CardImpl { this.toughness = new MageInt(3); // Affinity for Birds - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).setRuleAtTheTop(true).addHint(hint)); + this.addAbility(new AffinityAbility(AffinityType.BIRDS)); // When Bartz and Boko enters, each other Bird you control deals damage equal to its power to target creature an opponent controls. Ability ability = new EntersBattlefieldTriggeredAbility(new BartzAndBokoEffect()); diff --git a/Mage.Sets/src/mage/cards/b/BrineGiant.java b/Mage.Sets/src/mage/cards/b/BrineGiant.java index 074145eb82a..349c8bfcb60 100644 --- a/Mage.Sets/src/mage/cards/b/BrineGiant.java +++ b/Mage.Sets/src/mage/cards/b/BrineGiant.java @@ -1,18 +1,12 @@ package mage.cards.b; import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.common.FilterControlledEnchantmentPermanent; -import mage.filter.common.FilterControlledPermanent; import java.util.UUID; @@ -21,9 +15,6 @@ import java.util.UUID; */ public final class BrineGiant extends CardImpl { - static final FilterControlledPermanent filter = new FilterControlledEnchantmentPermanent("enchantments"); - private static final Hint hint = new ValueHint("Enchantments you control", new PermanentsOnBattlefieldCount(filter)); - public BrineGiant(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{U}"); @@ -31,8 +22,8 @@ public final class BrineGiant extends CardImpl { this.power = new MageInt(5); this.toughness = new MageInt(6); - // This spell costs {1} less to cast for each enchantment you control. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).addHint(hint)); + // Affinity for enchantments + this.addAbility(new AffinityAbility(AffinityType.ENCHANTMENTS)); } private BrineGiant(final BrineGiant card) { diff --git a/Mage.Sets/src/mage/cards/d/DrossGolem.java b/Mage.Sets/src/mage/cards/d/DrossGolem.java index 3a1515721ec..cfc213b6799 100644 --- a/Mage.Sets/src/mage/cards/d/DrossGolem.java +++ b/Mage.Sets/src/mage/cards/d/DrossGolem.java @@ -1,30 +1,30 @@ - package mage.cards.d; -import java.util.UUID; import mage.MageInt; -import mage.abilities.keyword.AffinityForLandTypeAbility; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.FearAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.SubType; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class DrossGolem extends CardImpl { public DrossGolem(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{5}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}"); this.subtype.add(SubType.GOLEM); this.power = new MageInt(3); this.toughness = new MageInt(2); // Affinity for Swamps - this.addAbility(new AffinityForLandTypeAbility(SubType.SWAMP, "Swamps")); - + this.addAbility(new AffinityAbility(AffinityType.SWAMPS)); + // Fear this.addAbility(FearAbility.getInstance()); } diff --git a/Mage.Sets/src/mage/cards/g/GateColossus.java b/Mage.Sets/src/mage/cards/g/GateColossus.java index c83c89ec368..9b88eee5c47 100644 --- a/Mage.Sets/src/mage/cards/g/GateColossus.java +++ b/Mage.Sets/src/mage/cards/g/GateColossus.java @@ -2,13 +2,12 @@ package mage.cards.g; import mage.MageInt; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.PutOnLibrarySourceEffect; -import mage.abilities.hint.common.GateYouControlHint; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.DauntAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; @@ -21,8 +20,7 @@ import java.util.UUID; */ public final class GateColossus extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.GATE, "Gates"); - private static final FilterControlledPermanent filter2 = new FilterControlledPermanent(SubType.GATE); + private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.GATE); public GateColossus(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{8}"); @@ -31,8 +29,8 @@ public final class GateColossus extends CardImpl { this.power = new MageInt(8); this.toughness = new MageInt(8); - // This spell costs {1} less to cast for each Gate you control. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).addHint(GateYouControlHint.instance)); + // Affinity for Gates + this.addAbility(new AffinityAbility(AffinityType.GATES)); // Gate Colossus can't be blocked by creatures with power 2 or less. this.addAbility(new DauntAbility()); @@ -42,7 +40,7 @@ public final class GateColossus extends CardImpl { Zone.GRAVEYARD, new PutOnLibrarySourceEffect( true, "put this card from your graveyard on top of your library" - ), filter2, true + ), filter, true )); } diff --git a/Mage.Sets/src/mage/cards/g/GatebreakerRam.java b/Mage.Sets/src/mage/cards/g/GatebreakerRam.java index bcb422f859b..8043d5e2d62 100644 --- a/Mage.Sets/src/mage/cards/g/GatebreakerRam.java +++ b/Mage.Sets/src/mage/cards/g/GatebreakerRam.java @@ -10,7 +10,7 @@ import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; -import mage.abilities.hint.common.GateYouControlHint; +import mage.abilities.hint.common.GatesYouControlHint; import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; @@ -51,7 +51,7 @@ public final class GatebreakerRam extends CardImpl { this.addAbility(new SimpleStaticAbility( new BoostSourceEffect(xValue, xValue, Duration.WhileOnBattlefield) .setText("{this} gets +1/+1 for each Gate you control.") - ).addHint(GateYouControlHint.instance)); + ).addHint(GatesYouControlHint.instance)); // As long as you control two or more Gates, Gatebreaker Ram has vigilance and trample. Ability ability = new SimpleStaticAbility(new ConditionalContinuousEffect( diff --git a/Mage.Sets/src/mage/cards/g/GatekeeperGargoyle.java b/Mage.Sets/src/mage/cards/g/GatekeeperGargoyle.java index 6878a0aa607..82a802d0aa3 100644 --- a/Mage.Sets/src/mage/cards/g/GatekeeperGargoyle.java +++ b/Mage.Sets/src/mage/cards/g/GatekeeperGargoyle.java @@ -4,7 +4,7 @@ import mage.MageInt; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.dynamicvalue.common.GateYouControlCount; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.hint.common.GateYouControlHint; +import mage.abilities.hint.common.GatesYouControlHint; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -35,7 +35,7 @@ public final class GatekeeperGargoyle extends CardImpl { CounterType.P1P1.createInstance(), GateYouControlCount.instance, true ), "with a +1/+1 counter on it for each Gate you control" - ).addHint(GateYouControlHint.instance)); + ).addHint(GatesYouControlHint.instance)); } private GatekeeperGargoyle(final GatekeeperGargoyle card) { diff --git a/Mage.Sets/src/mage/cards/g/GlaiveOfTheGuildpact.java b/Mage.Sets/src/mage/cards/g/GlaiveOfTheGuildpact.java index 42effa53c6a..2e2861158c3 100644 --- a/Mage.Sets/src/mage/cards/g/GlaiveOfTheGuildpact.java +++ b/Mage.Sets/src/mage/cards/g/GlaiveOfTheGuildpact.java @@ -6,7 +6,7 @@ import mage.abilities.dynamicvalue.common.GateYouControlCount; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; -import mage.abilities.hint.common.GateYouControlHint; +import mage.abilities.hint.common.GatesYouControlHint; import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.MenaceAbility; import mage.abilities.keyword.VigilanceAbility; @@ -36,7 +36,7 @@ public final class GlaiveOfTheGuildpact extends CardImpl { ability.addEffect(new GainAbilityAttachedEffect( new MenaceAbility(), AttachmentType.EQUIPMENT ).setText("and menace. (A creature with menace can't be blocked except by two or more creatures.)")); - ability.addHint(GateYouControlHint.instance); + ability.addHint(GatesYouControlHint.instance); this.addAbility(ability); // Equip {3} diff --git a/Mage.Sets/src/mage/cards/g/GoldwardensGambit.java b/Mage.Sets/src/mage/cards/g/GoldwardensGambit.java index 15d5e32dd4f..8d521308131 100644 --- a/Mage.Sets/src/mage/cards/g/GoldwardensGambit.java +++ b/Mage.Sets/src/mage/cards/g/GoldwardensGambit.java @@ -1,18 +1,17 @@ package mage.cards.g; import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.common.FilterControlledPermanent; +import mage.constants.AffinityType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.RebelRedToken; @@ -28,18 +27,11 @@ import java.util.UUID; */ public final class GoldwardensGambit extends CardImpl { - private static final FilterControlledPermanent filter - = new FilterControlledPermanent(SubType.EQUIPMENT, "Equipment"); - - private static final Hint hint = new ValueHint( - "Equipment you control", new PermanentsOnBattlefieldCount(filter) - ); - public GoldwardensGambit(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{6}{R}{R}"); // Affinity for Equipment - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).addHint(hint)); + this.addAbility(new AffinityAbility(AffinityType.EQUIPMENT)); // Create five 2/2 red Rebel creature tokens. They gain haste until end of turn. For each of those tokens, you may attach an Equipment you control to it. this.getSpellAbility().addEffect(new GoldwardensGambitEffect()); @@ -53,10 +45,6 @@ public final class GoldwardensGambit extends CardImpl { public GoldwardensGambit copy() { return new GoldwardensGambit(this); } - - public static FilterControlledPermanent getFilter() { - return filter; - } } class GoldwardensGambitEffect extends OneShotEffect { @@ -87,7 +75,7 @@ class GoldwardensGambitEffect extends OneShotEffect { game.addEffect(new GainAbilityTargetEffect( HasteAbility.getInstance(), Duration.EndOfTurn ).setTargetPointer(new FixedTargets(token, game)), source); - if (game.getBattlefield().count(GoldwardensGambit.getFilter(), source.getControllerId(), source, game) < 1) { + if (game.getBattlefield().count(StaticFilters.FILTER_CONTROLLED_PERMANENT_EQUIPMENT, source.getControllerId(), source, game) < 1) { return true; } for (UUID tokenId : token.getLastAddedTokenIds()) { @@ -98,7 +86,7 @@ class GoldwardensGambitEffect extends OneShotEffect { )) { continue; } - TargetPermanent target = new TargetPermanent(0, 1, GoldwardensGambit.getFilter(), true); + TargetPermanent target = new TargetPermanent(0, 1, StaticFilters.FILTER_CONTROLLED_PERMANENT_EQUIPMENT, true); player.choose(Outcome.BoostCreature, target, source, game); permanent.addAttachment(target.getFirstTarget(), source, game); } diff --git a/Mage.Sets/src/mage/cards/h/HellspurBrute.java b/Mage.Sets/src/mage/cards/h/HellspurBrute.java index 59417867a30..3106b271c65 100644 --- a/Mage.Sets/src/mage/cards/h/HellspurBrute.java +++ b/Mage.Sets/src/mage/cards/h/HellspurBrute.java @@ -1,19 +1,13 @@ package mage.cards.h; import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.mageobject.OutlawPredicate; import java.util.UUID; @@ -22,16 +16,6 @@ import java.util.UUID; */ public final class HellspurBrute extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("outlaws"); - - static { - filter.add(OutlawPredicate.instance); - } - - private static final Hint hint = new ValueHint( - "Outlaws you control", new PermanentsOnBattlefieldCount(filter) - ); - public HellspurBrute(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); @@ -41,7 +25,7 @@ public final class HellspurBrute extends CardImpl { this.toughness = new MageInt(4); // Affinity for outlaws - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).addHint(hint)); + this.addAbility(new AffinityAbility(AffinityType.OUTLAWS)); // Trample this.addAbility(TrampleAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/h/HoldTheGates.java b/Mage.Sets/src/mage/cards/h/HoldTheGates.java index b4ff9cf5c6e..e89b9f9ef44 100644 --- a/Mage.Sets/src/mage/cards/h/HoldTheGates.java +++ b/Mage.Sets/src/mage/cards/h/HoldTheGates.java @@ -6,13 +6,12 @@ import mage.abilities.dynamicvalue.common.GateYouControlCount; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.hint.common.GateYouControlHint; +import mage.abilities.hint.common.GatesYouControlHint; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Zone; import mage.filter.StaticFilters; import java.util.UUID; @@ -33,7 +32,7 @@ public final class HoldTheGates extends CardImpl { new GainAbilityControlledEffect(VigilanceAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES_CONTROLLED) .setText("and have vigilance") ); - ability.addHint(GateYouControlHint.instance); + ability.addHint(GatesYouControlHint.instance); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/i/IcebreakerKraken.java b/Mage.Sets/src/mage/cards/i/IcebreakerKraken.java index 3440213a5c2..ea59ea744de 100644 --- a/Mage.Sets/src/mage/cards/i/IcebreakerKraken.java +++ b/Mage.Sets/src/mage/cards/i/IcebreakerKraken.java @@ -4,22 +4,18 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.DontUntapInPlayersNextUntapStepAllEffect; import mage.abilities.effects.common.ReturnToHandSourceEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.constants.Zone; import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.filter.common.FilterControlledPermanent; @@ -39,8 +35,6 @@ public final class IcebreakerKraken extends CardImpl { filter.add(SuperType.SNOW.getPredicate()); } - private static final Hint hint = new ValueHint("Snow lands you control", new PermanentsOnBattlefieldCount(filter)); - public IcebreakerKraken(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{10}{U}{U}"); @@ -49,8 +43,8 @@ public final class IcebreakerKraken extends CardImpl { this.power = new MageInt(8); this.toughness = new MageInt(8); - // This spell costs {1} less to cast for each snow land you control. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).addHint(hint)); + // Affinity for snow lands + this.addAbility(new AffinityAbility(AffinityType.SNOW_LANDS)); // When Icebreaker Kraken enters the battlefield, artifacts and creatures target opponent controls don't untap during that player's next untap step. Effect effect = new DontUntapInPlayersNextUntapStepAllEffect(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE); diff --git a/Mage.Sets/src/mage/cards/j/JunkWinder.java b/Mage.Sets/src/mage/cards/j/JunkWinder.java index 34865ac6ce8..70ea3f64e11 100644 --- a/Mage.Sets/src/mage/cards/j/JunkWinder.java +++ b/Mage.Sets/src/mage/cards/j/JunkWinder.java @@ -3,24 +3,15 @@ package mage.cards.j; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; import mage.abilities.effects.common.TapTargetEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.TargetController; -import mage.constants.Zone; -import mage.filter.FilterPermanent; import mage.filter.StaticFilters; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.common.FilterNonlandPermanent; -import mage.filter.predicate.permanent.TokenPredicate; import mage.target.TargetPermanent; import java.util.UUID; @@ -30,16 +21,6 @@ import java.util.UUID; */ public final class JunkWinder extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("tokens"); - private static final FilterPermanent filter2 = new FilterNonlandPermanent("nonland permanent an opponent controls"); - - static { - filter.add(TokenPredicate.TRUE); - filter2.add(TargetController.OPPONENT.getControllerPredicate()); - } - - private static final Hint hint = new ValueHint("Tokens you control", new PermanentsOnBattlefieldCount(filter)); - public JunkWinder(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}"); @@ -48,7 +29,7 @@ public final class JunkWinder extends CardImpl { this.toughness = new MageInt(6); // Affinity for tokens - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).addHint(hint)); + this.addAbility(new AffinityAbility(AffinityType.TOKENS)); // Whenever a token you control enters, tap target nonland permanent an opponent controls. It doesn't untap during its controller's next untap step. Ability ability = new EntersBattlefieldControlledTriggeredAbility( diff --git a/Mage.Sets/src/mage/cards/m/MillicentRestlessRevenant.java b/Mage.Sets/src/mage/cards/m/MillicentRestlessRevenant.java index 7d46e8984dc..39cca31950d 100644 --- a/Mage.Sets/src/mage/cards/m/MillicentRestlessRevenant.java +++ b/Mage.Sets/src/mage/cards/m/MillicentRestlessRevenant.java @@ -3,19 +3,12 @@ package mage.cards.m; import mage.MageInt; import mage.MageObject; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; 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.constants.Zone; +import mage.constants.*; import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.permanent.TokenPredicate; @@ -33,9 +26,6 @@ import java.util.UUID; */ public final class MillicentRestlessRevenant extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.SPIRIT, "Spirits"); - private static final Hint hint = new ValueHint("Spirits you control", new PermanentsOnBattlefieldCount(filter)); - public MillicentRestlessRevenant(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}{U}"); @@ -45,8 +35,8 @@ public final class MillicentRestlessRevenant extends CardImpl { this.power = new MageInt(4); this.toughness = new MageInt(4); - // This spell costs {1} less to cast for each Spirit you control. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).addHint(hint)); + // Affinity for Spirits + this.addAbility(new AffinityAbility(AffinityType.SPIRITS)); // Flying this.addAbility(FlyingAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/n/NahiriForgedInFury.java b/Mage.Sets/src/mage/cards/n/NahiriForgedInFury.java index 81767b74734..291781b2532 100644 --- a/Mage.Sets/src/mage/cards/n/NahiriForgedInFury.java +++ b/Mage.Sets/src/mage/cards/n/NahiriForgedInFury.java @@ -3,20 +3,14 @@ package mage.cards.n; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.permanent.EquippedPredicate; import mage.game.Game; import mage.players.Player; @@ -26,19 +20,12 @@ import java.util.UUID; * @author correl */ public final class NahiriForgedInFury extends CardImpl { - private static final FilterControlledPermanent equipmentFilter = new FilterControlledPermanent(SubType.EQUIPMENT, - "Equipment"); + private static final FilterControlledCreaturePermanent equippedFilter = new FilterControlledCreaturePermanent( "an equipped creature you control"); - private static final Hint hint = new ValueHint( - "Equipment you control", new PermanentsOnBattlefieldCount(equipmentFilter)); - - static { - equippedFilter.add(EquippedPredicate.instance); - } public NahiriForgedInFury(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[] { CardType.CREATURE }, "{4}{R}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{W}"); this.supertype.add(SuperType.LEGENDARY); this.subtype.add(SubType.KOR); @@ -47,7 +34,8 @@ public final class NahiriForgedInFury extends CardImpl { this.toughness = new MageInt(4); // Affinity for Equipment - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(equipmentFilter)).addHint(hint)); + this.addAbility(new AffinityAbility(AffinityType.EQUIPMENT)); + // Whenever an equipped creature you control attacks, exile the top card // of your library. You may play that card this turn. You may cast // Equipment spells this way without paying their mana costs. diff --git a/Mage.Sets/src/mage/cards/o/OxiddaFinisher.java b/Mage.Sets/src/mage/cards/o/OxiddaFinisher.java index 395ca9c0410..3df56a7b716 100644 --- a/Mage.Sets/src/mage/cards/o/OxiddaFinisher.java +++ b/Mage.Sets/src/mage/cards/o/OxiddaFinisher.java @@ -1,32 +1,21 @@ package mage.cards.o; -import java.util.UUID; - import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; -import mage.constants.SubType; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; -import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; +import mage.constants.SubType; + +import java.util.UUID; /** * @author TheElk801 */ public final class OxiddaFinisher extends CardImpl { - private static final FilterControlledPermanent filter - = new FilterControlledPermanent(SubType.EQUIPMENT, "Equipment"); - private static final Hint hint = new ValueHint( - "Equipment you control", new PermanentsOnBattlefieldCount(filter) - ); - public OxiddaFinisher(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}{R}"); @@ -36,7 +25,7 @@ public final class OxiddaFinisher extends CardImpl { this.toughness = new MageInt(5); // Affinity for Equipment - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).addHint(hint)); + this.addAbility(new AffinityAbility(AffinityType.EQUIPMENT)); // Trample this.addAbility(TrampleAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/o/OxiddaGolem.java b/Mage.Sets/src/mage/cards/o/OxiddaGolem.java index dbb370c8b48..d7b91f346f5 100644 --- a/Mage.Sets/src/mage/cards/o/OxiddaGolem.java +++ b/Mage.Sets/src/mage/cards/o/OxiddaGolem.java @@ -1,30 +1,30 @@ - package mage.cards.o; -import java.util.UUID; import mage.MageInt; -import mage.abilities.keyword.AffinityForLandTypeAbility; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.SubType; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class OxiddaGolem extends CardImpl { public OxiddaGolem(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{6}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}"); this.subtype.add(SubType.GOLEM); this.power = new MageInt(3); this.toughness = new MageInt(2); // Affinity for Mountains - this.addAbility(new AffinityForLandTypeAbility(SubType.MOUNTAIN, "Mountains")); - + this.addAbility(new AffinityAbility(AffinityType.MOUNTAINS)); + // Haste this.addAbility(HasteAbility.getInstance()); } diff --git a/Mage.Sets/src/mage/cards/p/PearlEarImperialAdvisor.java b/Mage.Sets/src/mage/cards/p/PearlEarImperialAdvisor.java index 96a69d75506..39222e48050 100644 --- a/Mage.Sets/src/mage/cards/p/PearlEarImperialAdvisor.java +++ b/Mage.Sets/src/mage/cards/p/PearlEarImperialAdvisor.java @@ -3,19 +3,16 @@ package mage.cards.p; import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledSpellsEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.LifelinkAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.FilterSpell; import mage.filter.common.FilterControlledPermanent; @@ -37,11 +34,6 @@ public final class PearlEarImperialAdvisor extends CardImpl { filter.add(CardType.ENCHANTMENT.getPredicate()); } - private static final FilterControlledPermanent filterPermanentAura = new FilterControlledPermanent(SubType.AURA, "Auras"); - private static final Hint hint = new ValueHint( - "Auras you control", new PermanentsOnBattlefieldCount(filterPermanentAura) - ); - private static final FilterPermanent filterModified = new FilterControlledPermanent(); private static final FilterSpell filterAura = new FilterSpell("an Aura spell that targets a modified permanent you control"); @@ -64,12 +56,7 @@ public final class PearlEarImperialAdvisor extends CardImpl { this.addAbility(LifelinkAbility.getInstance()); // Enchantment spells you cast have affinity for Auras. - this.addAbility(new SimpleStaticAbility( - new GainAbilityControlledSpellsEffect( - new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filterPermanentAura)).addHint(hint), - filter - ) - )); + this.addAbility(new SimpleStaticAbility(new GainAbilityControlledSpellsEffect(new AffinityAbility(AffinityType.AURAS), filter))); // Whenever you cast an Aura spell that targets a modified permanent you control, draw a card. this.addAbility(new SpellCastControllerTriggeredAbility(new DrawCardSourceControllerEffect(1), filterAura, false)); diff --git a/Mage.Sets/src/mage/cards/p/Polliwallop.java b/Mage.Sets/src/mage/cards/p/Polliwallop.java index 5ea92391255..319908c8a88 100644 --- a/Mage.Sets/src/mage/cards/p/Polliwallop.java +++ b/Mage.Sets/src/mage/cards/p/Polliwallop.java @@ -1,18 +1,12 @@ package mage.cards.p; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.DamageWithPowerFromOneToAnotherTargetEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.StaticFilters; -import mage.filter.common.FilterControlledPermanent; import mage.target.TargetPermanent; import mage.target.common.TargetControlledCreaturePermanent; @@ -23,14 +17,11 @@ import java.util.UUID; */ public final class Polliwallop extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.FROG, "Frogs"); - private static final Hint hint = new ValueHint("Frogs you control", new PermanentsOnBattlefieldCount(filter)); - public Polliwallop(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{G}"); - // This spell costs {1} less to cast for each Frog you control. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).setRuleAtTheTop(true).addHint(hint)); + // Affinity for Frogs + this.addAbility(new AffinityAbility(AffinityType.FROGS)); // Target creature you control deals damage equal to twice its power to target creature you don't control. this.getSpellAbility().addEffect(new DamageWithPowerFromOneToAnotherTargetEffect("", 2)); diff --git a/Mage.Sets/src/mage/cards/r/RazorGolem.java b/Mage.Sets/src/mage/cards/r/RazorGolem.java index 529ff524b6f..b8a0f9cce0a 100644 --- a/Mage.Sets/src/mage/cards/r/RazorGolem.java +++ b/Mage.Sets/src/mage/cards/r/RazorGolem.java @@ -1,30 +1,29 @@ - package mage.cards.r; -import java.util.UUID; import mage.MageInt; -import mage.abilities.keyword.AffinityForLandTypeAbility; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.SubType; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class RazorGolem extends CardImpl { public RazorGolem(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{6}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}"); this.subtype.add(SubType.GOLEM); - this.power = new MageInt(3); this.toughness = new MageInt(4); // Affinity for Plains - this.addAbility(new AffinityForLandTypeAbility(SubType.PLAINS, "Plains")); + this.addAbility(new AffinityAbility(AffinityType.PLAINS)); // Vigilance this.addAbility(VigilanceAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/r/RebelSalvo.java b/Mage.Sets/src/mage/cards/r/RebelSalvo.java index b06205cdef2..700e985dcbf 100644 --- a/Mage.Sets/src/mage/cards/r/RebelSalvo.java +++ b/Mage.Sets/src/mage/cards/r/RebelSalvo.java @@ -1,20 +1,14 @@ package mage.cards.r; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.continuous.LoseAbilityTargetEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; import mage.target.common.TargetCreatureOrPlaneswalker; import java.util.UUID; @@ -24,18 +18,11 @@ import java.util.UUID; */ public final class RebelSalvo extends CardImpl { - private static final FilterControlledPermanent filter - = new FilterControlledPermanent(SubType.EQUIPMENT, "Equipment"); - - private static final Hint hint = new ValueHint( - "Equipment you control", new PermanentsOnBattlefieldCount(filter) - ); - public RebelSalvo(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}"); // Affinity for Equipment - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).addHint(hint)); + this.addAbility(new AffinityAbility(AffinityType.EQUIPMENT)); // Rebel Salvo deals 5 damage to target creature or planeswalker. That permanent loses indestructible until end of turn. this.getSpellAbility().addEffect(new DamageTargetEffect(5)); diff --git a/Mage.Sets/src/mage/cards/r/RidersOfTheMark.java b/Mage.Sets/src/mage/cards/r/RidersOfTheMark.java index deedcdd5fc3..01efb76c249 100644 --- a/Mage.Sets/src/mage/cards/r/RidersOfTheMark.java +++ b/Mage.Sets/src/mage/cards/r/RidersOfTheMark.java @@ -2,24 +2,16 @@ package mage.cards.r; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.AttackedThisTurnSourceCondition; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.TrampleAbility; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; +import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.HumanSoldierToken; @@ -32,9 +24,6 @@ import java.util.UUID; */ public final class RidersOfTheMark extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.HUMAN, "Humans"); - private static final Hint hint = new ValueHint("Humans you control", new PermanentsOnBattlefieldCount(filter)); - public RidersOfTheMark(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{R}"); @@ -43,8 +32,8 @@ public final class RidersOfTheMark extends CardImpl { this.power = new MageInt(7); this.toughness = new MageInt(4); - // This spell costs {1} less to cast for each Human you control. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).setRuleAtTheTop(true).addHint(hint)); + // Affinity for Humans + this.addAbility(new AffinityAbility(AffinityType.HUMANS)); // Trample this.addAbility(TrampleAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/s/ScalesOfShale.java b/Mage.Sets/src/mage/cards/s/ScalesOfShale.java index 305fffac10e..7b2927ef02d 100644 --- a/Mage.Sets/src/mage/cards/s/ScalesOfShale.java +++ b/Mage.Sets/src/mage/cards/s/ScalesOfShale.java @@ -1,21 +1,15 @@ package mage.cards.s; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.IndestructibleAbility; import mage.abilities.keyword.LifelinkAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -25,14 +19,11 @@ import java.util.UUID; */ public final class ScalesOfShale extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.LIZARD, "Lizards"); - private static final Hint hint = new ValueHint("Lizards you control", new PermanentsOnBattlefieldCount(filter)); - public ScalesOfShale(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}"); // This spell costs {1} less to cast for each Lizard you control. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).setRuleAtTheTop(true).addHint(hint)); + this.addAbility(new AffinityAbility(AffinityType.LIZARDS)); // Target creature gets +2/+0 and gains lifelink and indestructible until end of turn. this.getSpellAbility().addEffect(new BoostTargetEffect( diff --git a/Mage.Sets/src/mage/cards/s/SkyBlessedSamurai.java b/Mage.Sets/src/mage/cards/s/SkyBlessedSamurai.java index fc5ed5454ba..c867847c845 100644 --- a/Mage.Sets/src/mage/cards/s/SkyBlessedSamurai.java +++ b/Mage.Sets/src/mage/cards/s/SkyBlessedSamurai.java @@ -1,19 +1,13 @@ package mage.cards.s; import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.common.FilterControlledEnchantmentPermanent; -import mage.filter.common.FilterControlledPermanent; import java.util.UUID; @@ -22,9 +16,6 @@ import java.util.UUID; */ public final class SkyBlessedSamurai extends CardImpl { - static final FilterControlledPermanent filter = new FilterControlledEnchantmentPermanent("enchantments"); - private static final Hint hint = new ValueHint("Enchantments you control", new PermanentsOnBattlefieldCount(filter)); - public SkyBlessedSamurai(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{6}{W}"); @@ -33,8 +24,8 @@ public final class SkyBlessedSamurai extends CardImpl { this.power = new MageInt(4); this.toughness = new MageInt(4); - // This spell costs {1} less to cast for each enchantment you control. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).addHint(hint)); + // Affinity for enchantments + this.addAbility(new AffinityAbility(AffinityType.ENCHANTMENTS)); // Flying this.addAbility(FlyingAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/s/SpireGolem.java b/Mage.Sets/src/mage/cards/s/SpireGolem.java index 995174df778..42b08a6ad39 100644 --- a/Mage.Sets/src/mage/cards/s/SpireGolem.java +++ b/Mage.Sets/src/mage/cards/s/SpireGolem.java @@ -1,30 +1,30 @@ - package mage.cards.s; -import java.util.UUID; import mage.MageInt; -import mage.abilities.keyword.AffinityForLandTypeAbility; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.SubType; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class SpireGolem extends CardImpl { public SpireGolem(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{6}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}"); this.subtype.add(SubType.GOLEM); - this.power = new MageInt(2); this.toughness = new MageInt(4); // Affinity for Islands - this.addAbility(new AffinityForLandTypeAbility(SubType.ISLAND, "Islands")); + this.addAbility(new AffinityAbility(AffinityType.ISLANDS)); + // Flying this.addAbility(FlyingAbility.getInstance()); } diff --git a/Mage.Sets/src/mage/cards/t/TangleGolem.java b/Mage.Sets/src/mage/cards/t/TangleGolem.java index 2a82ff5e0b6..92529012d8b 100644 --- a/Mage.Sets/src/mage/cards/t/TangleGolem.java +++ b/Mage.Sets/src/mage/cards/t/TangleGolem.java @@ -1,28 +1,28 @@ - package mage.cards.t; -import java.util.UUID; import mage.MageInt; -import mage.abilities.keyword.AffinityForLandTypeAbility; +import mage.abilities.keyword.AffinityAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; import mage.constants.SubType; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class TangleGolem extends CardImpl { public TangleGolem(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{7}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{7}"); this.subtype.add(SubType.GOLEM); this.power = new MageInt(5); this.toughness = new MageInt(4); // Affinity for Forests - this.addAbility(new AffinityForLandTypeAbility(SubType.FOREST, "Forests")); + this.addAbility(new AffinityAbility(AffinityType.FORESTS)); } private TangleGolem(final TangleGolem card) { diff --git a/Mage.Sets/src/mage/cards/t/TheCircleOfLoyalty.java b/Mage.Sets/src/mage/cards/t/TheCircleOfLoyalty.java index a8b6ed085b2..7f4c805b7c0 100644 --- a/Mage.Sets/src/mage/cards/t/TheCircleOfLoyalty.java +++ b/Mage.Sets/src/mage/cards/t/TheCircleOfLoyalty.java @@ -6,17 +6,16 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.AffinityType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SuperType; import mage.filter.FilterSpell; -import mage.filter.common.FilterControlledPermanent; import mage.game.permanent.token.KnightToken; import java.util.UUID; @@ -26,22 +25,19 @@ import java.util.UUID; */ public final class TheCircleOfLoyalty extends CardImpl { - private static final FilterControlledPermanent filterKnight = new FilterControlledPermanent(SubType.KNIGHT, "Knights"); private static final FilterSpell filterLegendary = new FilterSpell("a legendary spell"); static { filterLegendary.add(SuperType.LEGENDARY.getPredicate()); } - private static final Hint hint = new ValueHint("Knights you control", new PermanentsOnBattlefieldCount(filterKnight)); - public TheCircleOfLoyalty(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}{W}{W}"); this.supertype.add(SuperType.LEGENDARY); // This spell costs {1} less to cast for each Knight you control. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filterKnight)).addHint(hint)); + this.addAbility(new AffinityAbility(AffinityType.KNIGHTS)); // Creatures you control get +1/+1. this.addAbility(new SimpleStaticAbility( diff --git a/Mage.Sets/src/mage/cards/t/TheDalekEmperor.java b/Mage.Sets/src/mage/cards/t/TheDalekEmperor.java index a60b3904f57..ea94067bddc 100644 --- a/Mage.Sets/src/mage/cards/t/TheDalekEmperor.java +++ b/Mage.Sets/src/mage/cards/t/TheDalekEmperor.java @@ -3,12 +3,9 @@ package mage.cards.t; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.FaceVillainousChoiceOpponentsEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.HasteAbility; import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.cards.CardImpl; @@ -32,7 +29,6 @@ import java.util.UUID; public final class TheDalekEmperor extends CardImpl { private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.DALEK, "Daleks"); - private static final Hint hint = new ValueHint("Daleks you control", new PermanentsOnBattlefieldCount(filter)); private static final FaceVillainousChoice choice = new FaceVillainousChoice( Outcome.Sacrifice, new TheDalekEmperorFirstChoice(), new TheDalekEmperorSecondChoice() ); @@ -46,7 +42,7 @@ public final class TheDalekEmperor extends CardImpl { this.toughness = new MageInt(6); // Affinity for Daleks - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).addHint(hint)); + this.addAbility(new AffinityAbility(AffinityType.DALEKS)); // Other Daleks you control have haste. this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( diff --git a/Mage.Sets/src/mage/cards/t/TomikWielderOfLaw.java b/Mage.Sets/src/mage/cards/t/TomikWielderOfLaw.java index b33d524311c..008d455a408 100644 --- a/Mage.Sets/src/mage/cards/t/TomikWielderOfLaw.java +++ b/Mage.Sets/src/mage/cards/t/TomikWielderOfLaw.java @@ -1,39 +1,27 @@ package mage.cards.t; -import java.util.UUID; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.LoseLifeTargetEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; -import mage.constants.SubType; -import mage.constants.SuperType; +import mage.abilities.keyword.AffinityAbility; 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.Zone; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.common.FilterControlledPlaneswalkerPermanent; +import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author DominionSpy */ public final class TomikWielderOfLaw extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPlaneswalkerPermanent("planeswalkers"); - private static final Hint hint = new ValueHint("planeswalkers you control", new PermanentsOnBattlefieldCount(filter)); - public TomikWielderOfLaw(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{B}"); @@ -44,8 +32,7 @@ public final class TomikWielderOfLaw extends CardImpl { this.toughness = new MageInt(4); // Affinity for planeswalkers - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)) - .addHint(hint)); + this.addAbility(new AffinityAbility(AffinityType.PLANESWALKERS)); // Flying this.addAbility(FlyingAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/t/TravelTheOverworld.java b/Mage.Sets/src/mage/cards/t/TravelTheOverworld.java index ae340291b87..0d2115a9333 100644 --- a/Mage.Sets/src/mage/cards/t/TravelTheOverworld.java +++ b/Mage.Sets/src/mage/cards/t/TravelTheOverworld.java @@ -1,17 +1,11 @@ package mage.cards.t; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AffinityType; import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; import java.util.UUID; @@ -20,14 +14,11 @@ import java.util.UUID; */ public final class TravelTheOverworld extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.TOWN, "Towns"); - private static final Hint hint = new ValueHint("Towns you control", new PermanentsOnBattlefieldCount(filter)); - public TravelTheOverworld(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{U}{U}"); // Affinity for Towns - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).setRuleAtTheTop(true).addHint(hint)); + this.addAbility(new AffinityAbility(AffinityType.TOWNS)); // Draw four cards. this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(4)); diff --git a/Mage.Sets/src/mage/cards/u/UrzaChiefArtificer.java b/Mage.Sets/src/mage/cards/u/UrzaChiefArtificer.java index 471d5c8fba2..7962bb9fd6d 100644 --- a/Mage.Sets/src/mage/cards/u/UrzaChiefArtificer.java +++ b/Mage.Sets/src/mage/cards/u/UrzaChiefArtificer.java @@ -1,15 +1,12 @@ package mage.cards.u; import mage.MageInt; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.AffinityAbility; import mage.abilities.keyword.MenaceAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -27,14 +24,6 @@ public final class UrzaChiefArtificer extends CardImpl { private static final FilterControlledPermanent filter = new FilterControlledCreaturePermanent("artifact creatures"); - static { - filter.add(CardType.ARTIFACT.getPredicate()); - } - - private static final Hint hint = new ValueHint( - "Artifact creatures you control", new PermanentsOnBattlefieldCount(filter) - ); - public UrzaChiefArtificer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{U}{B}"); @@ -45,7 +34,7 @@ public final class UrzaChiefArtificer extends CardImpl { this.toughness = new MageInt(5); // Affinity for artifact creatures - this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).addHint(hint)); + this.addAbility(new AffinityAbility(AffinityType.ARTIFACT_CREATURES)); // Artifact creatures you control have menace. this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( @@ -53,9 +42,7 @@ public final class UrzaChiefArtificer extends CardImpl { )); // At the beginning of your end step, create a 0/0 colorless Construct artifact creature token with "This creature gets +1/+1 for each artifact you control." - this.addAbility(new BeginningOfEndStepTriggeredAbility( - new CreateTokenEffect(new KarnConstructToken()) - )); + this.addAbility(new BeginningOfEndStepTriggeredAbility(new CreateTokenEffect(new KarnConstructToken()))); } private UrzaChiefArtificer(final UrzaChiefArtificer card) { diff --git a/Mage/src/main/java/mage/abilities/hint/common/GateYouControlHint.java b/Mage/src/main/java/mage/abilities/hint/common/GatesYouControlHint.java similarity index 75% rename from Mage/src/main/java/mage/abilities/hint/common/GateYouControlHint.java rename to Mage/src/main/java/mage/abilities/hint/common/GatesYouControlHint.java index 5a2498624aa..f6f7bc93084 100644 --- a/Mage/src/main/java/mage/abilities/hint/common/GateYouControlHint.java +++ b/Mage/src/main/java/mage/abilities/hint/common/GatesYouControlHint.java @@ -9,11 +9,11 @@ import mage.game.Game; /** * @author JayDi85 */ -public enum GateYouControlHint implements Hint { +public enum GatesYouControlHint implements Hint { instance; - private static final Hint hint = new ValueHint("Gate you control", GateYouControlCount.instance); + private static final Hint hint = new ValueHint("Gates you control", GateYouControlCount.instance); @Override public String getText(Game game, Ability ability) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/AffinityEffect.java b/Mage/src/main/java/mage/abilities/keyword/AffinityAbility.java similarity index 50% rename from Mage/src/main/java/mage/abilities/effects/common/AffinityEffect.java rename to Mage/src/main/java/mage/abilities/keyword/AffinityAbility.java index ebf43626e2c..4d3f1ca0853 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/AffinityEffect.java +++ b/Mage/src/main/java/mage/abilities/keyword/AffinityAbility.java @@ -1,11 +1,10 @@ -package mage.abilities.effects.common; +package mage.abilities.keyword; import mage.abilities.Ability; import mage.abilities.SpellAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.cost.CostModificationEffectImpl; -import mage.constants.CostModificationType; -import mage.constants.Duration; -import mage.constants.Outcome; +import mage.constants.*; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.util.CardUtil; @@ -15,15 +14,45 @@ import mage.util.CardUtil; * 702.40a Affinity is a static ability that functions while the spell with affinity is on the stack. * “Affinity for [text]” means “This spell costs you {1} less to cast for each [text] you control.” * 702.40b If a spell has multiple instances of affinity, each of them applies. + * + * @author Loki, TheElk801 */ -public class AffinityEffect extends CostModificationEffectImpl { +public class AffinityAbility extends SimpleStaticAbility { + + private AffinityType affinityType; + + public AffinityAbility(AffinityType affinityType) { + super(Zone.ALL, new AffinityEffect(affinityType.getFilter())); + setRuleAtTheTop(true); + this.addHint(affinityType.getHint()); + this.affinityType = affinityType; + } + + protected AffinityAbility(final AffinityAbility ability) { + super(ability); + this.affinityType = ability.affinityType; + } + + @Override + public AffinityAbility copy() { + return new AffinityAbility(this); + } + + @Override + public String getRule() { + return "Affinity for " + affinityType.getFilter().getMessage() + + " (This spell costs {1} less to cast for each " + + affinityType.getSingularName() + " you control.)"; + } +} + +class AffinityEffect extends CostModificationEffectImpl { private final FilterControlledPermanent filter; public AffinityEffect(FilterControlledPermanent affinityFilter) { super(Duration.WhileOnStack, Outcome.Benefit, CostModificationType.REDUCE_COST); this.filter = affinityFilter; - staticText = "Affinity for " + filter.getMessage(); } protected AffinityEffect(final AffinityEffect effect) { @@ -34,14 +63,18 @@ public class AffinityEffect extends CostModificationEffectImpl { @Override public boolean apply(Game game, Ability source, Ability abilityToModify) { // abilityToModify.getControllerId() works with Sen Triplets and in multiplayer games, see https://github.com/magefree/mage/issues/5931 - int count = game.getBattlefield().getActivePermanents(filter, abilityToModify.getControllerId(), source, game).size(); - CardUtil.reduceCost(abilityToModify, count); + CardUtil.reduceCost( + abilityToModify, game.getBattlefield().count( + filter, abilityToModify.getControllerId(), source, game + ) + ); return true; } @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { - return abilityToModify instanceof SpellAbility && abilityToModify.getSourceId().equals(source.getSourceId()); + return abilityToModify instanceof SpellAbility + && abilityToModify.getSourceId().equals(source.getSourceId()); } @Override diff --git a/Mage/src/main/java/mage/abilities/keyword/AffinityForArtifactsAbility.java b/Mage/src/main/java/mage/abilities/keyword/AffinityForArtifactsAbility.java index d5e5d5b203a..1b6793dd945 100644 --- a/Mage/src/main/java/mage/abilities/keyword/AffinityForArtifactsAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/AffinityForArtifactsAbility.java @@ -1,21 +1,14 @@ package mage.abilities.keyword; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.AffinityEffect; -import mage.abilities.hint.common.ArtifactYouControlHint; -import mage.constants.Zone; -import mage.filter.StaticFilters; +import mage.constants.AffinityType; /** * Affinity for artifacts */ -public class AffinityForArtifactsAbility extends SimpleStaticAbility { +public class AffinityForArtifactsAbility extends AffinityAbility { public AffinityForArtifactsAbility() { - super(Zone.ALL, new AffinityEffect(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT)); - setRuleAtTheTop(true); - - this.addHint(ArtifactYouControlHint.instance); + super(AffinityType.ARTIFACTS); } protected AffinityForArtifactsAbility(final AffinityForArtifactsAbility ability) { @@ -26,9 +19,4 @@ public class AffinityForArtifactsAbility extends SimpleStaticAbility { public AffinityForArtifactsAbility copy() { return new AffinityForArtifactsAbility(this); } - - @Override - public String getRule() { - return "Affinity for artifacts (This spell costs {1} less to cast for each artifact you control.)"; - } } diff --git a/Mage/src/main/java/mage/abilities/keyword/AffinityForLandTypeAbility.java b/Mage/src/main/java/mage/abilities/keyword/AffinityForLandTypeAbility.java deleted file mode 100644 index cc63bd9249d..00000000000 --- a/Mage/src/main/java/mage/abilities/keyword/AffinityForLandTypeAbility.java +++ /dev/null @@ -1,42 +0,0 @@ -package mage.abilities.keyword; - -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AffinityEffect; -import mage.abilities.hint.ValueHint; -import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; - -/** - * @author LevelX2 - */ - -public class AffinityForLandTypeAbility extends SimpleStaticAbility { - private final String rulesText; - - public AffinityForLandTypeAbility(SubType landType, String pluralName) { - super(Zone.ALL, null); - rulesText = "Affinity for " + pluralName + " (This spell costs {1} less to cast for each " + landType + " you control.)"; - setRuleAtTheTop(true); - - FilterControlledPermanent filter = new FilterControlledPermanent(landType); - addEffect(new AffinityEffect(filter)); - addHint(new ValueHint(pluralName + " you control", new PermanentsOnBattlefieldCount(filter))); - } - - protected AffinityForLandTypeAbility(final AffinityForLandTypeAbility ability) { - super(ability); - this.rulesText = ability.rulesText; - } - - @Override - public AffinityForLandTypeAbility copy() { - return new AffinityForLandTypeAbility(this); - } - - @Override - public String getRule() { - return rulesText; - } -} diff --git a/Mage/src/main/java/mage/constants/AffinityType.java b/Mage/src/main/java/mage/constants/AffinityType.java new file mode 100644 index 00000000000..8c9548ee374 --- /dev/null +++ b/Mage/src/main/java/mage/constants/AffinityType.java @@ -0,0 +1,119 @@ +package mage.constants; + +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.hint.common.ArtifactYouControlHint; +import mage.abilities.hint.common.CreaturesYouControlHint; +import mage.abilities.hint.common.GatesYouControlHint; +import mage.filter.common.*; +import mage.filter.predicate.mageobject.HistoricPredicate; +import mage.filter.predicate.mageobject.OutlawPredicate; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.util.CardUtil; + +/** + * @author TheElk801 + */ +public enum AffinityType { + ARTIFACTS(new FilterControlledArtifactPermanent("artifacts"), ArtifactYouControlHint.instance), + CREATURES(new FilterControlledCreaturePermanent("creatures"), CreaturesYouControlHint.instance), + ARTIFACT_CREATURES(AffinityFilters.ARTIFACT_CREATURES), + ENCHANTMENTS(new FilterControlledEnchantmentPermanent("enchantments")), + PLANESWALKERS(new FilterControlledPlaneswalkerPermanent("planeswalker")), + + EQUIPMENT(new FilterControlledPermanent(SubType.EQUIPMENT, "Equipment"), "Equipment"), + AURAS(new FilterControlledPermanent(SubType.AURA, "Auras")), + FOOD(new FilterControlledPermanent(SubType.FOOD, "Food"), "Food"), + TOKENS(AffinityFilters.TOKENS), + + PLAINS(new FilterControlledPermanent(SubType.PLAINS, "Plains")), + ISLANDS(new FilterControlledPermanent(SubType.ISLAND, "Islands")), + SWAMPS(new FilterControlledPermanent(SubType.SWAMP, "Swamps")), + MOUNTAINS(new FilterControlledPermanent(SubType.MOUNTAIN, "Mountains")), + FORESTS(new FilterControlledPermanent(SubType.FOREST, "Forests")), + + SPIRITS(new FilterControlledPermanent(SubType.SPIRIT, "Spirits")), + HUMANS(new FilterControlledPermanent(SubType.HUMAN, "Humans")), + KNIGHTS(new FilterControlledPermanent(SubType.KNIGHT, "Knights")), + DALEKS(new FilterControlledPermanent(SubType.DALEK, "Daleks")), + FROGS(new FilterControlledPermanent(SubType.FROG, "Frogs")), + LIZARDS(new FilterControlledPermanent(SubType.LIZARD, "Lizards")), + BIRDS(new FilterControlledPermanent(SubType.BIRD, "Birds")), + CITIZENS(new FilterControlledPermanent(SubType.CITIZEN, "Citizens")), + TOWNS(new FilterControlledPermanent(SubType.TOWN, "Towns")), + GATES(new FilterControlledPermanent(SubType.GATE, "Gates"), GatesYouControlHint.instance), + SNOW_LANDS(AffinityFilters.SNOW_LANDS), + HISTORIC(AffinityFilters.HISTORIC), + OUTLAWS(AffinityFilters.OUTLAWS); + + private final FilterControlledPermanent filter; + private final Hint hint; + private final String singularName; + + AffinityType(FilterControlledPermanent filter) { + this(filter, filter.getMessage()); + } + + AffinityType(FilterControlledPermanent filter, String singularName) { + this(filter, new ValueHint( + CardUtil.getTextWithFirstCharUpperCase(filter.getMessage()) + " you control", + new PermanentsOnBattlefieldCount(filter) + ), singularName); + } + + AffinityType(FilterControlledPermanent filter, Hint hint) { + this(filter, hint, filter.getMessage().substring(0, filter.getMessage().length() - 1)); + } + + AffinityType(FilterControlledPermanent filter, Hint hint, String singularName) { + this.filter = filter; + this.hint = hint; + this.singularName = singularName; + } + + public FilterControlledPermanent getFilter() { + return filter; + } + + public Hint getHint() { + return hint; + } + + public String getSingularName() { + return singularName; + } +} + +class AffinityFilters { + public static final FilterControlledPermanent TOKENS = new FilterControlledPermanent("tokens"); + + static { + TOKENS.add(TokenPredicate.TRUE); + } + + public static final FilterControlledPermanent SNOW_LANDS = new FilterControlledLandPermanent("snow lands"); + + static { + SNOW_LANDS.add(SuperType.SNOW.getPredicate()); + } + + public static final FilterControlledPermanent OUTLAWS = new FilterControlledPermanent("outlaws"); + + static { + OUTLAWS.add(OutlawPredicate.instance); + } + + public static final FilterControlledPermanent HISTORIC = new FilterControlledPermanent("historic permanents"); + + static { + HISTORIC.add(HistoricPredicate.instance); + } + + public static final FilterControlledPermanent ARTIFACT_CREATURES = new FilterControlledPermanent("artifact creatures"); + + static { + ARTIFACT_CREATURES.add(CardType.ARTIFACT.getPredicate()); + ARTIFACT_CREATURES.add(CardType.CREATURE.getPredicate()); + } +} diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 872dcfe0d60..33903843f47 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -1330,5 +1330,4 @@ public final class StaticFilters { static { FILTER_CONTROLLED_CLUE.setLockedFilter(true); } - }